diff --git a/src/cmc/deque.h b/src/cmc/deque.h index 6fb89fe..1d94336 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -547,11 +547,10 @@ struct cmc_callbacks_deque \ bool PFX##_resize(struct SNAME *_deque_, size_t capacity) \ { \ + _deque_->flag = cmc_flags.OK; \ + \ if (_deque_->capacity == capacity) \ - { \ - _deque_->flag = cmc_flags.OK; \ return true; \ - } \ \ if (capacity < _deque_->count) \ { \ @@ -581,8 +580,6 @@ struct cmc_callbacks_deque _deque_->front = 0; \ _deque_->back = _deque_->count; \ \ - _deque_->flag = cmc_flags.OK; \ - \ return true; \ } \ \ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index aebb1b9..7a26777 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -343,6 +343,7 @@ struct cmc_callbacks_hashmap struct SNAME *PFX##_copy_of(struct SNAME *_map_); \ bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \ struct cmc_string PFX##_to_string(struct SNAME *_map_); \ + bool PFX##_print(struct SNAME *_map_, FILE *fptr); \ \ /* Iterator Functions */ \ /* Iterator Allocation and Deallocation */ \ @@ -810,6 +811,8 @@ struct cmc_callbacks_hashmap \ bool PFX##_resize(struct SNAME *_map_, size_t capacity) \ { \ + _map_->flag = cmc_flags.OK; \ + \ if (_map_->capacity == capacity) \ return true; \ \ @@ -971,6 +974,23 @@ struct cmc_callbacks_hashmap return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ + bool PFX##_print(struct SNAME *_map_, FILE *fptr) \ + { \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct SNAME##_entry *entry = &(_map_->buffer[i]); \ + \ + if (entry->state == CMC_ES_FILLED) \ + { \ + if (!_map_->f_key->str(fptr, entry->key) || \ + !_map_->f_val->str(fptr, entry->value)) \ + return false; \ + } \ + } \ + \ + return true; \ + } \ + \ struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \ { \ struct SNAME##_iter *iter = \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 6607ff8..98bd4f0 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -309,6 +309,7 @@ struct cmc_callbacks_hashset struct SNAME *PFX##_copy_of(struct SNAME *_set_); \ bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_); \ struct cmc_string PFX##_to_string(struct SNAME *_set_); \ + bool PFX##_print(struct SNAME *_set_, FILE *fptr); \ \ /* Set Operations */ \ struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_); \ @@ -564,12 +565,12 @@ struct cmc_callbacks_hashset \ bool PFX##_remove(struct SNAME *_set_, V element) \ { \ - if (PFX##_empty(_set_))\ - {\ - _set_->flag = cmc_flags.EMPTY;\ - return false;\ - }\ - \ + if (PFX##_empty(_set_)) \ + { \ + _set_->flag = cmc_flags.EMPTY; \ + return false; \ + } \ + \ struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, element); \ \ if (result == NULL) \ @@ -691,6 +692,8 @@ struct cmc_callbacks_hashset \ bool PFX##_resize(struct SNAME *_set_, size_t capacity) \ { \ + _set_->flag = cmc_flags.OK; \ + \ if (_set_->capacity == capacity) \ return true; \ \ @@ -835,6 +838,22 @@ struct cmc_callbacks_hashset return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ + bool PFX##_print(struct SNAME *_set_, FILE *fptr) \ + { \ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct SNAME##_entry *entry = &(_set_->buffer[i]); \ + \ + if (entry->state == CMC_ES_FILLED) \ + { \ + if (!_set_->f_val->str(fptr, entry->value)) \ + return false; \ + } \ + } \ + \ + return true; \ + } \ + \ struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \ { \ struct SNAME *_set_r_ = \ diff --git a/src/cmc/heap.h b/src/cmc/heap.h index e3d0285..c4bb0ce 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -243,11 +243,13 @@ struct cmc_callbacks_heap bool PFX##_full(struct SNAME *_heap_); \ size_t PFX##_count(struct SNAME *_heap_); \ size_t PFX##_capacity(struct SNAME *_heap_); \ + int PFX##_flag(struct SNAME *_heap_); \ /* Collection Utility */ \ bool PFX##_resize(struct SNAME *_heap_, size_t capacity); \ struct SNAME *PFX##_copy_of(struct SNAME *_heap_); \ bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_); \ struct cmc_string PFX##_to_string(struct SNAME *_heap_); \ + bool PFX##_print(struct SNAME *_heap_, FILE *fptr); \ \ /* Iterator Functions */ \ /* Iterator Allocation and Deallocation */ \ @@ -377,6 +379,7 @@ struct cmc_callbacks_heap memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity); \ \ _heap_->count = 0; \ + _heap_->flag = cmc_flags.OK; \ } \ \ void PFX##_free(struct SNAME *_heap_) \ @@ -401,26 +404,36 @@ struct cmc_callbacks_heap \ if (callbacks) \ _heap_->callbacks = callbacks; \ + \ + _heap_->flag = cmc_flags.OK; \ } \ \ bool PFX##_insert(struct SNAME *_heap_, V element) \ { \ if (PFX##_full(_heap_)) \ { \ - if (!PFX##_resize(_heap_, PFX##_count(_heap_) * 2)) \ + if (!PFX##_resize(_heap_, _heap_->count * 2)) \ return false; \ } \ \ if (PFX##_empty(_heap_)) \ { \ _heap_->buffer[_heap_->count++] = element; \ + \ + _heap_->flag = cmc_flags.OK; \ + \ return true; \ } \ \ _heap_->buffer[_heap_->count++] = element; \ \ if (!PFX##_impl_float_up(_heap_, _heap_->count - 1)) \ + { \ + _heap_->flag = cmc_flags.ERROR; \ return false; \ + } \ + \ + _heap_->flag = cmc_flags.OK; \ \ return true; \ } \ @@ -428,16 +441,26 @@ struct cmc_callbacks_heap bool PFX##_remove(struct SNAME *_heap_, V *result) \ { \ if (PFX##_empty(_heap_)) \ + { \ + _heap_->flag = cmc_flags.EMPTY; \ return false; \ + } \ + \ + if (result) \ + *result = _heap_->buffer[0]; \ \ - *result = _heap_->buffer[0]; \ _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; \ _heap_->buffer[_heap_->count - 1] = (V){ 0 }; \ \ _heap_->count--; \ \ if (!PFX##_impl_float_down(_heap_, 0)) \ + { \ + _heap_->flag = cmc_flags.ERROR; \ return false; \ + } \ + \ + _heap_->flag = cmc_flags.OK; \ \ return true; \ } \ @@ -445,13 +468,20 @@ struct cmc_callbacks_heap V PFX##_peek(struct SNAME *_heap_) \ { \ if (PFX##_empty(_heap_)) \ + { \ + _heap_->flag = cmc_flags.EMPTY; \ return (V){ 0 }; \ + } \ + \ + _heap_->flag = cmc_flags.OK; \ \ return _heap_->buffer[0]; \ } \ \ bool PFX##_contains(struct SNAME *_heap_, V element) \ { \ + _heap_->flag = cmc_flags.OK; \ + \ for (size_t i = 0; i < _heap_->count; i++) \ { \ if (_heap_->f_val->cmp(_heap_->buffer[i], element) == 0) \ @@ -481,25 +511,38 @@ struct cmc_callbacks_heap return _heap_->capacity; \ } \ \ + int PFX##_flag(struct SNAME *_heap_) \ + { \ + return _heap_->flag; \ + } \ + \ bool PFX##_resize(struct SNAME *_heap_, size_t capacity) \ { \ - if (PFX##_capacity(_heap_) == capacity) \ + if (_heap_->capacity == capacity) \ return true; \ \ - if (capacity < PFX##_count(_heap_)) \ + if (capacity < _heap_->count) \ + { \ + _heap_->flag = cmc_flags.ERROR; \ return false; \ + } \ \ V *new_buffer = \ _heap_->alloc->realloc(_heap_->buffer, sizeof(V) * capacity); \ \ if (!new_buffer) \ + { \ + _heap_->flag = cmc_flags.ALLOC; \ return false; \ + } \ \ /* TODO zero out new slots */ \ \ _heap_->buffer = new_buffer; \ _heap_->capacity = capacity; \ \ + _heap_->flag = cmc_flags.OK; \ + \ return true; \ } \ \ @@ -510,7 +553,10 @@ struct cmc_callbacks_heap _heap_->alloc, _heap_->callbacks); \ \ if (!result) \ + { \ + _heap_->flag = cmc_flags.ERROR; \ return NULL; \ + } \ \ if (_heap_->f_val->cpy) \ { \ @@ -522,15 +568,20 @@ struct cmc_callbacks_heap \ result->count = _heap_->count; \ \ + _heap_->flag = cmc_flags.OK; \ + \ return result; \ } \ \ bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_) \ { \ - if (PFX##_count(_heap1_) != PFX##_count(_heap2_)) \ + _heap1_->flag = cmc_flags.OK; \ + _heap2_->flag = cmc_flags.OK; \ + \ + if (_heap1_->count != _heap2_->count) \ return false; \ \ - for (size_t i = 0; i < PFX##_count(_heap1_); i++) \ + for (size_t i = 0; i < _heap1_->count; i++) \ { \ if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != \ 0) \ @@ -553,6 +604,17 @@ struct cmc_callbacks_heap return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ + bool PFX##_print(struct SNAME *_heap_, FILE *fptr) \ + { \ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) \ + return false; \ + } \ + \ + return true; \ + } \ + \ struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \ { \ struct SNAME##_iter *iter = \ @@ -603,7 +665,7 @@ struct cmc_callbacks_heap { \ if (!PFX##_empty(iter->target)) \ { \ - iter->cursor = PFX##_count(iter->target) - 1; \ + iter->cursor = iter->target->count - 1; \ iter->start = PFX##_empty(iter->target); \ iter->end = true; \ } \ @@ -614,7 +676,7 @@ struct cmc_callbacks_heap if (iter->end) \ return false; \ \ - if (iter->cursor + 1 == PFX##_count(iter->target)) \ + if (iter->cursor + 1 == iter->target->count) \ { \ iter->end = true; \ return false; \ @@ -651,13 +713,13 @@ struct cmc_callbacks_heap if (iter->start) \ return false; \ \ - if (iter->cursor + 1 == PFX##_count(iter->target)) \ + if (iter->cursor + 1 == iter->target->count) \ { \ iter->end = true; \ return false; \ } \ \ - if (steps == 0 || iter->cursor + steps >= PFX##_count(iter->target)) \ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ return false; \ \ iter->start = PFX##_empty(iter->target); \ @@ -696,7 +758,7 @@ struct cmc_callbacks_heap /* given index */ \ bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ { \ - if (index >= PFX##_count(iter->target)) \ + if (index >= iter->target->count) \ return false; \ \ if (iter->cursor > index) \ diff --git a/tests/main/unt/heap.c b/tests/main/unt/heap.c index b28dd77..a0371d1 100644 --- a/tests/main/unt/heap.c +++ b/tests/main/unt/heap.c @@ -168,4 +168,62 @@ CMC_CREATE_UNIT(heap_test, true, { h_free(h); }); + + CMC_CREATE_TEST(flags, { + struct heap *h = h_new(100, cmc_max_heap, h_ftab_val); + + cmc_assert_not_equals(ptr, NULL, h); + cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + + h->flag = cmc_flags.ERROR; + + // insert + cmc_assert(h_insert(h, 10)); + cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + + h->flag = cmc_flags.ERROR; + + // remove + cmc_assert(h_remove(h, NULL)); + cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + + cmc_assert(!h_remove(h, NULL)); + cmc_assert_equals(int32_t, cmc_flags.EMPTY, h_flag(h)); + + // peek + cmc_assert(h_insert(h, 10)); + h_peek(h); + cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + cmc_assert(h_remove(h, NULL)); + h_peek(h); + cmc_assert_equals(int32_t, cmc_flags.EMPTY, h_flag(h)); + + // clear + h_clear(h); + cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + + h->flag = cmc_flags.ERROR; + + // contains + h_contains(h, 10); + cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + + h->flag = cmc_flags.ERROR; + + // copy of + struct heap *h2 = h_copy_of(h); + cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h2)); + + h->flag = cmc_flags.ERROR; + h2->flag = cmc_flags.ERROR; + + // equals + cmc_assert(h_equals(h, h2)); + cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h2)); + + h_free(h); + h_free(h2); + }); });