From 2b8f778c59e0fec4b61a33daaa7edb0228f62ae3 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 8 Jun 2020 21:14:56 -0300 Subject: [PATCH] Fixing some things, tests resumed --- autogen.py | 4 +- src/cmc/hashmap.h | 10 +- src/ext/cmc/bitset.h | 11 +- src/utl/test.h | 15 - tests/main/Makefile | 2 +- tests/main/src/bitset.c | 63 ++-- tests/main/src/deque.c | 166 ++++++--- tests/main/src/hashbidimap.c | 155 +++++--- tests/main/src/hashmap.c | 334 +++++++++++------ tests/main/src/hashmultimap.c | 263 ++++++++------ tests/main/src/hashmultiset.c | 667 ++++++++++++++++++---------------- tests/main/src/hashset.c | 480 ++++++++++++------------ tests/main/src/heap.c | 190 +++++----- tests/main/src/intervalheap.c | 389 ++++++++++---------- tests/main/src/linkedlist.c | 434 ++++++++++++---------- tests/main/src/list.c | 398 +++++++++++--------- tests/main/src/queue.c | 102 ++++-- tests/main/src/sortedlist.c | 291 ++++++++------- tests/main/src/stack.c | 107 +++--- tests/main/src/treemap.c | 355 ++++++++++-------- tests/main/src/treeset.c | 123 +++++-- tests/main/unt/bitset.c | 5 +- tests/main/unt/hashbidimap.c | 11 +- tests/main/unt/heap.c | 1 - tests/main/unt/utl.c | 5 + tests/to_string.c | 24 ++ 26 files changed, 2652 insertions(+), 1953 deletions(-) diff --git a/autogen.py b/autogen.py index fe8b08d..476ee47 100644 --- a/autogen.py +++ b/autogen.py @@ -53,11 +53,11 @@ for data in collections: file.write( f''' - #include {data['h']} + #include "macro_collections.h" {UNIQUE_FLAG} - CMC_{data['LIB']}_{data['COLLECTION']}_CORE(({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) + C_MACRO_COLLECTIONS_ALL({data['LIB']}, {data['COLLECTION']}, ({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) {UNIQUE_FLAG} ''') diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index c1d7529..c0e2e06 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -453,8 +453,8 @@ { \ if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ { \ - max_key = _map_->buffer[first].key; \ - max_val = _map_->buffer[first].value; \ + max_key = _map_->buffer[i].key; \ + max_val = _map_->buffer[i].value; \ } \ } \ } \ @@ -495,10 +495,10 @@ { \ if (_map_->buffer[i].state == CMC_ES_FILLED) \ { \ - if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) > 0) \ + if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) \ { \ - min_key = _map_->buffer[first].key; \ - min_val = _map_->buffer[first].value; \ + min_key = _map_->buffer[i].key; \ + min_val = _map_->buffer[i].value; \ } \ } \ } \ diff --git a/src/ext/cmc/bitset.h b/src/ext/cmc/bitset.h index 994c07e..791abcc 100644 --- a/src/ext/cmc/bitset.h +++ b/src/ext/cmc/bitset.h @@ -16,6 +16,15 @@ /** * All the EXT parts of CMC BitSet. */ -#define CMC_EXT_CMC_BITSET_PARTS +#define CMC_EXT_CMC_BITSET_PARTS PLACEHOLDER + +#define CMC_EXT_CMC_BITSET_PLACEHOLDER(PARAMS) + +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_HEADER(PARAMS) + +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_HEADER_(PFX, SNAME, V) +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_SOURCE_(PFX, SNAME, V) #endif /* CMC_EXT_CMC_BITSET_H */ diff --git a/src/utl/test.h b/src/utl/test.h index f604489..07238c2 100644 --- a/src/utl/test.h +++ b/src/utl/test.h @@ -136,12 +136,6 @@ CMC_UNUSED static void cmc_test_log(const char *unit_name, const char *current_t BODY; \ \ cmc_timer_stop(timer); \ -\ - unittest_abort: \ - if (tinfo.aborted) \ - { \ - cmc_test_log(unit_name, current_test, true, false); \ - } \ \ tinfo.assert_total = cmc_assert_total - tinfo.assert_total; \ tinfo.assert_failed = cmc_assert_failed - tinfo.assert_failed; \ @@ -225,13 +219,4 @@ CMC_UNUSED static void cmc_test_log(const char *unit_name, const char *current_t \ } while (0) -#define CMC_TEST_ABORT() \ - do \ - { \ - tinfo.aborted = true; \ - tinfo.total -= 1; \ - goto unittest_abort; \ -\ - } while (0) - #endif /* CMC_UTL_TEST_H */ diff --git a/tests/main/Makefile b/tests/main/Makefile index 2cf7991..f207ef3 100644 --- a/tests/main/Makefile +++ b/tests/main/Makefile @@ -1,6 +1,6 @@ CC = gcc CFLAGS = -std=c11 -Wall -Wextra -CFLAGS += -Wno-unused -Wno-missing-braces +CFLAGS += -Wno-missing-braces DBFLAGS = -g3 CVFLAGS = --coverage -O0 INCLUDE = ../../src/ diff --git a/tests/main/src/bitset.c b/tests/main/src/bitset.c index 93f3f3c..6fc38ba 100644 --- a/tests/main/src/bitset.c +++ b/tests/main/src/bitset.c @@ -14,7 +14,7 @@ struct bitset struct bitset_iter { struct bitset *target; - cmc_bitset_word cursor; + size_t cursor; _Bool start; _Bool end; }; @@ -70,15 +70,17 @@ struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct _bitset_->capacity = capacity; _bitset_->flag = CMC_FLAG_OK; _bitset_->alloc = alloc; - _bitset_->callbacks = callbacks; + (_bitset_)->callbacks = callbacks; return _bitset_; } struct bitset bs_init(size_t n_bits) { return bs_init_custom(n_bits, ((void *)0), ((void *)0)); } -struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, + struct cmc_callbacks *__attribute__((__unused__)) (callbacks)) { + ; struct bitset _bitset_ = { 0 }; if (n_bits < 1) return _bitset_; @@ -91,7 +93,7 @@ struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct _bitset_.capacity = capacity; _bitset_.flag = CMC_FLAG_OK; _bitset_.alloc = alloc; - _bitset_.callbacks = callbacks; + (&_bitset_)->callbacks = callbacks; return _bitset_; } void bs_free(struct bitset *_bitset_) @@ -105,11 +107,12 @@ void bs_release(struct bitset _bitset_) } void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _bitset_->alloc = &cmc_alloc_node_default; else _bitset_->alloc = alloc; - _bitset_->callbacks = callbacks; + (_bitset_)->callbacks = callbacks; _bitset_->flag = CMC_FLAG_OK; } _Bool bs_set(struct bitset *_bitset_, size_t bit_index) @@ -120,8 +123,9 @@ _Bool bs_set(struct bitset *_bitset_, size_t bit_index) size_t i = bs_bit_to_index(bit_index); _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->create) - _bitset_->callbacks->create(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; return 1; } _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) @@ -153,8 +157,9 @@ _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) _bitset_->buffer[end_index] |= end_mask; } _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->create) - _bitset_->callbacks->create(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; return 1; } _Bool bs_clear(struct bitset *_bitset_, size_t bit_index) @@ -165,8 +170,9 @@ _Bool bs_clear(struct bitset *_bitset_, size_t bit_index) size_t i = bs_bit_to_index(bit_index); _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->delete) - _bitset_->callbacks->delete (); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) + (_bitset_)->callbacks->delete (); + ; return 1; } _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) @@ -198,8 +204,9 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) _bitset_->buffer[end_index] &= ~end_mask; } _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->delete) - _bitset_->callbacks->delete (); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) + (_bitset_)->callbacks->delete (); + ; return 1; } _Bool bs_flip(struct bitset *_bitset_, size_t bit_index) @@ -210,8 +217,9 @@ _Bool bs_flip(struct bitset *_bitset_, size_t bit_index) size_t i = bs_bit_to_index(bit_index); _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->update) - _bitset_->callbacks->update(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) + (_bitset_)->callbacks->update(); + ; return 1; } _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) @@ -243,8 +251,9 @@ _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) _bitset_->buffer[end_index] ^= end_mask; } _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->update) - _bitset_->callbacks->update(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) + (_bitset_)->callbacks->update(); + ; return 1; } _Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state) @@ -266,8 +275,9 @@ _Bool bs_set_all(struct bitset *_bitset_) for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] = ~((cmc_bitset_word)0); _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->create) - _bitset_->callbacks->create(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; return 1; } _Bool bs_clear_all(struct bitset *_bitset_) @@ -275,8 +285,9 @@ _Bool bs_clear_all(struct bitset *_bitset_) for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] = 0; _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->delete) - _bitset_->callbacks->delete (); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) + (_bitset_)->callbacks->delete (); + ; return 1; } _Bool bs_flip_all(struct bitset *_bitset_) @@ -284,8 +295,9 @@ _Bool bs_flip_all(struct bitset *_bitset_) for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->create) - _bitset_->callbacks->create(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; return 1; } _Bool bs_get(struct bitset *_bitset_, size_t bit_index) @@ -318,8 +330,9 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) if (_bitset_->capacity < words) memset(_bitset_->buffer + _bitset_->capacity, 0, (words - _bitset_->capacity) * sizeof(cmc_bitset_word)); _bitset_->capacity = words; - if (_bitset_->callbacks && _bitset_->callbacks->resize) - _bitset_->callbacks->resize(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->resize) + (_bitset_)->callbacks->resize(); + ; _bitset_->flag = CMC_FLAG_OK; return 1; } diff --git a/tests/main/src/deque.c b/tests/main/src/deque.c index 8d83464..dc5f600 100644 --- a/tests/main/src/deque.c +++ b/tests/main/src/deque.c @@ -24,20 +24,11 @@ struct deque_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct deque_iter -{ - struct deque *target; - size_t cursor; - size_t index; - _Bool start; - _Bool end; -}; struct deque *d_new(size_t capacity, struct deque_fval *f_val); struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void d_clear(struct deque *_deque_); void d_free(struct deque *_deque_); -void d_release(struct deque _deque_); void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool d_push_front(struct deque *_deque_, size_t value); _Bool d_push_back(struct deque *_deque_, size_t value); @@ -54,8 +45,18 @@ int d_flag(struct deque *_deque_); _Bool d_resize(struct deque *_deque_, size_t capacity); struct deque *d_copy_of(struct deque *_deque_); _Bool d_equals(struct deque *_deque1_, struct deque *_deque2_); -struct cmc_string d_to_string(struct deque *_deque_); -_Bool d_print(struct deque *_deque_, FILE *fptr); +struct deque d_init(size_t capacity, struct deque_fval *f_val); +struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void d_release(struct deque _deque_); +struct deque_iter +{ + struct deque *target; + size_t cursor; + size_t index; + _Bool start; + _Bool end; +}; struct deque_iter d_iter_start(struct deque *target); struct deque_iter d_iter_end(struct deque *target); _Bool d_iter_at_start(struct deque_iter *iter); @@ -70,6 +71,8 @@ _Bool d_iter_go_to(struct deque_iter *iter, size_t index); size_t d_iter_value(struct deque_iter *iter); size_t *d_iter_rvalue(struct deque_iter *iter); size_t d_iter_index(struct deque_iter *iter); +_Bool d_to_string(struct deque *_deque_, FILE *fptr); +_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end); struct deque *d_new(size_t capacity, struct deque_fval *f_val) { return d_new_custom(capacity, f_val, ((void *)0), ((void *)0)); @@ -77,6 +80,7 @@ struct deque *d_new(size_t capacity, struct deque_fval *f_val) struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (!f_val) @@ -99,7 +103,7 @@ struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc _deque_->flag = CMC_FLAG_OK; _deque_->f_val = f_val; _deque_->alloc = alloc; - _deque_->callbacks = callbacks; + (_deque_)->callbacks = callbacks; return _deque_; } void d_clear(struct deque *_deque_) @@ -131,25 +135,14 @@ void d_free(struct deque *_deque_) _deque_->alloc->free(_deque_->buffer); _deque_->alloc->free(_deque_); } -void d_release(struct deque _deque_) -{ - if (_deque_.f_val->free) - { - for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) - { - _deque_.f_val->free(_deque_.buffer[i]); - i = (i + 1) % _deque_.capacity; - } - } - _deque_.alloc->free(_deque_.buffer); -} void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _deque_->alloc = &cmc_alloc_node_default; else _deque_->alloc = alloc; - _deque_->callbacks = callbacks; + (_deque_)->callbacks = callbacks; _deque_->flag = CMC_FLAG_OK; } _Bool d_push_front(struct deque *_deque_, size_t value) @@ -163,8 +156,9 @@ _Bool d_push_front(struct deque *_deque_, size_t value) _deque_->buffer[_deque_->front] = value; _deque_->count++; _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->create) - _deque_->callbacks->create(); + if ((_deque_)->callbacks && (_deque_)->callbacks->create) + (_deque_)->callbacks->create(); + ; return 1; } _Bool d_push_back(struct deque *_deque_, size_t value) @@ -178,8 +172,9 @@ _Bool d_push_back(struct deque *_deque_, size_t value) _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; _deque_->count++; _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->create) - _deque_->callbacks->create(); + if ((_deque_)->callbacks && (_deque_)->callbacks->create) + (_deque_)->callbacks->create(); + ; return 1; } _Bool d_pop_front(struct deque *_deque_) @@ -193,8 +188,9 @@ _Bool d_pop_front(struct deque *_deque_) _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; _deque_->count--; _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->delete) - _deque_->callbacks->delete (); + if ((_deque_)->callbacks && (_deque_)->callbacks->delete) + (_deque_)->callbacks->delete (); + ; return 1; } _Bool d_pop_back(struct deque *_deque_) @@ -208,8 +204,9 @@ _Bool d_pop_back(struct deque *_deque_) _deque_->buffer[_deque_->back] = (size_t){ 0 }; _deque_->count--; _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->delete) - _deque_->callbacks->delete (); + if ((_deque_)->callbacks && (_deque_)->callbacks->delete) + (_deque_)->callbacks->delete (); + ; return 1; } size_t d_front(struct deque *_deque_) @@ -220,8 +217,9 @@ size_t d_front(struct deque *_deque_) return (size_t){ 0 }; } _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->read) - _deque_->callbacks->read(); + if ((_deque_)->callbacks && (_deque_)->callbacks->read) + (_deque_)->callbacks->read(); + ; return _deque_->buffer[_deque_->front]; } size_t d_back(struct deque *_deque_) @@ -232,8 +230,9 @@ size_t d_back(struct deque *_deque_) return (size_t){ 0 }; } _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->read) - _deque_->callbacks->read(); + if ((_deque_)->callbacks && (_deque_)->callbacks->read) + (_deque_)->callbacks->read(); + ; return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; } _Bool d_contains(struct deque *_deque_, size_t value) @@ -249,8 +248,9 @@ _Bool d_contains(struct deque *_deque_, size_t value) } i = (i + 1) % _deque_->capacity; } - if (_deque_->callbacks && _deque_->callbacks->read) - _deque_->callbacks->read(); + if ((_deque_)->callbacks && (_deque_)->callbacks->read) + (_deque_)->callbacks->read(); + ; return result; } _Bool d_empty(struct deque *_deque_) @@ -300,18 +300,20 @@ _Bool d_resize(struct deque *_deque_, size_t capacity) _deque_->front = 0; _deque_->back = _deque_->count; success: - if (_deque_->callbacks && _deque_->callbacks->resize) - _deque_->callbacks->resize(); + if ((_deque_)->callbacks && (_deque_)->callbacks->resize) + (_deque_)->callbacks->resize(); + ; return 1; } struct deque *d_copy_of(struct deque *_deque_) { - struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, _deque_->callbacks); + struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, ((void *)0)); if (!result) { _deque_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _deque_->callbacks; if (_deque_->f_val->cpy) { for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) @@ -350,6 +352,46 @@ _Bool d_equals(struct deque *_deque1_, struct deque *_deque2_) } return 1; } +struct deque d_init(size_t capacity, struct deque_fval *f_val) +{ + return d_init_custom(capacity, f_val, ((void *)0), ((void *)0)); +} +struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + struct deque _deque_ = { 0 }; + if (capacity < 1) + return _deque_; + if (!f_val) + return _deque_; + if (!alloc) + alloc = &cmc_alloc_node_default; + _deque_.buffer = alloc->calloc(capacity, sizeof(size_t)); + if (!_deque_.buffer) + return _deque_; + _deque_.capacity = capacity; + _deque_.count = 0; + _deque_.front = 0; + _deque_.back = 0; + _deque_.flag = CMC_FLAG_OK; + _deque_.f_val = f_val; + _deque_.alloc = alloc; + (&_deque_)->callbacks = callbacks; + return _deque_; +} +void d_release(struct deque _deque_) +{ + if (_deque_.f_val->free) + { + for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) + { + _deque_.f_val->free(_deque_.buffer[i]); + i = (i + 1) % _deque_.capacity; + } + } + _deque_.alloc->free(_deque_.buffer); +} struct deque_iter d_iter_start(struct deque *target) { struct deque_iter iter; @@ -504,5 +546,45 @@ size_t d_iter_index(struct deque_iter *iter) { return iter->index; } +_Bool d_to_string(struct deque *_deque_, FILE *fptr) +{ + struct deque *d_ = _deque_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "front:%" + "I64u" + ", " + "back:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "deque", "size_t", d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back, d_->flag, + d_->f_val, d_->alloc, (d_)->callbacks); +} +_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) + return 0; + i = (i + 1) % _deque_->capacity; + if (j + 1 < _deque_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_DEQUE */ diff --git a/tests/main/src/hashbidimap.c b/tests/main/src/hashbidimap.c index 32029fd..42e2c8d 100644 --- a/tests/main/src/hashbidimap.c +++ b/tests/main/src/hashbidimap.c @@ -78,8 +78,6 @@ int hbm_flag(struct hashbidimap *_map_); _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity); struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_); _Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_); -struct cmc_string hbm_to_string(struct hashbidimap *_map_); -_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr); struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target); void hbm_iter_free(struct hashbidimap_iter *iter); void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target); @@ -95,6 +93,9 @@ _Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index); size_t hbm_iter_key(struct hashbidimap_iter *iter); size_t hbm_iter_value(struct hashbidimap_iter *iter); size_t hbm_iter_index(struct hashbidimap_iter *iter); +_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr); +_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, size_t key, size_t value); static struct hashbidimap_entry **hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key); static struct hashbidimap_entry **hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val); @@ -106,40 +107,13 @@ static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_); struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key, struct hashbidimap_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - size_t real_capacity = hbm_impl_calculate_size(capacity / load); - struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); - if (!_map_->buffer) - { - alloc->free(_map_->buffer); - alloc->free(_map_); - return ((void *)0); - } - _map_->count = 0; - _map_->capacity = real_capacity; - _map_->load = load; - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->alloc = alloc; - _map_->callbacks = ((void *)0); - _map_->it_start = hbm_impl_it_start; - _map_->it_end = hbm_impl_it_end; - return _map_; + return hbm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) @@ -167,7 +141,7 @@ struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidi _map_->f_val = f_val; _map_->flag = CMC_FLAG_OK; _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; _map_->it_start = hbm_impl_it_start; _map_->it_end = hbm_impl_it_end; return _map_; @@ -199,11 +173,12 @@ void hbm_free(struct hashbidimap *_map_) } void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) @@ -233,8 +208,9 @@ _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) } _map_->count++; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->create) - _map_->callbacks->create(); + if ((_map_)->callbacks && (_map_)->callbacks->create) + (_map_)->callbacks->create(); + ; return 1; } _Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key) @@ -277,8 +253,9 @@ _Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key) } success: _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return 1; } _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) @@ -321,8 +298,9 @@ _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) } success: _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return 1; } _Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val) @@ -354,8 +332,9 @@ _Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, *val_entry = ((void *)1); _map_->count--; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return 1; } _Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val) @@ -387,8 +366,9 @@ _Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, *val_entry = ((void *)1); _map_->count--; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return 1; } size_t hbm_get_key(struct hashbidimap *_map_, size_t val) @@ -400,8 +380,9 @@ size_t hbm_get_key(struct hashbidimap *_map_, size_t val) return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return (*entry)->key; } size_t hbm_get_val(struct hashbidimap *_map_, size_t key) @@ -413,24 +394,27 @@ size_t hbm_get_val(struct hashbidimap *_map_, size_t key) return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return (*entry)->value; } _Bool hbm_contains_key(struct hashbidimap *_map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0); - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return result; } _Bool hbm_contains_val(struct hashbidimap *_map_, size_t val) { _map_->flag = CMC_FLAG_OK; _Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0); - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return result; } _Bool hbm_empty(struct hashbidimap *_map_) @@ -516,19 +500,21 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) _map_->alloc->free(tmp_buff); _map_->alloc->free(_new_map_); success: - if (_map_->callbacks && _map_->callbacks->resize) - _map_->callbacks->resize(); + if ((_map_)->callbacks && (_map_)->callbacks->resize) + (_map_)->callbacks->resize(); + ; return 1; } struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_) { struct hashbidimap *result = hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, _map_->callbacks); + _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _map_->callbacks; for (size_t i = 0; i < _map_->capacity; i++) { struct hashbidimap_entry *scan = _map_->buffer[i][0]; @@ -607,8 +593,8 @@ void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target) { for (size_t i = 0; i < target->capacity; i++) { - struct hashbidimap_entry *tmp = target->buffer[i][0]; - if (tmp != ((void *)0) && tmp != ((void *)1)) + struct hashbidimap_entry *entry = target->buffer[i][0]; + if (entry && entry != ((void *)1)) { iter->first = i; break; @@ -617,8 +603,8 @@ void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target) iter->cursor = iter->first; for (size_t i = target->capacity; i > 0; i--) { - struct hashbidimap_entry *tmp = target->buffer[i - 1][0]; - if (tmp != ((void *)0) && tmp != ((void *)1)) + struct hashbidimap_entry *entry = target->buffer[i - 1][0]; + if (entry && entry != ((void *)1)) { iter->last = i - 1; break; @@ -910,5 +896,58 @@ static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_) hbm_iter_to_end(&iter); return iter; } +_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr) +{ + struct hashbidimap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashbidimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); +} +_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep) +{ + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _map_->capacity; i > 0; i--) + { + struct hashbidimap_entry *entry = _map_->buffer[i - 1][0]; + if (entry && entry != ((void *)1)) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashbidimap_entry *entry = _map_->buffer[i][0]; + if (entry && entry != ((void *)1)) + { + if (!_map_->f_key->str(fptr, entry->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, entry->value)) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_HASHBIDIMAP */ diff --git a/tests/main/src/hashmap.c b/tests/main/src/hashmap.c index d9b1f95..37980ab 100644 --- a/tests/main/src/hashmap.c +++ b/tests/main/src/hashmap.c @@ -40,22 +40,11 @@ struct hashmap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct hashmap_iter -{ - struct hashmap *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void hm_clear(struct hashmap *_map_); void hm_free(struct hashmap *_map_); -void hm_release(struct hashmap _map_); void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value); _Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value); @@ -74,8 +63,20 @@ int hm_flag(struct hashmap *_map_); _Bool hm_resize(struct hashmap *_map_, size_t capacity); struct hashmap *hm_copy_of(struct hashmap *_map_); _Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_); -struct cmc_string hm_to_string(struct hashmap *_map_); -_Bool hm_print(struct hashmap *_map_, FILE *fptr); +struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); +struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void hm_release(struct hashmap _map_); +struct hashmap_iter +{ + struct hashmap *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; struct hashmap_iter hm_iter_start(struct hashmap *target); struct hashmap_iter hm_iter_end(struct hashmap *target); _Bool hm_iter_at_start(struct hashmap_iter *iter); @@ -91,6 +92,9 @@ size_t hm_iter_key(struct hashmap_iter *iter); size_t hm_iter_value(struct hashmap_iter *iter); size_t *hm_iter_rvalue(struct hashmap_iter *iter); size_t hm_iter_index(struct hashmap_iter *iter); +_Bool hm_to_string(struct hashmap *_map_, FILE *fptr); +_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key); static size_t hm_impl_calculate_size(size_t required); struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) @@ -100,6 +104,7 @@ struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) @@ -125,7 +130,7 @@ struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; return _map_; } void hm_clear(struct hashmap *_map_) @@ -167,31 +172,14 @@ void hm_free(struct hashmap *_map_) _map_->alloc->free(_map_->buffer); _map_->alloc->free(_map_); } -void hm_release(struct hashmap _map_) -{ - if (_map_.f_key->free || _map_.f_val->free) - { - for (size_t i = 0; i < _map_.capacity; i++) - { - struct hashmap_entry *entry = &(_map_.buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (_map_.f_key->free) - _map_.f_key->free(entry->key); - if (_map_.f_val->free) - _map_.f_val->free(entry->value); - } - } - } - _map_.alloc->free(_map_.buffer); -} void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) @@ -247,8 +235,9 @@ _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) } _map_->count++; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->create) - _map_->callbacks->create(); + if ((_map_)->callbacks && (_map_)->callbacks->create) + (_map_)->callbacks->create(); + ; return 1; } _Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value) @@ -268,8 +257,9 @@ _Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old *old_value = entry->value; entry->value = new_value; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return 1; } _Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value) @@ -293,8 +283,9 @@ _Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value) result->state = CMC_ES_DELETED; _map_->count--; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return 1; } _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) @@ -304,26 +295,36 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } - struct hashmap_iter iter = hm_iter_start(_map_); - size_t max_key = hm_iter_key(&iter); - size_t max_val = hm_iter_value(&iter); - hm_iter_next(&iter); - for (; !hm_iter_at_end(&iter); hm_iter_next(&iter)) + size_t max_key; + size_t max_val; + size_t first = 0; + for (; first < _map_->capacity; first++) { - size_t iter_key = hm_iter_key(&iter); - size_t iter_val = hm_iter_value(&iter); - if (_map_->f_key->cmp(iter_key, max_key) > 0) + if (_map_->buffer[first].state == CMC_ES_FILLED) { - max_key = iter_key; - max_val = iter_val; + max_key = _map_->buffer[first].key; + max_val = _map_->buffer[first].value; + break; + } + } + for (size_t i = first + 1; i < _map_->capacity; i++) + { + if (_map_->buffer[i].state == CMC_ES_FILLED) + { + if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) + { + max_key = _map_->buffer[i].key; + max_val = _map_->buffer[i].value; + } } } if (key) *key = max_key; if (value) *value = max_val; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) @@ -333,26 +334,36 @@ _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } - struct hashmap_iter iter = hm_iter_start(_map_); - size_t min_key = hm_iter_key(&iter); - size_t min_val = hm_iter_value(&iter); - hm_iter_next(&iter); - for (; !hm_iter_at_end(&iter); hm_iter_next(&iter)) + size_t min_key; + size_t min_val; + size_t first = 0; + for (; first < _map_->capacity; first++) { - size_t iter_key = hm_iter_key(&iter); - size_t iter_val = hm_iter_value(&iter); - if (_map_->f_key->cmp(iter_key, min_key) < 0) + if (_map_->buffer[first].state == CMC_ES_FILLED) { - min_key = iter_key; - min_val = iter_val; + min_key = _map_->buffer[first].key; + min_val = _map_->buffer[first].value; + break; + } + } + for (size_t i = first + 1; i < _map_->capacity; i++) + { + if (_map_->buffer[i].state == CMC_ES_FILLED) + { + if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) + { + min_key = _map_->buffer[i].key; + min_val = _map_->buffer[i].value; + } } } if (key) *key = min_key; if (value) *value = min_val; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } size_t hm_get(struct hashmap *_map_, size_t key) @@ -369,8 +380,9 @@ size_t hm_get(struct hashmap *_map_, size_t key) return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return entry->value; } size_t *hm_get_ref(struct hashmap *_map_, size_t key) @@ -387,16 +399,18 @@ size_t *hm_get_ref(struct hashmap *_map_, size_t key) return ((void *)0); } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return &(entry->value); } _Bool hm_contains(struct hashmap *_map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hm_impl_get_entry(_map_, key) != ((void *)0); - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return result; } _Bool hm_empty(struct hashmap *_map_) @@ -448,12 +462,14 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity) _map_->flag = CMC_FLAG_ALLOC; return 0; } - struct hashmap_iter iter = hm_iter_start(_map_); - for (; !hm_iter_at_end(&iter); hm_iter_next(&iter)) + for (size_t i = 0; i < _map_->capacity; i++) { - size_t key = hm_iter_key(&iter); - size_t value = hm_iter_value(&iter); - hm_insert(_new_map_, key, value); + if (_map_->buffer[i].state == CMC_ES_FILLED) + { + size_t key = _map_->buffer[i].key; + size_t value = _map_->buffer[i].value; + hm_insert(_new_map_, key, value); + } } if (_map_->count != _new_map_->count) { @@ -471,19 +487,21 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity) _new_map_->f_val = &(struct hashmap_fval){ ((void *)0) }; hm_free(_new_map_); success: - if (_map_->callbacks && _map_->callbacks->resize) - _map_->callbacks->resize(); + if ((_map_)->callbacks && (_map_)->callbacks->resize) + (_map_)->callbacks->resize(); + ; return 1; } struct hashmap *hm_copy_of(struct hashmap *_map_) { struct hashmap *result = hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, _map_->callbacks); + _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _map_->callbacks; if (_map_->f_key->cpy || _map_->f_val->cpy) { for (size_t i = 0; i < _map_->capacity; i++) @@ -522,17 +540,97 @@ _Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_) _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; - struct hashmap_iter iter = hm_iter_start(_map1_); - for (; !hm_iter_at_end(&iter); hm_iter_next(&iter)) + struct hashmap *_map_a_; + struct hashmap *_map_b_; + _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; + _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; + for (size_t i = 0; i < _map_a_->capacity; i++) { - struct hashmap_entry *entry = hm_impl_get_entry(_map2_, hm_iter_key(&iter)); - if (entry == ((void *)0)) - return 0; - if (_map1_->f_val->cmp(entry->value, hm_iter_value(&iter)) != 0) - return 0; + if (_map_a_->buffer[i].state == CMC_ES_FILLED) + { + struct hashmap_entry *entry_a = &(_map_a_->buffer[i]); + struct hashmap_entry *entry_b = hm_impl_get_entry(_map_b_, entry_a->key); + if (!entry_b) + return 0; + if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) + return 0; + } } return 1; } +static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key) +{ + size_t hash = _map_->f_key->hash(key); + size_t pos = hash % _map_->capacity; + struct hashmap_entry *target = &(_map_->buffer[pos]); + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) + { + if (_map_->f_key->cmp(target->key, key) == 0) + return target; + pos++; + target = &(_map_->buffer[pos % _map_->capacity]); + } + return ((void *)0); +} +static size_t hm_impl_calculate_size(size_t required) +{ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; +} +struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) +{ + return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); +} +struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + struct hashmap _map_ = { 0 }; + if (capacity == 0 || load <= 0 || load >= 1) + return _map_; + if (capacity >= 0xffffffffffffffffULL * load) + return _map_; + if (!f_key || !f_val) + return _map_; + size_t real_capacity = hm_impl_calculate_size(capacity / load); + if (!alloc) + alloc = &cmc_alloc_node_default; + _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); + if (!_map_.buffer) + return _map_; + _map_.count = 0; + _map_.capacity = real_capacity; + _map_.load = load; + _map_.flag = CMC_FLAG_OK; + _map_.f_key = f_key; + _map_.f_val = f_val; + _map_.alloc = alloc; + (&_map_)->callbacks = callbacks; + return _map_; +} +void hm_release(struct hashmap _map_) +{ + if (_map_.f_key->free || _map_.f_val->free) + { + for (size_t i = 0; i < _map_.capacity; i++) + { + struct hashmap_entry *entry = &(_map_.buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (_map_.f_key->free) + _map_.f_key->free(entry->key); + if (_map_.f_val->free) + _map_.f_val->free(entry->value); + } + } + } + _map_.alloc->free(_map_.buffer); +} struct hashmap_iter hm_iter_start(struct hashmap *target) { struct hashmap_iter iter; @@ -734,29 +832,57 @@ size_t hm_iter_index(struct hashmap_iter *iter) { return iter->index; } -static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key) +_Bool hm_to_string(struct hashmap *_map_, FILE *fptr) { - size_t hash = _map_->f_key->hash(key); - size_t pos = hash % _map_->capacity; - struct hashmap_entry *target = &(_map_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) - { - if (_map_->f_key->cmp(target->key, key) == 0) - return target; - pos++; - target = &(_map_->buffer[pos % _map_->capacity]); - } - return ((void *)0); + struct hashmap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashmap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } -static size_t hm_impl_calculate_size(size_t required) +_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep) { - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _map_->capacity; i > 0; i--) + { + if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashmap_entry *entry = &(_map_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (!_map_->f_key->str(fptr, entry->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, entry->value)) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_HASHMAP */ diff --git a/tests/main/src/hashmultimap.c b/tests/main/src/hashmultimap.c index 981f107..0813264 100644 --- a/tests/main/src/hashmultimap.c +++ b/tests/main/src/hashmultimap.c @@ -40,17 +40,6 @@ struct hashmultimap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct hashmultimap_iter -{ - struct hashmultimap *target; - struct hashmultimap_entry *curr_entry; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, struct hashmultimap_fval *f_val); struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, @@ -79,8 +68,17 @@ int hmm_flag(struct hashmultimap *_map_); _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity); struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_); _Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_); -struct cmc_string hmm_to_string(struct hashmultimap *_map_); -_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr); +struct hashmultimap_iter +{ + struct hashmultimap *target; + struct hashmultimap_entry *curr_entry; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target); struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target); _Bool hmm_iter_at_start(struct hashmultimap_iter *iter); @@ -96,6 +94,9 @@ size_t hmm_iter_key(struct hashmultimap_iter *iter); size_t hmm_iter_value(struct hashmultimap_iter *iter); size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter); size_t hmm_iter_index(struct hashmultimap_iter *iter); +_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr); +_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value); struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key); size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key); @@ -103,37 +104,13 @@ size_t hmm_impl_calculate_size(size_t required); struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, struct hashmultimap_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || load <= 0) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - size_t real_capacity = hmm_impl_calculate_size(capacity / load); - struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); - if (!_map_->buffer) - { - alloc->free(_map_); - return ((void *)0); - } - _map_->count = 0; - _map_->capacity = real_capacity; - _map_->load = load; - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->alloc = alloc; - _map_->callbacks = ((void *)0); - return _map_; + return hmm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || load <= 0) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) @@ -159,7 +136,7 @@ struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmul _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; return _map_; } void hmm_clear(struct hashmultimap *_map_) @@ -219,11 +196,12 @@ void hmm_free(struct hashmultimap *_map_) } void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value) @@ -249,8 +227,9 @@ _Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value) } _map_->count++; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->create) - _map_->callbacks->create(); + if ((_map_)->callbacks && (_map_)->callbacks->create) + (_map_)->callbacks->create(); + ; return 1; } _Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value) @@ -270,8 +249,9 @@ _Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_ *old_value = entry->value; entry->value = new_value; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return 1; } size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values) @@ -316,8 +296,9 @@ size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, entry = entry->next; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return index; } _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) @@ -383,8 +364,9 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) _map_->alloc->free(entry); _map_->count--; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return 1; } size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values) @@ -455,8 +437,9 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_value } _map_->count -= index; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return index; } _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) @@ -490,8 +473,9 @@ _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) if (value) *value = max_val; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) @@ -525,8 +509,9 @@ _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) if (value) *value = min_val; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } size_t hmm_get(struct hashmultimap *_map_, size_t key) @@ -543,8 +528,9 @@ size_t hmm_get(struct hashmultimap *_map_, size_t key) return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return entry->value; } size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key) @@ -561,16 +547,18 @@ size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key) return ((void *)0); } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return &(entry->value); } _Bool hmm_contains(struct hashmultimap *_map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hmm_impl_get_entry(_map_, key) != ((void *)0); - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return result; } _Bool hmm_empty(struct hashmultimap *_map_) @@ -649,8 +637,9 @@ _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity) _new_map_->f_val = &(struct hashmultimap_fval){ ((void *)0) }; hmm_free(_new_map_); success: - if (_map_->callbacks && _map_->callbacks->resize) - _map_->callbacks->resize(); + if ((_map_)->callbacks && (_map_)->callbacks->resize) + (_map_)->callbacks->resize(); + ; return 1; } struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_) @@ -676,7 +665,7 @@ struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_) hmm_insert(result, key, value); } } - result->callbacks = _map_->callbacks; + (result)->callbacks = _map_->callbacks; _map_->flag = CMC_FLAG_OK; return result; } @@ -695,6 +684,54 @@ _Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_) } return 1; } +struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value) +{ + struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); + if (!entry) + return ((void *)0); + entry->key = key; + entry->value = value; + entry->next = ((void *)0); + entry->prev = ((void *)0); + return entry; +} +struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key) +{ + size_t hash = _map_->f_key->hash(key); + struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; + while (entry != ((void *)0)) + { + if (_map_->f_key->cmp(entry->key, key) == 0) + return entry; + entry = entry->next; + } + return ((void *)0); +} +size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key) +{ + size_t hash = _map_->f_key->hash(key); + struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; + size_t total_count = 0; + if (!entry) + return total_count; + while (entry != ((void *)0)) + { + if (_map_->f_key->cmp(entry->key, key) == 0) + total_count++; + entry = entry->next; + } + return total_count; +} +size_t hmm_impl_calculate_size(size_t required) +{ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; +} struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target) { struct hashmultimap_iter iter; @@ -710,7 +747,8 @@ struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target) { for (size_t i = 0; i < target->capacity; i++) { - if (target->buffer[i][0] != ((void *)0)) + struct hashmultimap_entry *entry = target->buffer[i][0]; + if (entry && entry != ((void *)1)) { iter.curr_entry = target->buffer[i][0]; iter.first = i; @@ -720,7 +758,8 @@ struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target) iter.cursor = iter.first; for (size_t i = target->capacity; i > 0; i--) { - if (target->buffer[i - 1][1] != ((void *)0)) + struct hashmultimap_entry *entry = target->buffer[i - 1][1]; + if (entry && entry != ((void *)1)) { iter.last = i - 1; break; @@ -744,7 +783,8 @@ struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target) { for (size_t i = 0; i < target->capacity; i++) { - if (target->buffer[i][0] != ((void *)0)) + struct hashmultimap_entry *entry = target->buffer[i][0]; + if (entry && entry != ((void *)1)) { iter.first = i; break; @@ -752,7 +792,8 @@ struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target) } for (size_t i = target->capacity; i > 0; i--) { - if (target->buffer[i - 1][1] != ((void *)0)) + struct hashmultimap_entry *entry = target->buffer[i - 1][1]; + if (entry && entry != ((void *)1)) { iter.curr_entry = target->buffer[i - 1][1]; iter.last = i - 1; @@ -910,53 +951,59 @@ size_t hmm_iter_index(struct hashmultimap_iter *iter) { return iter->index; } -struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value) +_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr) { - struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); - if (!entry) - return ((void *)0); - entry->key = key; - entry->value = value; - entry->next = ((void *)0); - entry->prev = ((void *)0); - return entry; + struct hashmultimap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashmultimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } -struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key) +_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep) { - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - while (entry != ((void *)0)) + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _map_->capacity; i > 0; i--) { - if (_map_->f_key->cmp(entry->key, key) == 0) - return entry; - entry = entry->next; + struct hashmultimap_entry *entry = _map_->buffer[i - 1][1]; + if (entry && entry != ((void *)1)) + { + last = i - 1; + break; + } } - return ((void *)0); -} -size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key) -{ - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - size_t total_count = 0; - if (!entry) - return total_count; - while (entry != ((void *)0)) + for (size_t i = 0; i < _map_->capacity; i++) { - if (_map_->f_key->cmp(entry->key, key) == 0) - total_count++; - entry = entry->next; + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan != ((void *)0)) + { + if (!_map_->f_key->str(fptr, scan->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, scan->value)) + return 0; + scan = scan->next; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } } - return total_count; -} -size_t hmm_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_HASHMULTIMAP */ diff --git a/tests/main/src/hashmultiset.c b/tests/main/src/hashmultiset.c index b87f565..ff0c2a7 100644 --- a/tests/main/src/hashmultiset.c +++ b/tests/main/src/hashmultiset.c @@ -31,16 +31,6 @@ struct hashmultiset_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct hashmultiset_iter -{ - struct hashmultiset *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val); struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -66,18 +56,16 @@ int hms_flag(struct hashmultiset *_set_); _Bool hms_resize(struct hashmultiset *_set_, size_t capacity); struct hashmultiset *hms_copy_of(struct hashmultiset *_set_); _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct cmc_string hms_to_string(struct hashmultiset *_set_); -_Bool hms_print(struct hashmultiset *_set_, FILE *fptr); -struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset_iter +{ + struct hashmultiset *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; struct hashmultiset_iter hms_iter_start(struct hashmultiset *target); struct hashmultiset_iter hms_iter_end(struct hashmultiset *target); _Bool hms_iter_at_start(struct hashmultiset_iter *iter); @@ -92,42 +80,31 @@ _Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index); size_t hms_iter_value(struct hashmultiset_iter *iter); size_t hms_iter_multiplicity(struct hashmultiset_iter *iter); size_t hms_iter_index(struct hashmultiset_iter *iter); +struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr); +_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value); static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node); static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value); static size_t hms_impl_calculate_size(size_t required); struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_val) - return ((void *)0); - size_t real_capacity = hms_impl_calculate_size(capacity / load); - struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset)); - if (!_set_) - return ((void *)0); - _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); - if (!_set_->buffer) - { - alloc->free(_set_); - return ((void *)0); - } - _set_->count = 0; - _set_->cardinality = 0; - _set_->capacity = real_capacity; - _set_->load = load; - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - _set_->callbacks = ((void *)0); - return _set_; + return hms_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); } struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) @@ -153,7 +130,7 @@ struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmul _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; return _set_; } void hms_clear(struct hashmultiset *_set_) @@ -191,11 +168,12 @@ void hms_free(struct hashmultiset *_set_) } void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _Bool hms_insert(struct hashmultiset *_set_, size_t value) @@ -211,8 +189,9 @@ _Bool hms_insert(struct hashmultiset *_set_, size_t value) entry->multiplicity++; _set_->cardinality++; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->create) - _set_->callbacks->create(); + if ((_set_)->callbacks && (_set_)->callbacks->create) + (_set_)->callbacks->create(); + ; return 1; } _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count) @@ -233,8 +212,9 @@ _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count) _set_->cardinality += count; success: _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->create) - _set_->callbacks->create(); + if ((_set_)->callbacks && (_set_)->callbacks->create) + (_set_)->callbacks->create(); + ; return 1; } _Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity) @@ -262,8 +242,9 @@ _Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity) entry->multiplicity = multiplicity; success: _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->update) - _set_->callbacks->update(); + if ((_set_)->callbacks && (_set_)->callbacks->update) + (_set_)->callbacks->update(); + ; return 1; } _Bool hms_remove(struct hashmultiset *_set_, size_t value) @@ -291,8 +272,9 @@ _Bool hms_remove(struct hashmultiset *_set_, size_t value) } _set_->cardinality--; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->delete) - _set_->callbacks->delete (); + if ((_set_)->callbacks && (_set_)->callbacks->delete) + (_set_)->callbacks->delete (); + ; return 1; } size_t hms_remove_all(struct hashmultiset *_set_, size_t value) @@ -316,8 +298,9 @@ size_t hms_remove_all(struct hashmultiset *_set_, size_t value) _set_->count--; _set_->cardinality -= removed; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->delete) - _set_->callbacks->delete (); + if ((_set_)->callbacks && (_set_)->callbacks->delete) + (_set_)->callbacks->delete (); + ; return removed; } _Bool hms_max(struct hashmultiset *_set_, size_t *value) @@ -341,8 +324,9 @@ _Bool hms_max(struct hashmultiset *_set_, size_t *value) if (value) *value = max_val; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } _Bool hms_min(struct hashmultiset *_set_, size_t *value) @@ -366,16 +350,18 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value) if (value) *value = min_val; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value) { struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; if (!entry) return 0; return entry->multiplicity; @@ -384,8 +370,9 @@ _Bool hms_contains(struct hashmultiset *_set_, size_t value) { _set_->flag = CMC_FLAG_OK; _Bool result = hms_impl_get_entry(_set_, value) != ((void *)0); - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return result; } _Bool hms_empty(struct hashmultiset *_set_) @@ -460,19 +447,21 @@ _Bool hms_resize(struct hashmultiset *_set_, size_t capacity) _new_set_->f_val = &(struct hashmultiset_fval){ ((void *)0) }; hms_free(_new_set_); success: - if (_set_->callbacks && _set_->callbacks->resize) - _set_->callbacks->resize(); + if ((_set_)->callbacks && (_set_)->callbacks->resize) + (_set_)->callbacks->resize(); + ; return 1; } struct hashmultiset *hms_copy_of(struct hashmultiset *_set_) { struct hashmultiset *result = - hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, _set_->callbacks); + hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _set_->callbacks; if (_set_->f_val->cpy) { for (size_t i = 0; i < _set_->capacity; i++) @@ -521,186 +510,97 @@ _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) } return 1; } -struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value) { - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) - { - size_t value = hms_iter_value(&iter1); - size_t m1 = hms_iter_multiplicity(&iter1); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - size_t max_ = m1 > m2 ? m1 : m2; - hms_update(_set_r_, value, max_); - } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - size_t value = hms_iter_value(&iter2); - size_t m1 = hms_impl_multiplicity_of(_set1_, value); - size_t m2 = hms_iter_multiplicity(&iter2); - size_t max_ = m1 > m2 ? m1 : m2; - hms_update(_set_r_, value, max_); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; + struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); + if (!entry) + return 0; + return entry->multiplicity; } -struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node) { - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct hashmultiset_iter iter = hms_iter_start(_set_A_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + *new_node = 0; + struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); + if (entry != ((void *)0)) + return entry; + *new_node = 1; + if (hms_full(_set_)) { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set_B_, value); - size_t max_ = m1 < m2 ? m1 : m2; - hms_update(_set_r_, value, max_); + if (!hms_resize(_set_, _set_->capacity + 1)) + return ((void *)0); } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + size_t hash = _set_->f_val->hash(value); + size_t original_pos = hash % _set_->capacity; + size_t pos = original_pos; + size_t curr_mul = 1; + struct hashmultiset_entry *target = &(_set_->buffer[pos]); + struct hashmultiset_entry *to_return = ((void *)0); + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); + target->value = value; + target->multiplicity = curr_mul; + target->dist = pos - original_pos; + target->state = CMC_ES_FILLED; + to_return = target; } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) + else { - hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1)); - } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2)); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) - { - size_t value = hms_iter_value(&iter1); - size_t m1 = hms_iter_multiplicity(&iter1); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 != m2) + while (1) { - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); - else - hms_update(_set_r_, value, m2 - m1); + pos++; + target = &(_set_->buffer[pos % _set_->capacity]); + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) + { + target->value = value; + target->multiplicity = curr_mul; + target->dist = pos - original_pos; + target->state = CMC_ES_FILLED; + if (!to_return) + to_return = target; + break; + } + else if (target->dist < pos - original_pos) + { + size_t tmp = target->value; + size_t tmp_dist = target->dist; + size_t tmp_mul = target->multiplicity; + target->value = value; + target->dist = pos - original_pos; + target->multiplicity = curr_mul; + value = tmp; + original_pos = pos - tmp_dist; + curr_mul = tmp_mul; + if (!to_return) + to_return = target; + } } } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - size_t value = hms_iter_value(&iter2); - size_t m1 = hms_impl_multiplicity_of(_set1_, value); - size_t m2 = hms_iter_multiplicity(&iter2); - if (m1 != m2) - { - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); - else - hms_update(_set_r_, value, m2 - m1); - } - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; + _set_->count++; + return to_return; } -_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value) { - if (_set1_->count > _set2_->count) - return 0; - if (hms_empty(_set1_)) - return 1; - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + size_t hash = _set_->f_val->hash(value); + size_t pos = hash % _set_->capacity; + struct hashmultiset_entry *target = &(_set_->buffer[pos]); + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 > m2) - return 0; + if (_set_->f_val->cmp(target->value, value) == 0) + return target; + pos++; + target = &(_set_->buffer[pos % _set_->capacity]); } - return 1; + return ((void *)0); } -_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +static size_t hms_impl_calculate_size(size_t required) { - return hms_is_subset(_set2_, _set1_); -} -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - if (_set1_->count >= _set2_->count) - return 0; - if (hms_empty(_set1_)) - { - if (!hms_empty(_set2_)) - return 1; - else - return 0; - } - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 >= m2) - return 0; - } - return 1; -} -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - return hms_is_proper_subset(_set2_, _set1_); -} -_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - if (hms_empty(_set1_)) - return 1; - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - if (hms_impl_get_entry(_set2_, value) != ((void *)0)) - return 0; - } - return 1; + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; } struct hashmultiset_iter hms_iter_start(struct hashmultiset *target) { @@ -897,97 +797,244 @@ size_t hms_iter_index(struct hashmultiset_iter *iter) { return iter->index; } -static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value) +struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { - struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - if (!entry) - return 0; - return entry->multiplicity; + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter1 = hms_iter_start(_set1_); + struct hashmultiset_iter iter2 = hms_iter_start(_set2_); + for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) + { + size_t value = hms_iter_value(&iter1); + size_t m1 = hms_iter_multiplicity(&iter1); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + size_t max_ = m1 > m2 ? m1 : m2; + hms_update(_set_r_, value, max_); + } + for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) + { + size_t value = hms_iter_value(&iter2); + size_t m1 = hms_impl_multiplicity_of(_set1_, value); + size_t m2 = hms_iter_multiplicity(&iter2); + size_t max_ = m1 > m2 ? m1 : m2; + hms_update(_set_r_, value, max_); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; } -static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node) +struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { - *new_node = 0; - struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - if (entry != ((void *)0)) - return entry; - *new_node = 1; - if (hms_full(_set_)) + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; + struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; + struct hashmultiset_iter iter = hms_iter_start(_set_A_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { - if (!hms_resize(_set_, _set_->capacity + 1)) - return ((void *)0); + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set_B_, value); + size_t max_ = m1 < m2 ? m1 : m2; + hms_update(_set_r_, value, max_); } - size_t hash = _set_->f_val->hash(value); - size_t original_pos = hash % _set_->capacity; - size_t pos = original_pos; - size_t curr_mul = 1; - struct hashmultiset_entry *target = &(_set_->buffer[pos]); - struct hashmultiset_entry *to_return = ((void *)0); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { - target->value = value; - target->multiplicity = curr_mul; - target->dist = pos - original_pos; - target->state = CMC_ES_FILLED; - to_return = target; + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 > m2) + hms_update(_set_r_, value, m1 - m2); } - else + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter1 = hms_iter_start(_set1_); + struct hashmultiset_iter iter2 = hms_iter_start(_set2_); + for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) { - while (1) + hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1)); + } + for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) + { + hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2)); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter1 = hms_iter_start(_set1_); + struct hashmultiset_iter iter2 = hms_iter_start(_set2_); + for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) + { + size_t value = hms_iter_value(&iter1); + size_t m1 = hms_iter_multiplicity(&iter1); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 != m2) { - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->value = value; - target->multiplicity = curr_mul; - target->dist = pos - original_pos; - target->state = CMC_ES_FILLED; - if (!to_return) - to_return = target; - break; - } - else if (target->dist < pos - original_pos) - { - size_t tmp = target->value; - size_t tmp_dist = target->dist; - size_t tmp_mul = target->multiplicity; - target->value = value; - target->dist = pos - original_pos; - target->multiplicity = curr_mul; - value = tmp; - original_pos = pos - tmp_dist; - curr_mul = tmp_mul; - if (!to_return) - to_return = target; - } + if (m1 > m2) + hms_update(_set_r_, value, m1 - m2); + else + hms_update(_set_r_, value, m2 - m1); } } - _set_->count++; - return to_return; -} -static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value) -{ - size_t hash = _set_->f_val->hash(value); - size_t pos = hash % _set_->capacity; - struct hashmultiset_entry *target = &(_set_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) + for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) { - if (_set_->f_val->cmp(target->value, value) == 0) - return target; - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); + size_t value = hms_iter_value(&iter2); + size_t m1 = hms_impl_multiplicity_of(_set1_, value); + size_t m2 = hms_iter_multiplicity(&iter2); + if (m1 != m2) + { + if (m1 > m2) + hms_update(_set_r_, value, m1 - m2); + else + hms_update(_set_r_, value, m2 - m1); + } } - return ((void *)0); + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; } -static size_t hms_impl_calculate_size(size_t required) +_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; + if (_set1_->count > _set2_->count) + return 0; + if (hms_empty(_set1_)) + return 1; + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 > m2) + return 0; + } + return 1; +} +_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + return hms_is_subset(_set2_, _set1_); +} +_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + if (_set1_->count >= _set2_->count) + return 0; + if (hms_empty(_set1_)) + { + if (!hms_empty(_set2_)) + return 1; + else + return 0; + } + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 >= m2) + return 0; + } + return 1; +} +_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + return hms_is_proper_subset(_set2_, _set1_); +} +_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + if (hms_empty(_set1_)) + return 1; + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + if (hms_impl_get_entry(_set2_, value) != ((void *)0)) + return 0; + } + return 1; +} +_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr) +{ + struct hashmultiset *s_ = _set_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "cardinality:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashmultiset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, s_->load, + s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); +} +_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *val_mul_sep) +{ + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _set_->capacity; i > 0; i--) + { + if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashmultiset_entry *entry = &(_set_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (!_set_->f_val->str(fptr, entry->value)) + return 0; + fprintf(fptr, "%s", val_mul_sep); + if (fprintf(fptr, + "%" + "I64u" + "", + entry->multiplicity) < 0) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_HASHMULTISET */ diff --git a/tests/main/src/hashset.c b/tests/main/src/hashset.c index f4b278f..cf11adb 100644 --- a/tests/main/src/hashset.c +++ b/tests/main/src/hashset.c @@ -29,16 +29,6 @@ struct hashset_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct hashset_iter -{ - struct hashset *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val); struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -59,17 +49,16 @@ int hs_flag(struct hashset *_set_); _Bool hs_resize(struct hashset *_set_, size_t capacity); struct hashset *hs_copy_of(struct hashset *_set_); _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_); -struct cmc_string hs_to_string(struct hashset *_set_); -_Bool hs_print(struct hashset *_set_, FILE *fptr); -struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_); +struct hashset_iter +{ + struct hashset *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; struct hashset_iter hs_iter_start(struct hashset *target); struct hashset_iter hs_iter_end(struct hashset *target); _Bool hs_iter_at_start(struct hashset_iter *iter); @@ -83,41 +72,27 @@ _Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps); _Bool hs_iter_go_to(struct hashset_iter *iter, size_t index); size_t hs_iter_value(struct hashset_iter *iter); size_t hs_iter_index(struct hashset_iter *iter); +struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_to_string(struct hashset *_set_, FILE *fptr); +_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value); static size_t hs_impl_calculate_size(size_t required); -static struct hashset_iter hs_impl_it_start(struct hashset *_set_); -static struct hashset_iter hs_impl_it_end(struct hashset *_set_); struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_val) - return ((void *)0); - size_t real_capacity = hs_impl_calculate_size(capacity / load); - struct hashset *_set_ = alloc->malloc(sizeof(struct hashset)); - if (!_set_) - return ((void *)0); - _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashset_entry)); - if (!_set_->buffer) - { - alloc->free(_set_); - return ((void *)0); - } - _set_->count = 0; - _set_->capacity = real_capacity; - _set_->load = load; - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - _set_->callbacks = ((void *)0); - return _set_; + return hs_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); } struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) @@ -142,7 +117,7 @@ struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; return _set_; } void hs_clear(struct hashset *_set_) @@ -180,11 +155,12 @@ void hs_free(struct hashset *_set_) } void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _Bool hs_insert(struct hashset *_set_, size_t value) @@ -235,8 +211,9 @@ _Bool hs_insert(struct hashset *_set_, size_t value) } _set_->count++; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->create) - _set_->callbacks->create(); + if ((_set_)->callbacks && (_set_)->callbacks->create) + (_set_)->callbacks->create(); + ; return 1; } _Bool hs_remove(struct hashset *_set_, size_t value) @@ -257,8 +234,9 @@ _Bool hs_remove(struct hashset *_set_, size_t value) result->state = CMC_ES_DELETED; _set_->count--; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->delete) - _set_->callbacks->delete (); + if ((_set_)->callbacks && (_set_)->callbacks->delete) + (_set_)->callbacks->delete (); + ; return 1; } _Bool hs_max(struct hashset *_set_, size_t *value) @@ -282,8 +260,9 @@ _Bool hs_max(struct hashset *_set_, size_t *value) if (value) *value = max_value; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } _Bool hs_min(struct hashset *_set_, size_t *value) @@ -307,16 +286,18 @@ _Bool hs_min(struct hashset *_set_, size_t *value) if (value) *value = min_value; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } _Bool hs_contains(struct hashset *_set_, size_t value) { _set_->flag = CMC_FLAG_OK; _Bool result = hs_impl_get_entry(_set_, value) != ((void *)0); - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return result; } _Bool hs_empty(struct hashset *_set_) @@ -388,19 +369,21 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity) _new_set_->f_val = &(struct hashset_fval){ ((void *)0) }; hs_free(_new_set_); success: - if (_set_->callbacks && _set_->callbacks->resize) - _set_->callbacks->resize(); + if ((_set_)->callbacks && (_set_)->callbacks->resize) + (_set_)->callbacks->resize(); + ; return 1; } struct hashset *hs_copy_of(struct hashset *_set_) { struct hashset *result = - hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, _set_->callbacks); + hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _set_->callbacks; if (_set_->f_val->cpy) { for (size_t i = 0; i < _set_->capacity; i++) @@ -442,155 +425,29 @@ _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_) } return 1; } -struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_) +static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value) { - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) + size_t hash = _set_->f_val->hash(value); + size_t pos = hash % _set_->capacity; + struct hashset_entry *target = &(_set_->buffer[pos]); + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); + if (_set_->f_val->cmp(target->value, value) == 0) + return target; + pos++; + target = &(_set_->buffer[pos % _set_->capacity]); } - struct hashset_iter iter1 = hs_iter_start(_set1_); - struct hashset_iter iter2 = hs_iter_start(_set2_); - for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) - { - hs_insert(_set_r_, hs_iter_value(&iter1)); - } - for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) - { - hs_insert(_set_r_, hs_iter_value(&iter2)); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; + return ((void *)0); } -struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_) +static size_t hs_impl_calculate_size(size_t required) { - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct hashset_iter iter = hs_iter_start(_set_A_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set_B_, value) != ((void *)0)) - hs_insert(_set_r_, value); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_) -{ - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_) -{ - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset_iter iter1 = hs_iter_start(_set1_); - struct hashset_iter iter2 = hs_iter_start(_set2_); - for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) - { - size_t value = hs_iter_value(&iter1); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) - { - size_t value = hs_iter_value(&iter2); - if (hs_impl_get_entry(_set1_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count > _set2_->count) - return 0; - if (hs_empty(_set1_)) - return 1; - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_) -{ - return hs_is_subset(_set2_, _set1_); -} -_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count >= _set2_->count) - return 0; - if (hs_empty(_set1_)) - { - if (!hs_empty(_set2_)) - return 1; - else - return 0; - } - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_) -{ - return hs_is_proper_subset(_set2_, _set1_); -} -_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (hs_empty(_set1_)) - return 1; - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) != ((void *)0)) - return 0; - } - return 1; + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; } struct hashset_iter hs_iter_start(struct hashset *target) { @@ -781,29 +638,202 @@ size_t hs_iter_index(struct hashset_iter *iter) { return iter->index; } -static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value) +struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_) { - size_t hash = _set_->f_val->hash(value); - size_t pos = hash % _set_->capacity; - struct hashset_entry *target = &(_set_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) { - if (_set_->f_val->cmp(target->value, value) == 0) - return target; - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); } - return ((void *)0); + struct hashset_iter iter1 = hs_iter_start(_set1_); + struct hashset_iter iter2 = hs_iter_start(_set2_); + for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) + { + hs_insert(_set_r_, hs_iter_value(&iter1)); + } + for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) + { + hs_insert(_set_r_, hs_iter_value(&iter2)); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; } -static size_t hs_impl_calculate_size(size_t required) +struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_) { - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + { + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; + struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; + struct hashset_iter iter = hs_iter_start(_set_A_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set_B_, value) != ((void *)0)) + hs_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_) +{ + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + { + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + hs_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_) +{ + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + { + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + struct hashset_iter iter1 = hs_iter_start(_set1_); + struct hashset_iter iter2 = hs_iter_start(_set2_); + for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) + { + size_t value = hs_iter_value(&iter1); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + hs_insert(_set_r_, value); + } + for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) + { + size_t value = hs_iter_value(&iter2); + if (hs_impl_get_entry(_set1_, value) == ((void *)0)) + hs_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (_set1_->count > _set2_->count) + return 0; + if (hs_empty(_set1_)) + return 1; + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + return 0; + } + return 1; +} +_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_) +{ + return hs_is_subset(_set2_, _set1_); +} +_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (_set1_->count >= _set2_->count) + return 0; + if (hs_empty(_set1_)) + { + if (!hs_empty(_set2_)) + return 1; + else + return 0; + } + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + return 0; + } + return 1; +} +_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_) +{ + return hs_is_proper_subset(_set2_, _set1_); +} +_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (hs_empty(_set1_)) + return 1; + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) != ((void *)0)) + return 0; + } + return 1; +} +_Bool hs_to_string(struct hashset *_set_, FILE *fptr) +{ + struct hashset *s_ = _set_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p }", + "hashset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->load, s_->flag, s_->f_val, + s_->alloc, (s_)->callbacks); +} +_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _set_->capacity; i > 0; i--) + { + if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashset_entry *entry = &(_set_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (!_set_->f_val->str(fptr, entry->value)) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_HASHSET */ diff --git a/tests/main/src/heap.c b/tests/main/src/heap.c index 37b968d..5e435b9 100644 --- a/tests/main/src/heap.c +++ b/tests/main/src/heap.c @@ -23,13 +23,6 @@ struct heap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct heap_iter -{ - struct heap *target; - size_t cursor; - _Bool start; - _Bool end; -}; struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val); struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -48,8 +41,13 @@ int h_flag(struct heap *_heap_); _Bool h_resize(struct heap *_heap_, size_t capacity); struct heap *h_copy_of(struct heap *_heap_); _Bool h_equals(struct heap *_heap1_, struct heap *_heap2_); -struct cmc_string h_to_string(struct heap *_heap_); -_Bool h_print(struct heap *_heap_, FILE *fptr); +struct heap_iter +{ + struct heap *target; + size_t cursor; + _Bool start; + _Bool end; +}; struct heap_iter h_iter_start(struct heap *target); struct heap_iter h_iter_end(struct heap *target); _Bool h_iter_at_start(struct heap_iter *iter); @@ -63,38 +61,18 @@ _Bool h_iter_rewind(struct heap_iter *iter, size_t steps); _Bool h_iter_go_to(struct heap_iter *iter, size_t index); size_t h_iter_value(struct heap_iter *iter); size_t h_iter_index(struct heap_iter *iter); +_Bool h_to_string(struct heap *_heap_, FILE *fptr); +_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); static void h_impl_float_up(struct heap *_heap_, size_t index); static void h_impl_float_down(struct heap *_heap_, size_t index); struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity < 1) - return ((void *)0); - if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) - return ((void *)0); - if (!f_val) - return ((void *)0); - struct heap *_heap_ = alloc->malloc(sizeof(struct heap)); - if (!_heap_) - return ((void *)0); - _heap_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_heap_->buffer) - { - alloc->free(_heap_); - return ((void *)0); - } - _heap_->capacity = capacity; - _heap_->count = 0; - _heap_->HO = HO; - _heap_->flag = CMC_FLAG_OK; - _heap_->f_val = f_val; - _heap_->alloc = alloc; - _heap_->callbacks = ((void *)0); - return _heap_; + return h_new_custom(capacity, HO, f_val, ((void *)0), ((void *)0)); } struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) @@ -118,7 +96,7 @@ struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_f _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; - _heap_->callbacks = callbacks; + (_heap_)->callbacks = callbacks; return _heap_; } void h_clear(struct heap *_heap_) @@ -148,11 +126,12 @@ void h_free(struct heap *_heap_) } void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _heap_->alloc = &cmc_alloc_node_default; else _heap_->alloc = alloc; - _heap_->callbacks = callbacks; + (_heap_)->callbacks = callbacks; _heap_->flag = CMC_FLAG_OK; } _Bool h_insert(struct heap *_heap_, size_t value) @@ -168,8 +147,9 @@ _Bool h_insert(struct heap *_heap_, size_t value) h_impl_float_up(_heap_, _heap_->count - 1); } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->create) - _heap_->callbacks->create(); + if ((_heap_)->callbacks && (_heap_)->callbacks->create) + (_heap_)->callbacks->create(); + ; return 1; } _Bool h_remove(struct heap *_heap_) @@ -184,8 +164,9 @@ _Bool h_remove(struct heap *_heap_) _heap_->count--; h_impl_float_down(_heap_, 0); _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->delete) - _heap_->callbacks->delete (); + if ((_heap_)->callbacks && (_heap_)->callbacks->delete) + (_heap_)->callbacks->delete (); + ; return 1; } size_t h_peek(struct heap *_heap_) @@ -196,8 +177,9 @@ size_t h_peek(struct heap *_heap_) return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->read) - _heap_->callbacks->read(); + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; return _heap_->buffer[0]; } _Bool h_contains(struct heap *_heap_, size_t value) @@ -212,8 +194,9 @@ _Bool h_contains(struct heap *_heap_, size_t value) break; } } - if (_heap_->callbacks && _heap_->callbacks->read) - _heap_->callbacks->read(); + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; return result; } _Bool h_empty(struct heap *_heap_) @@ -255,18 +238,20 @@ _Bool h_resize(struct heap *_heap_, size_t capacity) _heap_->buffer = new_buffer; _heap_->capacity = capacity; success: - if (_heap_->callbacks && _heap_->callbacks->resize) - _heap_->callbacks->resize(); + if ((_heap_)->callbacks && (_heap_)->callbacks->resize) + (_heap_)->callbacks->resize(); + ; return 1; } struct heap *h_copy_of(struct heap *_heap_) { - struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, _heap_->callbacks); + struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, ((void *)0)); if (!result) { _heap_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _heap_->callbacks; if (_heap_->f_val->cpy) { for (size_t i = 0; i < _heap_->count; i++) @@ -291,6 +276,51 @@ _Bool h_equals(struct heap *_heap1_, struct heap *_heap2_) } return 1; } +static void h_impl_float_up(struct heap *_heap_, size_t index) +{ + size_t C = index; + size_t child = _heap_->buffer[C]; + size_t parent = _heap_->buffer[(index - 1) / 2]; + int mod = _heap_->HO; + while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) + { + size_t tmp = _heap_->buffer[C]; + _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; + _heap_->buffer[(C - 1) / 2] = tmp; + C = (C - 1) / 2; + if (C == 0) + break; + child = _heap_->buffer[C]; + parent = _heap_->buffer[(C - 1) / 2]; + } +} +static void h_impl_float_down(struct heap *_heap_, size_t index) +{ + int mod = _heap_->HO; + while (index < _heap_->count) + { + size_t L = 2 * index + 1; + size_t R = 2 * index + 2; + size_t C = index; + if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) + { + C = L; + } + if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) + { + C = R; + } + if (C != index) + { + size_t tmp = _heap_->buffer[index]; + _heap_->buffer[index] = _heap_->buffer[C]; + _heap_->buffer[C] = tmp; + index = C; + } + else + break; + } +} struct heap_iter h_iter_start(struct heap *target) { struct heap_iter iter; @@ -419,50 +449,40 @@ size_t h_iter_index(struct heap_iter *iter) { return iter->cursor; } -static void h_impl_float_up(struct heap *_heap_, size_t index) +_Bool h_to_string(struct heap *_heap_, FILE *fptr) { - size_t C = index; - size_t child = _heap_->buffer[C]; - size_t parent = _heap_->buffer[(index - 1) / 2]; - int mod = _heap_->HO; - while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) - { - size_t tmp = _heap_->buffer[C]; - _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; - _heap_->buffer[(C - 1) / 2] = tmp; - C = (C - 1) / 2; - if (C == 0) - break; - child = _heap_->buffer[C]; - parent = _heap_->buffer[(C - 1) / 2]; - } + struct heap *h_ = _heap_; + const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "type:%s, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p}", + "heap", "size_t", h_, h_->buffer, h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc, + (h_)->callbacks); } -static void h_impl_float_down(struct heap *_heap_, size_t index) +_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end) { - int mod = _heap_->HO; - while (index < _heap_->count) + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _heap_->count; i++) { - size_t L = 2 * index + 1; - size_t R = 2 * index + 2; - size_t C = index; - if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) - { - C = L; - } - if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) - { - C = R; - } - if (C != index) - { - size_t tmp = _heap_->buffer[index]; - _heap_->buffer[index] = _heap_->buffer[C]; - _heap_->buffer[C] = tmp; - index = C; - } - else - break; + if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) + return 0; + if (i + 1 < _heap_->count) + fprintf(fptr, "%s", separator); } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_HEAP */ diff --git a/tests/main/src/intervalheap.c b/tests/main/src/intervalheap.c index f72ad33..b609bfb 100644 --- a/tests/main/src/intervalheap.c +++ b/tests/main/src/intervalheap.c @@ -23,13 +23,6 @@ struct intervalheap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct intervalheap_iter -{ - struct intervalheap *target; - size_t cursor; - _Bool start; - _Bool end; -}; struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val); struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -50,10 +43,15 @@ size_t ih_count(struct intervalheap *_heap_); size_t ih_capacity(struct intervalheap *_heap_); int ih_flag(struct intervalheap *_heap_); _Bool ih_resize(struct intervalheap *_heap_, size_t capacity); -struct intervalheap *ih_copy_of(struct intervalheap *_set_); +struct intervalheap *ih_copy_of(struct intervalheap *_heap_); _Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_); -struct cmc_string ih_to_string(struct intervalheap *_heap_); -_Bool ih_print(struct intervalheap *_heap_, FILE *fptr); +struct intervalheap_iter +{ + struct intervalheap *target; + size_t cursor; + _Bool start; + _Bool end; +}; struct intervalheap_iter ih_iter_start(struct intervalheap *target); struct intervalheap_iter ih_iter_end(struct intervalheap *target); _Bool ih_iter_at_start(struct intervalheap_iter *iter); @@ -67,39 +65,20 @@ _Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps); _Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index); size_t ih_iter_value(struct intervalheap_iter *iter); size_t ih_iter_index(struct intervalheap_iter *iter); +_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr); +_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); static void ih_impl_float_up_max(struct intervalheap *_heap_); static void ih_impl_float_up_min(struct intervalheap *_heap_); static void ih_impl_float_down_max(struct intervalheap *_heap_); static void ih_impl_float_down_min(struct intervalheap *_heap_); struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || capacity == 0xffffffffffffffffULL) - return ((void *)0); - if (!f_val) - return ((void *)0); - struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap)); - if (!_heap_) - return ((void *)0); - capacity = (capacity + capacity % 2) / 2; - _heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2])); - if (!_heap_->buffer) - { - alloc->free(_heap_); - return ((void *)0); - } - _heap_->capacity = capacity; - _heap_->size = 0; - _heap_->count = 0; - _heap_->flag = CMC_FLAG_OK; - _heap_->f_val = f_val; - _heap_->alloc = alloc; - _heap_->callbacks = ((void *)0); - return _heap_; + return ih_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || capacity == 0xffffffffffffffffULL) return ((void *)0); if (!f_val) @@ -122,7 +101,7 @@ struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_ _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; - _heap_->callbacks = callbacks; + (_heap_)->callbacks = callbacks; return _heap_; } void ih_clear(struct intervalheap *_heap_) @@ -153,11 +132,12 @@ void ih_free(struct intervalheap *_heap_) } void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _heap_->alloc = &cmc_alloc_node_default; else _heap_->alloc = alloc; - _heap_->callbacks = callbacks; + (_heap_)->callbacks = callbacks; _heap_->flag = CMC_FLAG_OK; } _Bool ih_insert(struct intervalheap *_heap_, size_t value) @@ -196,8 +176,9 @@ _Bool ih_insert(struct intervalheap *_heap_, size_t value) else if (_heap_->f_val->cmp((*parent)[1], value) < 0) ih_impl_float_up_max(_heap_); } - if (_heap_->callbacks && _heap_->callbacks->create) - _heap_->callbacks->create(); + if ((_heap_)->callbacks && (_heap_)->callbacks->create) + (_heap_)->callbacks->create(); + ; return 1; } _Bool ih_remove_max(struct intervalheap *_heap_) @@ -230,8 +211,9 @@ _Bool ih_remove_max(struct intervalheap *_heap_) ih_impl_float_down_max(_heap_); success: _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->delete) - _heap_->callbacks->delete (); + if ((_heap_)->callbacks && (_heap_)->callbacks->delete) + (_heap_)->callbacks->delete (); + ; return 1; } _Bool ih_remove_min(struct intervalheap *_heap_) @@ -264,8 +246,9 @@ _Bool ih_remove_min(struct intervalheap *_heap_) ih_impl_float_down_min(_heap_); success: _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->delete) - _heap_->callbacks->delete (); + if ((_heap_)->callbacks && (_heap_)->callbacks->delete) + (_heap_)->callbacks->delete (); + ; return 1; } _Bool ih_update_max(struct intervalheap *_heap_, size_t value) @@ -291,8 +274,9 @@ _Bool ih_update_max(struct intervalheap *_heap_, size_t value) ih_impl_float_down_max(_heap_); } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->update) - _heap_->callbacks->update(); + if ((_heap_)->callbacks && (_heap_)->callbacks->update) + (_heap_)->callbacks->update(); + ; return 1; } _Bool ih_update_min(struct intervalheap *_heap_, size_t value) @@ -318,8 +302,9 @@ _Bool ih_update_min(struct intervalheap *_heap_, size_t value) ih_impl_float_down_min(_heap_); } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->update) - _heap_->callbacks->update(); + if ((_heap_)->callbacks && (_heap_)->callbacks->update) + (_heap_)->callbacks->update(); + ; return 1; } size_t ih_max(struct intervalheap *_heap_) @@ -330,8 +315,9 @@ size_t ih_max(struct intervalheap *_heap_) return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->read) - _heap_->callbacks->read(); + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; if (_heap_->count == 1) return _heap_->buffer[0][0]; return _heap_->buffer[0][1]; @@ -344,8 +330,9 @@ size_t ih_min(struct intervalheap *_heap_) return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->read) - _heap_->callbacks->read(); + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; return _heap_->buffer[0][0]; } _Bool ih_contains(struct intervalheap *_heap_, size_t value) @@ -360,8 +347,9 @@ _Bool ih_contains(struct intervalheap *_heap_, size_t value) break; } } - if (_heap_->callbacks && _heap_->callbacks->read) - _heap_->callbacks->read(); + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; return result; } _Bool ih_empty(struct intervalheap *_heap_) @@ -413,8 +401,9 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity) _heap_->capacity = capacity; success: _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->resize) - _heap_->callbacks->resize(); + if ((_heap_)->callbacks && (_heap_)->callbacks->resize) + (_heap_)->callbacks->resize(); + ; return 1; } struct intervalheap *ih_copy_of(struct intervalheap *_heap_) @@ -446,7 +435,7 @@ struct intervalheap *ih_copy_of(struct intervalheap *_heap_) result->flag = CMC_FLAG_OK; result->f_val = _heap_->f_val; result->alloc = _heap_->alloc; - result->callbacks = _heap_->callbacks; + (result)->callbacks = _heap_->callbacks; _heap_->flag = CMC_FLAG_OK; return result; } @@ -465,134 +454,6 @@ _Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_) } return 1; } -struct intervalheap_iter ih_iter_start(struct intervalheap *target) -{ - struct intervalheap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = ih_empty(target); - return iter; -} -struct intervalheap_iter ih_iter_end(struct intervalheap *target) -{ - struct intervalheap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = ih_empty(target); - iter.end = 1; - if (!ih_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -_Bool ih_iter_at_start(struct intervalheap_iter *iter) -{ - return ih_empty(iter->target) || iter->start; -} -_Bool ih_iter_at_end(struct intervalheap_iter *iter) -{ - return ih_empty(iter->target) || iter->end; -} -_Bool ih_iter_to_start(struct intervalheap_iter *iter) -{ - if (!ih_empty(iter->target)) - { - iter->cursor = 0; - iter->start = 1; - iter->end = ih_empty(iter->target); - return 1; - } - return 0; -} -_Bool ih_iter_to_end(struct intervalheap_iter *iter) -{ - if (!ih_empty(iter->target)) - { - iter->cursor = iter->target->count - 1; - iter->start = ih_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool ih_iter_next(struct intervalheap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = ih_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool ih_iter_prev(struct intervalheap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - iter->end = ih_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - if (iter->end) - return 0; - iter->start = ih_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->end = ih_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return ih_iter_rewind(iter, iter->cursor - index); - else if (iter->cursor < index) - return ih_iter_advance(iter, index - iter->cursor); - return 1; -} -size_t ih_iter_value(struct intervalheap_iter *iter) -{ - if (ih_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; -} -size_t ih_iter_index(struct intervalheap_iter *iter) -{ - return iter->cursor; -} static void ih_impl_float_up_max(struct intervalheap *_heap_) { size_t index = _heap_->size - 1; @@ -725,5 +586,169 @@ static void ih_impl_float_down_min(struct intervalheap *_heap_) curr_node = child_node; } } +struct intervalheap_iter ih_iter_start(struct intervalheap *target) +{ + struct intervalheap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = 1; + iter.end = ih_empty(target); + return iter; +} +struct intervalheap_iter ih_iter_end(struct intervalheap *target) +{ + struct intervalheap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = ih_empty(target); + iter.end = 1; + if (!ih_empty(target)) + iter.cursor = target->count - 1; + return iter; +} +_Bool ih_iter_at_start(struct intervalheap_iter *iter) +{ + return ih_empty(iter->target) || iter->start; +} +_Bool ih_iter_at_end(struct intervalheap_iter *iter) +{ + return ih_empty(iter->target) || iter->end; +} +_Bool ih_iter_to_start(struct intervalheap_iter *iter) +{ + if (!ih_empty(iter->target)) + { + iter->cursor = 0; + iter->start = 1; + iter->end = ih_empty(iter->target); + return 1; + } + return 0; +} +_Bool ih_iter_to_end(struct intervalheap_iter *iter) +{ + if (!ih_empty(iter->target)) + { + iter->cursor = iter->target->count - 1; + iter->start = ih_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool ih_iter_next(struct intervalheap_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = ih_empty(iter->target); + iter->cursor++; + return 1; +} +_Bool ih_iter_prev(struct intervalheap_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + iter->end = ih_empty(iter->target); + iter->cursor--; + return 1; +} +_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->cursor + steps >= iter->target->count) + return 0; + if (iter->end) + return 0; + iter->start = ih_empty(iter->target); + iter->cursor += steps; + return 1; +} +_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->cursor < steps) + return 0; + iter->end = ih_empty(iter->target); + iter->cursor -= steps; + return 1; +} +_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->cursor > index) + return ih_iter_rewind(iter, iter->cursor - index); + else if (iter->cursor < index) + return ih_iter_advance(iter, index - iter->cursor); + return 1; +} +size_t ih_iter_value(struct intervalheap_iter *iter) +{ + if (ih_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; +} +size_t ih_iter_index(struct intervalheap_iter *iter) +{ + return iter->cursor; +} +_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr) +{ + struct intervalheap *h_ = _heap_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "size:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "intervalheap", "size_t", h_, h_->buffer, h_->capacity, h_->size, h_->count, h_->flag, + h_->f_val, h_->alloc, (h_)->callbacks); +} +_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _heap_->count; i++) + { + if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) + return 0; + if (i + 1 < _heap_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_INTERVALHEAP */ diff --git a/tests/main/src/linkedlist.c b/tests/main/src/linkedlist.c index e07b066..3030f9b 100644 --- a/tests/main/src/linkedlist.c +++ b/tests/main/src/linkedlist.c @@ -28,14 +28,6 @@ struct linkedlist_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct linkedlist_iter -{ - struct linkedlist *target; - struct linkedlist_node *cursor; - size_t index; - _Bool start; - _Bool end; -}; struct linkedlist *ll_new(struct linkedlist_fval *f_val); struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -58,20 +50,14 @@ size_t ll_count(struct linkedlist *_list_); int ll_flag(struct linkedlist *_list_); struct linkedlist *ll_copy_of(struct linkedlist *_list_); _Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_); -struct cmc_string ll_to_string(struct linkedlist *_list_); -_Bool ll_print(struct linkedlist *_list_, FILE *fptr); -struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value); -void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_); -struct linkedlist_node *ll_head(struct linkedlist *_list_); -struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index); -struct linkedlist_node *ll_tail(struct linkedlist *_list_); -_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); -_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); -_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_); -_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_); -_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_); -struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_); -struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_); +struct linkedlist_iter +{ + struct linkedlist *target; + struct linkedlist_node *cursor; + size_t index; + _Bool start; + _Bool end; +}; struct linkedlist_iter ll_iter_start(struct linkedlist *target); struct linkedlist_iter ll_iter_end(struct linkedlist *target); _Bool ll_iter_at_start(struct linkedlist_iter *iter); @@ -87,26 +73,28 @@ size_t ll_iter_value(struct linkedlist_iter *iter); size_t *ll_iter_rvalue(struct linkedlist_iter *iter); size_t ll_iter_index(struct linkedlist_iter *iter); struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter); +struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value); +void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_); +struct linkedlist_node *ll_head(struct linkedlist *_list_); +struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index); +struct linkedlist_node *ll_tail(struct linkedlist *_list_); +_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); +_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); +_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_); +_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_); +_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_); +struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_); +struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_); +_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr); +_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); struct linkedlist *ll_new(struct linkedlist_fval *f_val) { - if (!f_val) - return ((void *)0); - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - struct linkedlist *_list_ = alloc->malloc(sizeof(struct linkedlist)); - if (!_list_) - return ((void *)0); - _list_->count = 0; - _list_->head = ((void *)0); - _list_->tail = ((void *)0); - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - _list_->callbacks = ((void *)0); - return _list_; + return ll_new_custom(f_val, ((void *)0), ((void *)0)); } struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!f_val) return ((void *)0); if (!alloc) @@ -120,7 +108,7 @@ struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; return _list_; } void ll_clear(struct linkedlist *_list_) @@ -148,11 +136,12 @@ void ll_free(struct linkedlist *_list_) } void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool ll_push_front(struct linkedlist *_list_, size_t value) @@ -173,8 +162,9 @@ _Bool ll_push_front(struct linkedlist *_list_, size_t value) } _list_->count++; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index) @@ -202,8 +192,9 @@ _Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index) _node_->prev->next = _node_; _list_->count++; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool ll_push_back(struct linkedlist *_list_, size_t value) @@ -224,8 +215,9 @@ _Bool ll_push_back(struct linkedlist *_list_, size_t value) } _list_->count++; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool ll_pop_front(struct linkedlist *_list_) @@ -244,8 +236,9 @@ _Bool ll_pop_front(struct linkedlist *_list_) _list_->head->prev = ((void *)0); _list_->count--; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } _Bool ll_pop_at(struct linkedlist *_list_, size_t index) @@ -276,8 +269,9 @@ _Bool ll_pop_at(struct linkedlist *_list_, size_t index) _list_->alloc->free(_node_); _list_->count--; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } _Bool ll_pop_back(struct linkedlist *_list_) @@ -296,8 +290,9 @@ _Bool ll_pop_back(struct linkedlist *_list_) _list_->tail->next = ((void *)0); _list_->count--; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } size_t ll_front(struct linkedlist *_list_) @@ -308,8 +303,9 @@ size_t ll_front(struct linkedlist *_list_) return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->head->value; } size_t ll_get(struct linkedlist *_list_, size_t index) @@ -327,8 +323,9 @@ size_t ll_get(struct linkedlist *_list_, size_t index) struct linkedlist_node *scan = ll_get_node(_list_, index); if (scan == ((void *)0)) return (size_t){ 0 }; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return scan->value; } size_t *ll_get_ref(struct linkedlist *_list_, size_t index) @@ -346,8 +343,9 @@ size_t *ll_get_ref(struct linkedlist *_list_, size_t index) struct linkedlist_node *scan = ll_get_node(_list_, index); if (scan == ((void *)0)) return ((void *)0); - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return &(scan->value); } size_t ll_back(struct linkedlist *_list_) @@ -358,8 +356,9 @@ size_t ll_back(struct linkedlist *_list_) return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->tail->value; } _Bool ll_contains(struct linkedlist *_list_, size_t value) @@ -376,8 +375,9 @@ _Bool ll_contains(struct linkedlist *_list_, size_t value) } scan = scan->next; } - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return result; } _Bool ll_empty(struct linkedlist *_list_) @@ -394,9 +394,10 @@ int ll_flag(struct linkedlist *_list_) } struct linkedlist *ll_copy_of(struct linkedlist *_list_) { - struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, _list_->callbacks); + struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, ((void *)0)); if (!result) return ((void *)0); + (result)->callbacks = _list_->callbacks; struct linkedlist_node *scan = _list_->head; while (scan != ((void *)0)) { @@ -439,6 +440,152 @@ _Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_) } return 1; } +struct linkedlist_iter ll_iter_start(struct linkedlist *target) +{ + struct linkedlist_iter iter; + iter.target = target; + iter.cursor = target->head; + iter.index = 0; + iter.start = 1; + iter.end = ll_empty(target); + return iter; +} +struct linkedlist_iter ll_iter_end(struct linkedlist *target) +{ + struct linkedlist_iter iter; + iter.target = target; + iter.cursor = target->tail; + iter.index = 0; + iter.start = ll_empty(target); + iter.end = 1; + if (!ll_empty(target)) + iter.index = target->count - 1; + return iter; +} +_Bool ll_iter_at_start(struct linkedlist_iter *iter) +{ + return ll_empty(iter->target) || iter->start; +} +_Bool ll_iter_at_end(struct linkedlist_iter *iter) +{ + return ll_empty(iter->target) || iter->end; +} +_Bool ll_iter_to_start(struct linkedlist_iter *iter) +{ + if (!ll_empty(iter->target)) + { + iter->cursor = iter->target->head; + iter->index = 0; + iter->start = 1; + iter->end = ll_empty(iter->target); + return 1; + } + return 0; +} +_Bool ll_iter_to_end(struct linkedlist_iter *iter) +{ + if (!ll_empty(iter->target)) + { + iter->cursor = iter->target->tail; + iter->index = iter->target->count - 1; + iter->start = ll_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool ll_iter_next(struct linkedlist_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor->next == ((void *)0)) + { + iter->end = 1; + return 0; + } + iter->start = ll_empty(iter->target); + iter->cursor = iter->cursor->next; + iter->index++; + return 1; +} +_Bool ll_iter_prev(struct linkedlist_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor->prev == ((void *)0)) + { + iter->start = 1; + return 0; + } + iter->end = ll_empty(iter->target); + iter->cursor = iter->cursor->prev; + iter->index--; + return 1; +} +_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor->next == ((void *)0)) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + iter->start = ll_empty(iter->target); + iter->index += steps; + for (size_t i = 0; i < steps; i++) + iter->cursor = iter->cursor->next; + return 1; +} +_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor->prev == ((void *)0)) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + iter->end = ll_empty(iter->target); + iter->index -= steps; + for (size_t i = 0; i < steps; i++) + iter->cursor = iter->cursor->prev; + return 1; +} +_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return ll_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return ll_iter_advance(iter, index - iter->index); + return 1; +} +size_t ll_iter_value(struct linkedlist_iter *iter) +{ + if (ll_empty(iter->target)) + return (size_t){ 0 }; + return iter->cursor->value; +} +size_t *ll_iter_rvalue(struct linkedlist_iter *iter) +{ + if (ll_empty(iter->target)) + return ((void *)0); + return &(iter->cursor->value); +} +size_t ll_iter_index(struct linkedlist_iter *iter) +{ + return iter->index; +} +struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter) +{ + return iter->cursor; +} struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value) { struct linkedlist_node *_node_ = _list_->alloc->malloc(sizeof(struct linkedlist_node)); @@ -587,151 +734,38 @@ struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_) { return _node_->prev; } -struct linkedlist_iter ll_iter_start(struct linkedlist *target) +_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr) { - struct linkedlist_iter iter; - iter.target = target; - iter.cursor = target->head; - iter.index = 0; - iter.start = 1; - iter.end = ll_empty(target); - return iter; + struct linkedlist *l_ = _list_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "count:%" + "I64u" + ", " + "head:%p, " + "tail:%p, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "linkedlist", "size_t", l_, l_->count, l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc, + (l_)->callbacks); } -struct linkedlist_iter ll_iter_end(struct linkedlist *target) +_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end) { - struct linkedlist_iter iter; - iter.target = target; - iter.cursor = target->tail; - iter.index = 0; - iter.start = ll_empty(target); - iter.end = 1; - if (!ll_empty(target)) - iter.index = target->count - 1; - return iter; -} -_Bool ll_iter_at_start(struct linkedlist_iter *iter) -{ - return ll_empty(iter->target) || iter->start; -} -_Bool ll_iter_at_end(struct linkedlist_iter *iter) -{ - return ll_empty(iter->target) || iter->end; -} -_Bool ll_iter_to_start(struct linkedlist_iter *iter) -{ - if (!ll_empty(iter->target)) + fprintf(fptr, "%s", start); + struct linkedlist_node *scan = _list_->head; + while (scan != ((void *)0)) { - iter->cursor = iter->target->head; - iter->index = 0; - iter->start = 1; - iter->end = ll_empty(iter->target); - return 1; + if (!_list_->f_val->str(fptr, scan->value)) + return 0; + scan = scan->next; + if (scan) + fprintf(fptr, "%s", separator); } - return 0; -} -_Bool ll_iter_to_end(struct linkedlist_iter *iter) -{ - if (!ll_empty(iter->target)) - { - iter->cursor = iter->target->tail; - iter->index = iter->target->count - 1; - iter->start = ll_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool ll_iter_next(struct linkedlist_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor->next == ((void *)0)) - { - iter->end = 1; - return 0; - } - iter->start = ll_empty(iter->target); - iter->cursor = iter->cursor->next; - iter->index++; + fprintf(fptr, "%s", end); return 1; } -_Bool ll_iter_prev(struct linkedlist_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor->prev == ((void *)0)) - { - iter->start = 1; - return 0; - } - iter->end = ll_empty(iter->target); - iter->cursor = iter->cursor->prev; - iter->index--; - return 1; -} -_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor->next == ((void *)0)) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - iter->start = ll_empty(iter->target); - iter->index += steps; - for (size_t i = 0; i < steps; i++) - iter->cursor = iter->cursor->next; - return 1; -} -_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor->prev == ((void *)0)) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - iter->end = ll_empty(iter->target); - iter->index -= steps; - for (size_t i = 0; i < steps; i++) - iter->cursor = iter->cursor->prev; - return 1; -} -_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return ll_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return ll_iter_advance(iter, index - iter->index); - return 1; -} -size_t ll_iter_value(struct linkedlist_iter *iter) -{ - if (ll_empty(iter->target)) - return (size_t){ 0 }; - return iter->cursor->value; -} -size_t *ll_iter_rvalue(struct linkedlist_iter *iter) -{ - if (ll_empty(iter->target)) - return ((void *)0); - return &(iter->cursor->value); -} -size_t ll_iter_index(struct linkedlist_iter *iter) -{ - return iter->index; -} -struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter) -{ - return iter->cursor; -} #endif /* CMC_TEST_SRC_LINKEDLIST */ diff --git a/tests/main/src/list.c b/tests/main/src/list.c index eeca0cf..5c5ffbf 100644 --- a/tests/main/src/list.c +++ b/tests/main/src/list.c @@ -22,13 +22,6 @@ struct list_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct list_iter -{ - struct list *target; - size_t cursor; - _Bool start; - _Bool end; -}; struct list *l_new(size_t capacity, struct list_fval *f_val); struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -41,11 +34,6 @@ _Bool l_push_back(struct list *_list_, size_t value); _Bool l_pop_front(struct list *_list_); _Bool l_pop_at(struct list *_list_, size_t index); _Bool l_pop_back(struct list *_list_); -_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index); -_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to); -struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to); size_t l_front(struct list *_list_); size_t l_get(struct list *_list_, size_t index); size_t *l_get_ref(struct list *_list_, size_t index); @@ -61,8 +49,13 @@ int l_flag(struct list *_list_); _Bool l_resize(struct list *_list_, size_t capacity); struct list *l_copy_of(struct list *_list_); _Bool l_equals(struct list *_list1_, struct list *_list2_); -struct cmc_string l_to_string(struct list *_list_); -_Bool l_print(struct list *_list_, FILE *fptr); +struct list_iter +{ + struct list *target; + size_t cursor; + _Bool start; + _Bool end; +}; struct list_iter l_iter_start(struct list *target); struct list_iter l_iter_end(struct list *target); _Bool l_iter_at_start(struct list_iter *iter); @@ -77,31 +70,21 @@ _Bool l_iter_go_to(struct list_iter *iter, size_t index); size_t l_iter_value(struct list_iter *iter); size_t *l_iter_rvalue(struct list_iter *iter); size_t l_iter_index(struct list_iter *iter); +_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size); +_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index); +_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size); +_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to); +struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to); +_Bool l_to_string(struct list *_list_, FILE *fptr); +_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end); struct list *l_new(size_t capacity, struct list_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity < 1) - return ((void *)0); - struct list *_list_ = alloc->malloc(sizeof(struct list)); - if (!_list_) - return ((void *)0); - _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_list_->buffer) - { - alloc->free(_list_); - return ((void *)0); - } - _list_->capacity = capacity; - _list_->count = 0; - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - _list_->callbacks = ((void *)0); - return _list_; + return l_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (!f_val) @@ -122,7 +105,7 @@ struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_a _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; return _list_; } void l_clear(struct list *_list_) @@ -148,11 +131,12 @@ void l_free(struct list *_list_) } void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool l_push_front(struct list *_list_, size_t value) @@ -169,8 +153,9 @@ _Bool l_push_front(struct list *_list_, size_t value) _list_->buffer[0] = value; _list_->count++; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool l_push_at(struct list *_list_, size_t value, size_t index) @@ -189,8 +174,9 @@ _Bool l_push_at(struct list *_list_, size_t value, size_t index) _list_->buffer[index] = value; _list_->count++; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool l_push_back(struct list *_list_, size_t value) @@ -202,8 +188,9 @@ _Bool l_push_back(struct list *_list_, size_t value) } _list_->buffer[_list_->count++] = value; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool l_pop_front(struct list *_list_) @@ -216,8 +203,9 @@ _Bool l_pop_front(struct list *_list_) memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } _Bool l_pop_at(struct list *_list_, size_t index) @@ -235,8 +223,9 @@ _Bool l_pop_at(struct list *_list_, size_t index) memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } _Bool l_pop_back(struct list *_list_) @@ -245,128 +234,11 @@ _Bool l_pop_back(struct list *_list_) return 0; _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } -_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t)); - memcpy(_list_->buffer, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); - return 1; -} -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (index > _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - if (index == 0) - return l_seq_push_front(_list_, values, size); - else if (index == _list_->count) - return l_seq_push_back(_list_, values, size); - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); - memcpy(_list_->buffer + index, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); - return 1; -} -_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); - return 1; -} -_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to) -{ - if (from > to) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (to >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - size_t length = (to - from + 1); - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); - _list_->count -= to - from + 1; - _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); - return 1; -} -struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) -{ - if (from > to) - { - _list_->flag = CMC_FLAG_INVALID; - return ((void *)0); - } - if (to >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return ((void *)0); - } - size_t length = to - from + 1; - struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, _list_->callbacks); - if (!result) - { - _list_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); - _list_->count -= length; - result->count = length; - _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); - return result; -} size_t l_front(struct list *_list_) { if (l_empty(_list_)) @@ -375,8 +247,9 @@ size_t l_front(struct list *_list_) return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[0]; } size_t l_get(struct list *_list_, size_t index) @@ -392,8 +265,9 @@ size_t l_get(struct list *_list_, size_t index) return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[index]; } size_t *l_get_ref(struct list *_list_, size_t index) @@ -409,8 +283,9 @@ size_t *l_get_ref(struct list *_list_, size_t index) return ((void *)0); } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return &(_list_->buffer[index]); } size_t l_back(struct list *_list_) @@ -421,8 +296,9 @@ size_t l_back(struct list *_list_) return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[_list_->count - 1]; } size_t l_index_of(struct list *_list_, size_t value, _Bool from_start) @@ -451,8 +327,9 @@ size_t l_index_of(struct list *_list_, size_t value, _Bool from_start) } } } - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return result; } _Bool l_contains(struct list *_list_, size_t value) @@ -467,8 +344,9 @@ _Bool l_contains(struct list *_list_, size_t value) break; } } - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return result; } _Bool l_empty(struct list *_list_) @@ -513,18 +391,20 @@ _Bool l_resize(struct list *_list_, size_t capacity) } _list_->buffer = new_buffer; _list_->capacity = capacity; - if (_list_->callbacks && _list_->callbacks->resize) - _list_->callbacks->resize(); + if ((_list_)->callbacks && (_list_)->callbacks->resize) + (_list_)->callbacks->resize(); + ; return 1; } struct list *l_copy_of(struct list *_list_) { - struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, _list_->callbacks); + struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0)); if (!result) { _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } + (result)->callbacks = _list_->callbacks; if (_list_->f_val->cpy) { for (size_t i = 0; i < _list_->count; i++) @@ -544,7 +424,7 @@ _Bool l_equals(struct list *_list1_, struct list *_list2_) return 0; for (size_t i = 0; i < _list1_->count; i++) { - if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) + if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) return 0; } return 1; @@ -681,5 +561,161 @@ size_t l_iter_index(struct list_iter *iter) { return iter->cursor; } +_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (!l_fits(_list_, size)) + { + if (!l_resize(_list_, _list_->count + size)) + return 0; + } + memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t)); + memcpy(_list_->buffer, values, size * sizeof(size_t)); + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (index > _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + if (index == 0) + return l_seq_push_front(_list_, values, size); + else if (index == _list_->count) + return l_seq_push_back(_list_, values, size); + if (!l_fits(_list_, size)) + { + if (!l_resize(_list_, _list_->count + size)) + return 0; + } + memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); + memcpy(_list_->buffer + index, values, size * sizeof(size_t)); + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (!l_fits(_list_, size)) + { + if (!l_resize(_list_, _list_->count + size)) + return 0; + } + memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t)); + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to) +{ + if (from > to) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (to >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + size_t length = (to - from + 1); + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); + _list_->count -= to - from + 1; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return 1; +} +struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) +{ + if (from > to) + { + _list_->flag = CMC_FLAG_INVALID; + return ((void *)0); + } + if (to >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return ((void *)0); + } + size_t length = to - from + 1; + struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, (_list_)->callbacks); + if (!result) + { + _list_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); + _list_->count -= length; + result->count = length; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return result; +} +_Bool l_to_string(struct list *_list_, FILE *fptr) +{ + struct list *l_ = _list_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "list", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc, + (l_)->callbacks); +} +_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _list_->count; i++) + { + if (!_list_->f_val->str(fptr, _list_->buffer[i])) + return 0; + if (i + 1 < _list_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_LIST */ diff --git a/tests/main/src/queue.c b/tests/main/src/queue.c index b0a4f7d..e5e6d85 100644 --- a/tests/main/src/queue.c +++ b/tests/main/src/queue.c @@ -50,8 +50,6 @@ int q_flag(struct queue *_queue_); _Bool q_resize(struct queue *_queue_, size_t capacity); struct queue *q_copy_of(struct queue *_queue_); _Bool q_equals(struct queue *_queue1_, struct queue *_queue2_); -struct cmc_string q_to_string(struct queue *_queue_); -_Bool q_print(struct queue *_queue_, FILE *fptr); struct queue_iter q_iter_start(struct queue *target); struct queue_iter q_iter_end(struct queue *target); _Bool q_iter_at_start(struct queue_iter *iter); @@ -66,35 +64,16 @@ _Bool q_iter_go_to(struct queue_iter *iter, size_t index); size_t q_iter_value(struct queue_iter *iter); size_t *q_iter_rvalue(struct queue_iter *iter); size_t q_iter_index(struct queue_iter *iter); +_Bool q_to_string(struct queue *_queue_, FILE *fptr); +_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end); struct queue *q_new(size_t capacity, struct queue_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - struct queue *_queue_ = alloc->malloc(sizeof(struct queue)); - if (!_queue_) - return ((void *)0); - _queue_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_queue_->buffer) - { - alloc->free(_queue_); - return ((void *)0); - } - _queue_->capacity = capacity; - _queue_->count = 0; - _queue_->front = 0; - _queue_->back = 0; - _queue_->flag = CMC_FLAG_OK; - _queue_->f_val = f_val; - _queue_->alloc = alloc; - _queue_->callbacks = ((void *)0); - return _queue_; + return q_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (!f_val) @@ -117,7 +96,7 @@ struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc _queue_->flag = CMC_FLAG_OK; _queue_->f_val = f_val; _queue_->alloc = alloc; - _queue_->callbacks = callbacks; + (_queue_)->callbacks = callbacks; return _queue_; } void q_clear(struct queue *_queue_) @@ -151,11 +130,12 @@ void q_free(struct queue *_queue_) } void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _queue_->alloc = &cmc_alloc_node_default; else _queue_->alloc = alloc; - _queue_->callbacks = callbacks; + (_queue_)->callbacks = callbacks; _queue_->flag = CMC_FLAG_OK; } _Bool q_enqueue(struct queue *_queue_, size_t value) @@ -169,8 +149,9 @@ _Bool q_enqueue(struct queue *_queue_, size_t value) _queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; _queue_->count++; _queue_->flag = CMC_FLAG_OK; - if (_queue_->callbacks && _queue_->callbacks->create) - _queue_->callbacks->create(); + if ((_queue_)->callbacks && (_queue_)->callbacks->create) + (_queue_)->callbacks->create(); + ; return 1; } _Bool q_dequeue(struct queue *_queue_) @@ -184,8 +165,9 @@ _Bool q_dequeue(struct queue *_queue_) _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; _queue_->count--; _queue_->flag = CMC_FLAG_OK; - if (_queue_->callbacks && _queue_->callbacks->delete) - _queue_->callbacks->delete (); + if ((_queue_)->callbacks && (_queue_)->callbacks->delete) + (_queue_)->callbacks->delete (); + ; return 1; } size_t q_peek(struct queue *_queue_) @@ -196,8 +178,9 @@ size_t q_peek(struct queue *_queue_) return (size_t){ 0 }; } _queue_->flag = CMC_FLAG_OK; - if (_queue_->callbacks && _queue_->callbacks->read) - _queue_->callbacks->read(); + if ((_queue_)->callbacks && (_queue_)->callbacks->read) + (_queue_)->callbacks->read(); + ; return _queue_->buffer[_queue_->front]; } _Bool q_contains(struct queue *_queue_, size_t value) @@ -213,8 +196,9 @@ _Bool q_contains(struct queue *_queue_, size_t value) } i = (i + 1) % _queue_->capacity; } - if (_queue_->callbacks && _queue_->callbacks->read) - _queue_->callbacks->read(); + if ((_queue_)->callbacks && (_queue_)->callbacks->read) + (_queue_)->callbacks->read(); + ; return result; } _Bool q_empty(struct queue *_queue_) @@ -264,18 +248,20 @@ _Bool q_resize(struct queue *_queue_, size_t capacity) _queue_->back = _queue_->count; success: _queue_->flag = CMC_FLAG_OK; - if (_queue_->callbacks && _queue_->callbacks->resize) - _queue_->callbacks->resize(); + if ((_queue_)->callbacks && (_queue_)->callbacks->resize) + (_queue_)->callbacks->resize(); + ; return 1; } struct queue *q_copy_of(struct queue *_queue_) { - struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, _queue_->callbacks); + struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, ((void *)0)); if (!result) { _queue_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _queue_->callbacks; if (_queue_->f_val->cpy) { for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) @@ -468,5 +454,45 @@ size_t q_iter_index(struct queue_iter *iter) { return iter->index; } +_Bool q_to_string(struct queue *_queue_, FILE *fptr) +{ + struct queue *q_ = _queue_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "front:%" + "I64u" + ", " + "back:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "queue", "size_t", q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back, q_->flag, + q_->f_val, q_->alloc, (q_)->callbacks); +} +_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) + { + if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) + return 0; + i = (i + 1) % _queue_->capacity; + if (j + 1 < _queue_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_QUEUE */ diff --git a/tests/main/src/sortedlist.c b/tests/main/src/sortedlist.c index cb2f97f..480a08c 100644 --- a/tests/main/src/sortedlist.c +++ b/tests/main/src/sortedlist.c @@ -23,13 +23,6 @@ struct sortedlist_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct sortedlist_iter -{ - struct sortedlist *target; - size_t cursor; - _Bool start; - _Bool end; -}; struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val); struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -52,8 +45,13 @@ _Bool sl_resize(struct sortedlist *_list_, size_t capacity); void sl_sort(struct sortedlist *_list_); struct sortedlist *sl_copy_of(struct sortedlist *_list_); _Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_); -struct cmc_string sl_to_string(struct sortedlist *_list_); -_Bool sl_print(struct sortedlist *_list_, FILE *fptr); +struct sortedlist_iter +{ + struct sortedlist *target; + size_t cursor; + _Bool start; + _Bool end; +}; struct sortedlist_iter sl_iter_start(struct sortedlist *target); struct sortedlist_iter sl_iter_end(struct sortedlist *target); _Bool sl_iter_at_start(struct sortedlist_iter *iter); @@ -67,38 +65,20 @@ _Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps); _Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index); size_t sl_iter_value(struct sortedlist_iter *iter); size_t sl_iter_index(struct sortedlist_iter *iter); +_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr); +_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value); static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value); void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high); void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high); struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - struct sortedlist *_list_ = alloc->malloc(sizeof(struct sortedlist)); - if (!_list_) - return ((void *)0); - _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_list_->buffer) - { - alloc->free(_list_); - return ((void *)0); - } - _list_->capacity = capacity; - _list_->count = 0; - _list_->is_sorted = 0; - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - _list_->callbacks = ((void *)0); - return _list_; + return sl_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (!alloc) @@ -118,7 +98,7 @@ struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; return _list_; } void sl_clear(struct sortedlist *_list_) @@ -144,11 +124,12 @@ void sl_free(struct sortedlist *_list_) } void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool sl_insert(struct sortedlist *_list_, size_t value) @@ -161,8 +142,9 @@ _Bool sl_insert(struct sortedlist *_list_, size_t value) _list_->buffer[_list_->count++] = value; _list_->is_sorted = 0; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool sl_remove(struct sortedlist *_list_, size_t index) @@ -180,8 +162,9 @@ _Bool sl_remove(struct sortedlist *_list_, size_t index) memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } size_t sl_max(struct sortedlist *_list_) @@ -193,8 +176,9 @@ size_t sl_max(struct sortedlist *_list_) } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[_list_->count - 1]; } size_t sl_min(struct sortedlist *_list_) @@ -206,8 +190,9 @@ size_t sl_min(struct sortedlist *_list_) } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[0]; } size_t sl_get(struct sortedlist *_list_, size_t index) @@ -224,16 +209,18 @@ size_t sl_get(struct sortedlist *_list_, size_t index) } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[index]; } size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start) { _list_->flag = CMC_FLAG_OK; sl_sort(_list_); - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; if (from_start) { return sl_impl_binary_search_first(_list_, value); @@ -246,8 +233,9 @@ _Bool sl_contains(struct sortedlist *_list_, size_t value) if (sl_empty(_list_)) return 0; sl_sort(_list_); - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return sl_impl_binary_search_first(_list_, value) < _list_->count; } _Bool sl_empty(struct sortedlist *_list_) @@ -289,8 +277,9 @@ _Bool sl_resize(struct sortedlist *_list_, size_t capacity) _list_->capacity = capacity; success: _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->resize) - _list_->callbacks->resize(); + if ((_list_)->callbacks && (_list_)->callbacks->resize) + (_list_)->callbacks->resize(); + ; return 1; } void sl_sort(struct sortedlist *_list_) @@ -304,12 +293,13 @@ void sl_sort(struct sortedlist *_list_) } struct sortedlist *sl_copy_of(struct sortedlist *_list_) { - struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, _list_->callbacks); + struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0)); if (!result) { _list_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _list_->callbacks; if (_list_->f_val->cpy) { for (size_t i = 0; i < _list_->count; i++) @@ -334,6 +324,95 @@ _Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_) } return 1; } +static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value) +{ + if (sl_empty(_list_)) + return 1; + size_t L = 0; + size_t R = _list_->count; + while (L < R) + { + size_t M = L + (R - L) / 2; + if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) + L = M + 1; + else + R = M; + } + if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) + return L; + return _list_->count; +} +static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value) +{ + if (sl_empty(_list_)) + return 1; + size_t L = 0; + size_t R = _list_->count; + while (L < R) + { + size_t M = L + (R - L) / 2; + if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) + R = M; + else + L = M + 1; + } + if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) + return L - 1; + return _list_->count; +} +void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) +{ + while (low < high) + { + if (high - low < 10) + { + sl_impl_sort_insertion(array, cmp, low, high); + break; + } + else + { + size_t pivot = array[high]; + size_t pindex = low; + for (size_t i = low; i < high; i++) + { + if (cmp(array[i], pivot) <= 0) + { + size_t _tmp_ = array[i]; + array[i] = array[pindex]; + array[pindex] = _tmp_; + pindex++; + } + } + size_t _tmp_ = array[pindex]; + array[pindex] = array[high]; + array[high] = _tmp_; + if (pindex - low < high - pindex) + { + sl_impl_sort_quicksort(array, cmp, low, pindex - 1); + low = pindex + 1; + } + else + { + sl_impl_sort_quicksort(array, cmp, pindex + 1, high); + high = pindex - 1; + } + } + } +} +void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) +{ + for (size_t i = low + 1; i <= high; i++) + { + size_t _tmp_ = array[i]; + size_t j = i; + while (j > low && cmp(array[j - 1], _tmp_) > 0) + { + array[j] = array[j - 1]; + j--; + } + array[j] = _tmp_; + } +} struct sortedlist_iter sl_iter_start(struct sortedlist *target) { sl_sort(target); @@ -462,94 +541,40 @@ size_t sl_iter_index(struct sortedlist_iter *iter) { return iter->cursor; } -static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value) +_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr) { - if (sl_empty(_list_)) - return 1; - size_t L = 0; - size_t R = _list_->count; - while (L < R) - { - size_t M = L + (R - L) / 2; - if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) - L = M + 1; - else - R = M; - } - if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) - return L; - return _list_->count; + struct sortedlist *l_ = _list_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "is_sorted:%s, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "sortedlist", "size_t", l_, l_->buffer, l_->capacity, l_->count, + l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); } -static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value) +_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end) { - if (sl_empty(_list_)) - return 1; - size_t L = 0; - size_t R = _list_->count; - while (L < R) + sl_sort(_list_); + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _list_->count; i++) { - size_t M = L + (R - L) / 2; - if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) - R = M; - else - L = M + 1; - } - if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) - return L - 1; - return _list_->count; -} -void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) -{ - while (low < high) - { - if (high - low < 10) - { - sl_impl_sort_insertion(array, cmp, low, high); - break; - } - else - { - size_t pivot = array[high]; - size_t pindex = low; - for (size_t i = low; i < high; i++) - { - if (cmp(array[i], pivot) <= 0) - { - size_t _tmp_ = array[i]; - array[i] = array[pindex]; - array[pindex] = _tmp_; - pindex++; - } - } - size_t _tmp_ = array[pindex]; - array[pindex] = array[high]; - array[high] = _tmp_; - if (pindex - low < high - pindex) - { - sl_impl_sort_quicksort(array, cmp, low, pindex - 1); - low = pindex + 1; - } - else - { - sl_impl_sort_quicksort(array, cmp, pindex + 1, high); - high = pindex - 1; - } - } - } -} -void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) -{ - for (size_t i = low + 1; i <= high; i++) - { - size_t _tmp_ = array[i]; - size_t j = i; - while (j > low && cmp(array[j - 1], _tmp_) > 0) - { - array[j] = array[j - 1]; - j--; - } - array[j] = _tmp_; + if (!_list_->f_val->str(fptr, _list_->buffer[i])) + return 0; + if (i + 1 < _list_->count) + fprintf(fptr, "%s", separator); } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_SORTEDLIST */ diff --git a/tests/main/src/stack.c b/tests/main/src/stack.c index 69ab69f..1be2b1a 100644 --- a/tests/main/src/stack.c +++ b/tests/main/src/stack.c @@ -22,13 +22,6 @@ struct stack_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct stack_iter -{ - struct stack *target; - size_t cursor; - _Bool start; - _Bool end; -}; struct stack *s_new(size_t capacity, struct stack_fval *f_val); struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -47,8 +40,13 @@ int s_flag(struct stack *_stack_); _Bool s_resize(struct stack *_stack_, size_t capacity); struct stack *s_copy_of(struct stack *_stack_); _Bool s_equals(struct stack *_stack1_, struct stack *_stack2_); -struct cmc_string s_to_string(struct stack *_stack_); -_Bool s_print(struct stack *_stack_, FILE *fptr); +struct stack_iter +{ + struct stack *target; + size_t cursor; + _Bool start; + _Bool end; +}; struct stack_iter s_iter_start(struct stack *target); struct stack_iter s_iter_end(struct stack *target); _Bool s_iter_at_start(struct stack_iter *iter); @@ -63,33 +61,16 @@ _Bool s_iter_go_to(struct stack_iter *iter, size_t index); size_t s_iter_value(struct stack_iter *iter); size_t *s_iter_rvalue(struct stack_iter *iter); size_t s_iter_index(struct stack_iter *iter); +_Bool s_to_string(struct stack *_stack_, FILE *fptr); +_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end); struct stack *s_new(size_t capacity, struct stack_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - struct stack *_stack_ = alloc->malloc(sizeof(struct stack)); - if (!_stack_) - return ((void *)0); - _stack_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_stack_->buffer) - { - alloc->free(_stack_); - return ((void *)0); - } - _stack_->capacity = capacity; - _stack_->count = 0; - _stack_->flag = CMC_FLAG_OK; - _stack_->f_val = f_val; - _stack_->alloc = alloc; - _stack_->callbacks = ((void *)0); - return _stack_; + return s_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (!f_val) @@ -110,7 +91,7 @@ struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc _stack_->flag = CMC_FLAG_OK; _stack_->f_val = f_val; _stack_->alloc = alloc; - _stack_->callbacks = callbacks; + (_stack_)->callbacks = callbacks; return _stack_; } void s_clear(struct stack *_stack_) @@ -136,11 +117,12 @@ void s_free(struct stack *_stack_) } void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _stack_->alloc = &cmc_alloc_node_default; else _stack_->alloc = alloc; - _stack_->callbacks = callbacks; + (_stack_)->callbacks = callbacks; _stack_->flag = CMC_FLAG_OK; } _Bool s_push(struct stack *_stack_, size_t value) @@ -152,8 +134,9 @@ _Bool s_push(struct stack *_stack_, size_t value) } _stack_->buffer[_stack_->count++] = value; _stack_->flag = CMC_FLAG_OK; - if (_stack_->callbacks && _stack_->callbacks->create) - _stack_->callbacks->create(); + if ((_stack_)->callbacks && (_stack_)->callbacks->create) + (_stack_)->callbacks->create(); + ; return 1; } _Bool s_pop(struct stack *_stack_) @@ -165,8 +148,9 @@ _Bool s_pop(struct stack *_stack_) } _stack_->buffer[--_stack_->count] = (size_t){ 0 }; _stack_->flag = CMC_FLAG_OK; - if (_stack_->callbacks && _stack_->callbacks->delete) - _stack_->callbacks->delete (); + if ((_stack_)->callbacks && (_stack_)->callbacks->delete) + (_stack_)->callbacks->delete (); + ; return 1; } size_t s_top(struct stack *_stack_) @@ -177,8 +161,9 @@ size_t s_top(struct stack *_stack_) return (size_t){ 0 }; } _stack_->flag = CMC_FLAG_OK; - if (_stack_->callbacks && _stack_->callbacks->read) - _stack_->callbacks->read(); + if ((_stack_)->callbacks && (_stack_)->callbacks->read) + (_stack_)->callbacks->read(); + ; return _stack_->buffer[_stack_->count - 1]; } _Bool s_contains(struct stack *_stack_, size_t value) @@ -193,8 +178,9 @@ _Bool s_contains(struct stack *_stack_, size_t value) break; } } - if (_stack_->callbacks && _stack_->callbacks->read) - _stack_->callbacks->read(); + if ((_stack_)->callbacks && (_stack_)->callbacks->read) + (_stack_)->callbacks->read(); + ; return result; } _Bool s_empty(struct stack *_stack_) @@ -236,18 +222,20 @@ _Bool s_resize(struct stack *_stack_, size_t capacity) _stack_->capacity = capacity; success: _stack_->flag = CMC_FLAG_OK; - if (_stack_->callbacks && _stack_->callbacks->resize) - _stack_->callbacks->resize(); + if ((_stack_)->callbacks && (_stack_)->callbacks->resize) + (_stack_)->callbacks->resize(); + ; return 1; } struct stack *s_copy_of(struct stack *_stack_) { - struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, _stack_->callbacks); + struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, ((void *)0)); if (!result) { _stack_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (_stack_)->callbacks = callbacks; if (_stack_->f_val->cpy) { for (size_t i = 0; i < _stack_->count; i++) @@ -406,5 +394,38 @@ size_t s_iter_index(struct stack_iter *iter) return 0; return iter->target->count - 1 - iter->cursor; } +_Bool s_to_string(struct stack *_stack_, FILE *fptr) +{ + struct stack *s_ = _stack_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "stack", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc, + (s_)->callbacks); +} +_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = _stack_->count; i > 0; i--) + { + if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) + return 0; + if (i - 1 != 0) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_STACK */ diff --git a/tests/main/src/treemap.c b/tests/main/src/treemap.c index 2f16e80..fa081be 100644 --- a/tests/main/src/treemap.c +++ b/tests/main/src/treemap.c @@ -40,16 +40,6 @@ struct treemap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct treemap_iter -{ - struct treemap *target; - struct treemap_node *cursor; - struct treemap_node *first; - struct treemap_node *last; - size_t index; - _Bool start; - _Bool end; -}; struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val); struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -69,8 +59,16 @@ size_t tm_count(struct treemap *_map_); int tm_flag(struct treemap *_map_); struct treemap *tm_copy_of(struct treemap *_map_); _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_); -struct cmc_string tm_to_string(struct treemap *_map_); -_Bool tm_print(struct treemap *_map_, FILE *fptr); +struct treemap_iter +{ + struct treemap *target; + struct treemap_node *cursor; + struct treemap_node *first; + struct treemap_node *last; + size_t index; + _Bool start; + _Bool end; +}; struct treemap_iter tm_iter_start(struct treemap *target); struct treemap_iter tm_iter_end(struct treemap *target); _Bool tm_iter_at_start(struct treemap_iter *iter); @@ -86,6 +84,9 @@ size_t tm_iter_key(struct treemap_iter *iter); size_t tm_iter_value(struct treemap_iter *iter); size_t *tm_iter_rvalue(struct treemap_iter *iter); size_t tm_iter_index(struct treemap_iter *iter); +_Bool tm_to_string(struct treemap *_map_, FILE *fptr); +_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value); static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key); static unsigned char tm_impl_h(struct treemap_node *node); @@ -95,24 +96,12 @@ static void tm_impl_rotate_left(struct treemap_node **Z); static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node); struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val) { - if (!f_key || !f_val) - return ((void *)0); - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - struct treemap *_map_ = alloc->malloc(sizeof(struct treemap)); - if (!_map_) - return ((void *)0); - _map_->count = 0; - _map_->root = ((void *)0); - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->alloc = alloc; - _map_->callbacks = ((void *)0); - return _map_; + return tm_new_custom(f_key, f_val, ((void *)0), ((void *)0)); } struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!f_key || !f_val) return ((void *)0); if (!alloc) @@ -126,7 +115,7 @@ struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; return _map_; } void tm_clear(struct treemap *_map_) @@ -193,11 +182,12 @@ void tm_free(struct treemap *_map_) } void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) @@ -255,8 +245,9 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) } _map_->count++; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->create) - _map_->callbacks->create(); + if ((_map_)->callbacks && (_map_)->callbacks->create) + (_map_)->callbacks->create(); + ; return 1; } _Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value) @@ -271,8 +262,9 @@ _Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old *old_value = node->value; node->value = new_value; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return 1; } _Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value) @@ -383,8 +375,9 @@ _Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value) _map_->root = ((void *)0); _map_->count--; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return 1; } _Bool tm_max(struct treemap *_map_, size_t *key, size_t *value) @@ -402,8 +395,9 @@ _Bool tm_max(struct treemap *_map_, size_t *key, size_t *value) if (value) *value = scan->value; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } _Bool tm_min(struct treemap *_map_, size_t *key, size_t *value) @@ -421,8 +415,9 @@ _Bool tm_min(struct treemap *_map_, size_t *key, size_t *value) if (value) *value = scan->value; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } size_t tm_get(struct treemap *_map_, size_t key) @@ -439,8 +434,9 @@ size_t tm_get(struct treemap *_map_, size_t key) return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return node->value; } size_t *tm_get_ref(struct treemap *_map_, size_t key) @@ -457,15 +453,17 @@ size_t *tm_get_ref(struct treemap *_map_, size_t key) return ((void *)0); } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return &(node->value); } _Bool tm_contains(struct treemap *_map_, size_t key) { _Bool result = tm_impl_get_node(_map_, key) != ((void *)0); - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return result; } _Bool tm_empty(struct treemap *_map_) @@ -499,7 +497,7 @@ struct treemap *tm_copy_of(struct treemap *_map_) value = _map_->f_val->cpy(value); tm_insert(result, key, value); } - result->callbacks = _map_->callbacks; + (result)->callbacks = _map_->callbacks; _map_->flag = CMC_FLAG_OK; return result; } @@ -520,6 +518,122 @@ _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_) } return 1; } +static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value) +{ + struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node)); + if (!node) + return ((void *)0); + node->key = key; + node->value = value; + node->right = ((void *)0); + node->left = ((void *)0); + node->parent = ((void *)0); + node->height = 0; + return node; +} +static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key) +{ + struct treemap_node *scan = _map_->root; + while (scan != ((void *)0)) + { + if (_map_->f_key->cmp(scan->key, key) > 0) + scan = scan->left; + else if (_map_->f_key->cmp(scan->key, key) < 0) + scan = scan->right; + else + return scan; + } + return ((void *)0); +} +static unsigned char tm_impl_h(struct treemap_node *node) +{ + if (node == ((void *)0)) + return 0; + return node->height; +} +static unsigned char tm_impl_hupdate(struct treemap_node *node) +{ + if (node == ((void *)0)) + return 0; + unsigned char h_l = tm_impl_h(node->left); + unsigned char h_r = tm_impl_h(node->right); + return 1 + (h_l > h_r ? h_l : h_r); +} +static void tm_impl_rotate_right(struct treemap_node **Z) +{ + struct treemap_node *root = *Z; + struct treemap_node *new_root = root->left; + if (root->parent != ((void *)0)) + { + if (root->parent->left == root) + root->parent->left = new_root; + else + root->parent->right = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->left = new_root->right; + if (root->left) + root->left->parent = root; + new_root->right = root; + root->height = tm_impl_hupdate(root); + new_root->height = tm_impl_hupdate(new_root); + *Z = new_root; +} +static void tm_impl_rotate_left(struct treemap_node **Z) +{ + struct treemap_node *root = *Z; + struct treemap_node *new_root = root->right; + if (root->parent != ((void *)0)) + { + if (root->parent->right == root) + root->parent->right = new_root; + else + root->parent->left = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->right = new_root->left; + if (root->right) + root->right->parent = root; + new_root->left = root; + root->height = tm_impl_hupdate(root); + new_root->height = tm_impl_hupdate(new_root); + *Z = new_root; +} +static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node) +{ + struct treemap_node *scan = node, *child = ((void *)0); + int balance; + _Bool is_root = 0; + while (scan != ((void *)0)) + { + if (scan->parent == ((void *)0)) + is_root = 1; + scan->height = tm_impl_hupdate(scan); + balance = tm_impl_h(scan->right) - tm_impl_h(scan->left); + if (balance >= 2) + { + child = scan->right; + if (tm_impl_h(child->right) < tm_impl_h(child->left)) + tm_impl_rotate_right(&(scan->right)); + tm_impl_rotate_left(&scan); + } + else if (balance <= -2) + { + child = scan->left; + if (tm_impl_h(child->left) < tm_impl_h(child->right)) + tm_impl_rotate_left(&(scan->left)); + tm_impl_rotate_right(&scan); + } + if (is_root) + { + _map_->root = scan; + is_root = 0; + } + scan = scan->parent; + } +} struct treemap_iter tm_iter_start(struct treemap *target) { struct treemap_iter iter; @@ -715,121 +829,64 @@ size_t tm_iter_index(struct treemap_iter *iter) { return iter->index; } -static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value) +_Bool tm_to_string(struct treemap *_map_, FILE *fptr) { - struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node)); - if (!node) - return ((void *)0); - node->key = key; - node->value = value; - node->right = ((void *)0); - node->left = ((void *)0); - node->parent = ((void *)0); - node->height = 0; - return node; + struct treemap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "root:%p, " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "f_key:%p, " + "alloc:%p, " + "callbacks:%p }", + "treemap", "size_t", "size_t", m_, m_->root, m_->count, m_->flag, m_->f_key, m_->f_val, + m_->alloc, (m_)->callbacks); } -static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key) +_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep) { - struct treemap_node *scan = _map_->root; - while (scan != ((void *)0)) + fprintf(fptr, "%s", start); + struct treemap_node *root = _map_->root; + _Bool left_done = 0; + size_t i = 0; + while (root) { - if (_map_->f_key->cmp(scan->key, key) > 0) - scan = scan->left; - else if (_map_->f_key->cmp(scan->key, key) < 0) - scan = scan->right; - else - return scan; - } - return ((void *)0); -} -static unsigned char tm_impl_h(struct treemap_node *node) -{ - if (node == ((void *)0)) - return 0; - return node->height; -} -static unsigned char tm_impl_hupdate(struct treemap_node *node) -{ - if (node == ((void *)0)) - return 0; - unsigned char h_l = tm_impl_h(node->left); - unsigned char h_r = tm_impl_h(node->right); - return 1 + (h_l > h_r ? h_l : h_r); -} -static void tm_impl_rotate_right(struct treemap_node **Z) -{ - struct treemap_node *root = *Z; - struct treemap_node *new_root = root->left; - if (root->parent != ((void *)0)) - { - if (root->parent->left == root) - root->parent->left = new_root; - else - root->parent->right = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->left = new_root->right; - if (root->left) - root->left->parent = root; - new_root->right = root; - root->height = tm_impl_hupdate(root); - new_root->height = tm_impl_hupdate(new_root); - *Z = new_root; -} -static void tm_impl_rotate_left(struct treemap_node **Z) -{ - struct treemap_node *root = *Z; - struct treemap_node *new_root = root->right; - if (root->parent != ((void *)0)) - { - if (root->parent->right == root) - root->parent->right = new_root; - else - root->parent->left = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->right = new_root->left; - if (root->right) - root->right->parent = root; - new_root->left = root; - root->height = tm_impl_hupdate(root); - new_root->height = tm_impl_hupdate(new_root); - *Z = new_root; -} -static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node) -{ - struct treemap_node *scan = node, *child = ((void *)0); - int balance; - _Bool is_root = 0; - while (scan != ((void *)0)) - { - if (scan->parent == ((void *)0)) - is_root = 1; - scan->height = tm_impl_hupdate(scan); - balance = tm_impl_h(scan->right) - tm_impl_h(scan->left); - if (balance >= 2) + if (!left_done) { - child = scan->right; - if (tm_impl_h(child->right) < tm_impl_h(child->left)) - tm_impl_rotate_right(&(scan->right)); - tm_impl_rotate_left(&scan); + while (root->left) + root = root->left; } - else if (balance <= -2) + if (!_map_->f_key->str(fptr, root->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, root->value)) + return 0; + if (++i < _map_->count) + fprintf(fptr, "%s", separator); + left_done = 1; + if (root->right) { - child = scan->left; - if (tm_impl_h(child->left) < tm_impl_h(child->right)) - tm_impl_rotate_left(&(scan->left)); - tm_impl_rotate_right(&scan); + left_done = 0; + root = root->right; } - if (is_root) + else if (root->parent) { - _map_->root = scan; - is_root = 0; + while (root->parent && root == root->parent->right) + root = root->parent; + if (!root->parent) + break; + root = root->parent; } - scan = scan->parent; + else + break; } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_TREEMAP */ diff --git a/tests/main/src/treeset.c b/tests/main/src/treeset.c index a1969ef..1bf5884 100644 --- a/tests/main/src/treeset.c +++ b/tests/main/src/treeset.c @@ -55,8 +55,6 @@ size_t ts_count(struct treeset *_set_); int ts_flag(struct treeset *_set_); struct treeset *ts_copy_of(struct treeset *_set_); _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_); -struct cmc_string ts_to_string(struct treeset *_set_); -_Bool ts_print(struct treeset *_set_, FILE *fptr); struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); @@ -79,12 +77,8 @@ _Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps); _Bool ts_iter_go_to(struct treeset_iter *iter, size_t index); size_t ts_iter_value(struct treeset_iter *iter); size_t ts_iter_index(struct treeset_iter *iter); -static inline size_t ts_impl_default_value(void) -{ - size_t _empty_value_; - memset(&_empty_value_, 0, sizeof(size_t)); - return _empty_value_; -} +_Bool ts_to_string(struct treeset *_set_, FILE *fptr); +_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value); static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value); static unsigned char ts_impl_h(struct treeset_node *node); @@ -94,22 +88,11 @@ static void ts_impl_rotate_left(struct treeset_node **Z); static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node); struct treeset *ts_new(struct treeset_fval *f_val) { - if (!f_val) - return ((void *)0); - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - struct treeset *_set_ = alloc->malloc(sizeof(struct treeset)); - if (!_set_) - return ((void *)0); - _set_->count = 0; - _set_->root = ((void *)0); - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - _set_->callbacks = ((void *)0); - return _set_; + return ts_new_custom(f_val, ((void *)0), ((void *)0)); } struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!f_val) return ((void *)0); if (!alloc) @@ -122,7 +105,7 @@ struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; return _set_; } void ts_clear(struct treeset *_set_) @@ -185,11 +168,12 @@ void ts_free(struct treeset *_set_) } void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _Bool ts_insert(struct treeset *_set_, size_t value) @@ -247,8 +231,9 @@ _Bool ts_insert(struct treeset *_set_, size_t value) } _set_->count++; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->create) - _set_->callbacks->create(); + if ((_set_)->callbacks && (_set_)->callbacks->create) + (_set_)->callbacks->create(); + ; return 1; } _Bool ts_remove(struct treeset *_set_, size_t value) @@ -355,8 +340,9 @@ _Bool ts_remove(struct treeset *_set_, size_t value) _set_->root = ((void *)0); _set_->count--; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->delete) - _set_->callbacks->delete (); + if ((_set_)->callbacks && (_set_)->callbacks->delete) + (_set_)->callbacks->delete (); + ; return 1; } _Bool ts_max(struct treeset *_set_, size_t *value) @@ -372,8 +358,9 @@ _Bool ts_max(struct treeset *_set_, size_t *value) if (value) *value = scan->value; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } _Bool ts_min(struct treeset *_set_, size_t *value) @@ -389,15 +376,17 @@ _Bool ts_min(struct treeset *_set_, size_t *value) if (value) *value = scan->value; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } _Bool ts_contains(struct treeset *_set_, size_t value) { _Bool result = ts_impl_get_node(_set_, value) != ((void *)0); - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return result; } _Bool ts_empty(struct treeset *_set_) @@ -414,12 +403,13 @@ int ts_flag(struct treeset *_set_) } struct treeset *ts_copy_of(struct treeset *_set_) { - struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, _set_->callbacks); + struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _set_->callbacks; if (!ts_empty(_set_)) { struct treeset_iter iter = ts_iter_start(_set_); @@ -450,7 +440,7 @@ _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_) } struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter1 = ts_iter_start(_set1_); @@ -463,11 +453,12 @@ struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) { ts_insert(_set_r_, ts_iter_value(&iter2)); } + (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; @@ -479,11 +470,12 @@ struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) if (ts_impl_get_node(_set_B_, value) != ((void *)0)) ts_insert(_set_r_, value); } + (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter = ts_iter_start(_set1_); @@ -493,11 +485,12 @@ struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) if (ts_impl_get_node(_set2_, value) == ((void *)0)) ts_insert(_set_r_, value); } + (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter1 = ts_iter_start(_set1_); @@ -514,6 +507,7 @@ struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset * if (ts_impl_get_node(_set1_, value) == ((void *)0)) ts_insert(_set_r_, value); } + (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } _Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_) @@ -870,5 +864,58 @@ static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node) scan = scan->parent; } } +_Bool ts_to_string(struct treeset *_set_, FILE *fptr) +{ + struct treeset *s_ = _set_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "root:%p, " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "treeset", "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); +} +_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + struct treeset_node *root = _set_->root; + _Bool left_done = 0; + size_t i = 0; + while (root) + { + if (!left_done) + { + while (root->left) + root = root->left; + } + if (!_set_->f_val->str(fptr, root->value)) + return 0; + if (++i < _set_->count) + fprintf(fptr, "%s", separator); + left_done = 1; + if (root->right) + { + left_done = 0; + root = root->right; + } + else if (root->parent) + { + while (root->parent && root == root->parent->right) + root = root->parent; + if (!root->parent) + break; + root = root->parent; + } + else + break; + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_TREESET */ diff --git a/tests/main/unt/bitset.c b/tests/main/unt/bitset.c index 2524a4e..3e6053f 100644 --- a/tests/main/unt/bitset.c +++ b/tests/main/unt/bitset.c @@ -8,7 +8,6 @@ struct cmc_alloc_node *bs_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; CMC_CREATE_UNIT(BitSet, true, { - const size_t word_bytes = sizeof(cmc_bitset_word); const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT; printf("%s", cmc_test_color(5)); @@ -421,8 +420,8 @@ CMC_CREATE_UNIT(BitSet, true, { }); CMC_CREATE_UNIT(BitSetIter, true, { - const size_t word_bytes = sizeof(cmc_bitset_word); - const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT; + // const size_t word_bytes = sizeof(cmc_bitset_word); + // const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT; printf("%s", cmc_test_color(5)); printf(" BitSet<" CMC_TO_STRING(CMC_BITSET_WORD_TYPE) ">\n"); diff --git a/tests/main/unt/hashbidimap.c b/tests/main/unt/hashbidimap.c index 3d73272..1d8bd1e 100644 --- a/tests/main/unt/hashbidimap.c +++ b/tests/main/unt/hashbidimap.c @@ -793,10 +793,13 @@ CMC_CREATE_UNIT(HashBidiMap, true, { }); }); -CMC_CREATE_UNIT(HashBidiMapIter, true, - { - - }); +CMC_CREATE_UNIT(HashBidiMapIter, true, { + CMC_CREATE_TEST(PFX##_iter_start, { + // WIP + cmc_assert(true); + cmc_assert(true); + }); +}); #ifdef CMC_TEST_MAIN int main(void) diff --git a/tests/main/unt/heap.c b/tests/main/unt/heap.c index dcf7e9e..94f2fa8 100644 --- a/tests/main/unt/heap.c +++ b/tests/main/unt/heap.c @@ -123,7 +123,6 @@ CMC_CREATE_UNIT(Heap, true, { for (size_t i = 1; i <= 100; i++) cmc_assert(h_insert(h, i)); - size_t r; size_t i = 0; size_t arr[100]; while (!h_empty(h)) diff --git a/tests/main/unt/utl.c b/tests/main/unt/utl.c index 591157e..391e3b4 100644 --- a/tests/main/unt/utl.c +++ b/tests/main/unt/utl.c @@ -16,16 +16,19 @@ size_t numhash(size_t a) size_t hashcapminus1(size_t a) { + (void)a; return cmc_hashtable_primes[0] - 1; } size_t hashcapminus4(size_t a) { + (void)a; return cmc_hashtable_primes[0] - 1; } size_t hash0(size_t a) { + (void)a; return 0; } @@ -65,6 +68,7 @@ bool k_c_str(FILE *fptr, size_t a) void k_c_free(size_t a) { + (void)a; k_total_free++; } @@ -103,6 +107,7 @@ bool v_c_str(FILE *fptr, size_t a) void v_c_free(size_t a) { + (void)a; v_total_free++; } diff --git a/tests/to_string.c b/tests/to_string.c index 4f37d45..a4e91f7 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -16,6 +16,8 @@ C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l, list, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q, queue, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl, sortedlist, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s, stack, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm, treemap, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts, treeset, , , int)) struct { @@ -49,6 +51,9 @@ int main(void) struct queue *q = q_new(100, (struct queue_fval *)&int_ftab); struct sortedlist *sl = sl_new(100, (struct sortedlist_fval *)&int_ftab); struct stack *s = s_new(100, (struct stack_fval *)&int_ftab); + struct treemap *tm = tm_new((struct treemap_fkey *)&int_ftab, + (struct treemap_fval *)&int_ftab); + struct treeset *ts = ts_new((struct treeset_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -76,6 +81,10 @@ int main(void) sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); s_to_string(s, stdout); s_print(s, stdout, "\n[ ", ", ", " ]\n"); + tm_to_string(tm, stdout); + tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + ts_to_string(ts, stdout); + ts_print(ts, stdout, "\n[ ", ", ", " ]\n"); fprintf(stdout, "\n"); @@ -92,6 +101,8 @@ int main(void) q_enqueue(q, 0); sl_insert(sl, 0); s_push(s, 0); + tm_insert(tm, 0, 0); + ts_insert(ts, 0); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -119,6 +130,10 @@ int main(void) sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); s_to_string(s, stdout); s_print(s, stdout, "\n[ ", ", ", " ]\n"); + tm_to_string(tm, stdout); + tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + ts_to_string(ts, stdout); + ts_print(ts, stdout, "\n[ ", ", ", " ]\n"); for (int i = 1; i < 20; i++) { @@ -135,6 +150,8 @@ int main(void) q_enqueue(q, i); sl_insert(sl, i); s_push(s, i); + tm_insert(tm, i, i); + ts_insert(ts, i); } fprintf(stdout, "\n"); @@ -165,6 +182,10 @@ int main(void) sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); s_to_string(s, stdout); s_print(s, stdout, "\n[ ", ", ", " ]\n"); + tm_to_string(tm, stdout); + tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + ts_to_string(ts, stdout); + ts_print(ts, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hbm_free(hbm); @@ -178,6 +199,9 @@ int main(void) l_free(l); q_free(q); sl_free(sl); + s_free(s); + tm_free(tm); + ts_free(ts); } // clang-format on