diff --git a/src/cmc/heap.h b/src/cmc/heap.h index 2c69594..de17b72 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -107,12 +107,6 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " \ /* Custom callback functions */ \ struct cmc_callbacks *callbacks; \ - \ - /* Function that returns an iterator to the start of the heap */ \ - struct SNAME##_iter (*it_start)(struct SNAME *); \ - \ - /* Function that returns an iterator to the end of the heap */ \ - struct SNAME##_iter (*it_end)(struct SNAME *); \ }; \ \ /* Value struct function table */ \ @@ -185,17 +179,15 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " bool PFX##_print(struct SNAME *_heap_, FILE *fptr); \ \ /* Iterator Functions */ \ - /* Iterator Allocation and Deallocation */ \ - struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \ - void PFX##_iter_free(struct SNAME##_iter *iter); \ /* Iterator Initialization */ \ - void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \ + struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ + struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ /* Iterator State */ \ - bool PFX##_iter_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_end(struct SNAME##_iter *iter); \ + bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ + bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ /* Iterator Movement */ \ - void PFX##_iter_to_start(struct SNAME##_iter *iter); \ - void PFX##_iter_to_end(struct SNAME##_iter *iter); \ + bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ + bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ bool PFX##_iter_next(struct SNAME##_iter *iter); \ bool PFX##_iter_prev(struct SNAME##_iter *iter); \ bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ @@ -213,8 +205,6 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " /* Implementation Detail Functions */ \ static void PFX##_impl_float_up(struct SNAME *_heap_, size_t index); \ static void PFX##_impl_float_down(struct SNAME *_heap_, size_t index); \ - static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_heap_); \ - static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_heap_); \ \ struct SNAME *PFX##_new(size_t capacity, enum cmc_heap_order HO, \ struct SNAME##_fval *f_val) \ @@ -250,8 +240,6 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " _heap_->f_val = f_val; \ _heap_->alloc = alloc; \ _heap_->callbacks = NULL; \ - _heap_->it_start = PFX##_impl_it_start; \ - _heap_->it_end = PFX##_impl_it_end; \ \ return _heap_; \ } \ @@ -292,8 +280,6 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " _heap_->f_val = f_val; \ _heap_->alloc = alloc; \ _heap_->callbacks = callbacks; \ - _heap_->it_start = PFX##_impl_it_start; \ - _heap_->it_end = PFX##_impl_it_end; \ \ return _heap_; \ } \ @@ -553,60 +539,71 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return true; \ } \ \ - struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \ + struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ { \ - struct SNAME##_iter *iter = \ - target->alloc->malloc(sizeof(struct SNAME##_iter)); \ + struct SNAME##_iter iter; \ \ - if (!iter) \ - return NULL; \ - \ - PFX##_iter_init(iter, target); \ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = PFX##_empty(target); \ \ return iter; \ } \ \ - void PFX##_iter_free(struct SNAME##_iter *iter) \ + struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ { \ - iter->target->alloc->free(iter); \ + struct SNAME##_iter iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = PFX##_empty(target); \ + iter.end = true; \ + \ + if (!PFX##_empty(target)) \ + { \ + iter.cursor = target->count - 1; \ + } \ + \ + return iter; \ } \ \ - void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \ - { \ - iter->target = target; \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(target); \ - } \ - \ - bool PFX##_iter_start(struct SNAME##_iter *iter) \ + bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ { \ return PFX##_empty(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_end(struct SNAME##_iter *iter) \ + bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ { \ return PFX##_empty(iter->target) || iter->end; \ } \ \ - void PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ { \ if (!PFX##_empty(iter->target)) \ { \ iter->cursor = 0; \ iter->start = true; \ iter->end = PFX##_empty(iter->target); \ + \ + return true; \ } \ + \ + return false; \ } \ \ - void PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ { \ if (!PFX##_empty(iter->target)) \ { \ iter->cursor = iter->target->count - 1; \ iter->start = PFX##_empty(iter->target); \ iter->end = true; \ + \ + return true; \ } \ + \ + return false; \ } \ \ bool PFX##_iter_next(struct SNAME##_iter *iter) \ @@ -648,7 +645,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " /* Returns true only if the iterator moved */ \ bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ { \ - if (iter->start) \ + if (iter->end) \ return false; \ \ if (iter->cursor + 1 == iter->target->count) \ @@ -787,26 +784,6 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " else \ break; \ } \ - } \ - \ - static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_heap_) \ - { \ - struct SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _heap_); \ - PFX##_iter_to_start(&iter); \ - \ - return iter; \ - } \ - \ - static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_heap_) \ - { \ - struct SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _heap_); \ - PFX##_iter_to_end(&iter); \ - \ - return iter; \ } #endif /* CMC_HEAP_H */ diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index a3cd030..445b943 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -877,7 +877,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " /* Returns true only if the iterator moved */ \ bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ { \ - if (iter->start) \ + if (iter->end) \ return false; \ \ if (iter->cursor == 0) \ diff --git a/tests/main/src/heap.c b/tests/main/src/heap.c index 1071f0d..6ebb2b7 100644 --- a/tests/main/src/heap.c +++ b/tests/main/src/heap.c @@ -10,8 +10,6 @@ struct heap struct heap_fval *f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; - struct heap_iter (*it_start)(struct heap *); - struct heap_iter (*it_end)(struct heap *); }; struct heap_fval { @@ -52,13 +50,12 @@ 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 *h_iter_new(struct heap *target); -void h_iter_free(struct heap_iter *iter); -void h_iter_init(struct heap_iter *iter, struct heap *target); -_Bool h_iter_start(struct heap_iter *iter); -_Bool h_iter_end(struct heap_iter *iter); -void h_iter_to_start(struct heap_iter *iter); -void h_iter_to_end(struct heap_iter *iter); +struct heap_iter h_iter_start(struct heap *target); +struct heap_iter h_iter_end(struct heap *target); +_Bool h_iter_at_start(struct heap_iter *iter); +_Bool h_iter_at_end(struct heap_iter *iter); +_Bool h_iter_to_start(struct heap_iter *iter); +_Bool h_iter_to_end(struct heap_iter *iter); _Bool h_iter_next(struct heap_iter *iter); _Bool h_iter_prev(struct heap_iter *iter); _Bool h_iter_advance(struct heap_iter *iter, size_t steps); @@ -68,8 +65,6 @@ size_t h_iter_value(struct heap_iter *iter); size_t h_iter_index(struct heap_iter *iter); static void h_impl_float_up(struct heap *_heap_, size_t index); static void h_impl_float_down(struct heap *_heap_, size_t index); -static struct heap_iter h_impl_it_start(struct heap *_heap_); -static struct heap_iter h_impl_it_end(struct heap *_heap_); struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val) { @@ -96,8 +91,6 @@ struct heap *h_new(size_t capacity, enum cmc_heap_order HO, _heap_->f_val = f_val; _heap_->alloc = alloc; _heap_->callbacks = ((void *)0); - _heap_->it_start = h_impl_it_start; - _heap_->it_end = h_impl_it_end; return _heap_; } struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, @@ -128,8 +121,6 @@ struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, _heap_->f_val = f_val; _heap_->alloc = alloc; _heap_->callbacks = callbacks; - _heap_->it_start = h_impl_it_start; - _heap_->it_end = h_impl_it_end; return _heap_; } void h_clear(struct heap *_heap_) @@ -325,50 +316,57 @@ _Bool h_print(struct heap *_heap_, FILE *fptr) } return 1; } -struct heap_iter *h_iter_new(struct heap *target) +struct heap_iter h_iter_start(struct heap *target) { - struct heap_iter *iter = target->alloc->malloc(sizeof(struct heap_iter)); - if (!iter) - return ((void *)0); - h_iter_init(iter, target); + struct heap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = 1; + iter.end = h_empty(target); return iter; } -void h_iter_free(struct heap_iter *iter) +struct heap_iter h_iter_end(struct heap *target) { - iter->target->alloc->free(iter); + struct heap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = h_empty(target); + iter.end = 1; + if (!h_empty(target)) + { + iter.cursor = target->count - 1; + } + return iter; } -void h_iter_init(struct heap_iter *iter, struct heap *target) -{ - iter->target = target; - iter->cursor = 0; - iter->start = 1; - iter->end = h_empty(target); -} -_Bool h_iter_start(struct heap_iter *iter) +_Bool h_iter_at_start(struct heap_iter *iter) { return h_empty(iter->target) || iter->start; } -_Bool h_iter_end(struct heap_iter *iter) +_Bool h_iter_at_end(struct heap_iter *iter) { return h_empty(iter->target) || iter->end; } -void h_iter_to_start(struct heap_iter *iter) +_Bool h_iter_to_start(struct heap_iter *iter) { if (!h_empty(iter->target)) { iter->cursor = 0; iter->start = 1; iter->end = h_empty(iter->target); + return 1; } + return 0; } -void h_iter_to_end(struct heap_iter *iter) +_Bool h_iter_to_end(struct heap_iter *iter) { if (!h_empty(iter->target)) { iter->cursor = iter->target->count - 1; iter->start = h_empty(iter->target); iter->end = 1; + return 1; } + return 0; } _Bool h_iter_next(struct heap_iter *iter) { @@ -398,7 +396,7 @@ _Bool h_iter_prev(struct heap_iter *iter) } _Bool h_iter_advance(struct heap_iter *iter, size_t steps) { - if (iter->start) + if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { @@ -495,17 +493,3 @@ static void h_impl_float_down(struct heap *_heap_, size_t index) break; } } -static struct heap_iter h_impl_it_start(struct heap *_heap_) -{ - struct heap_iter iter; - h_iter_init(&iter, _heap_); - h_iter_to_start(&iter); - return iter; -} -static struct heap_iter h_impl_it_end(struct heap *_heap_) -{ - struct heap_iter iter; - h_iter_init(&iter, _heap_); - h_iter_to_end(&iter); - return iter; -} diff --git a/tests/main/src/intervalheap.c b/tests/main/src/intervalheap.c index 28b460b..2b0ab22 100644 --- a/tests/main/src/intervalheap.c +++ b/tests/main/src/intervalheap.c @@ -578,7 +578,7 @@ _Bool ih_iter_prev(struct intervalheap_iter *iter) } _Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps) { - if (iter->start) + if (iter->end) return 0; if (iter->cursor == 0) { diff --git a/tests/main/unt/deque.c b/tests/main/unt/deque.c index 6c52a09..acb9a56 100644 --- a/tests/main/unt/deque.c +++ b/tests/main/unt/deque.c @@ -1294,6 +1294,7 @@ CMC_CREATE_UNIT(DequeIter, true, { it = d_iter_start(d); cmc_assert_equals(size_t, 0, it.index); + cmc_assert_equals(bool, false, it.end); cmc_assert_equals(size_t, d->front, it.cursor); d_free(d); @@ -1323,6 +1324,7 @@ CMC_CREATE_UNIT(DequeIter, true, { cmc_assert_equals(size_t, d->count - 1, it.index); cmc_assert_equals(size_t, d->back - 1, it.cursor); + cmc_assert_equals(bool, false, it.start); d_free(d); }); diff --git a/tests/main/unt/hashmap.c b/tests/main/unt/hashmap.c index 14f40cb..5ac006b 100644 --- a/tests/main/unt/hashmap.c +++ b/tests/main/unt/hashmap.c @@ -928,6 +928,7 @@ CMC_CREATE_UNIT(HashMapIter, true, { cmc_assert_equals(size_t, 1, it.cursor); cmc_assert_equals(size_t, 1, it.first); cmc_assert_equals(size_t, 3, it.last); + cmc_assert_equals(bool, false, it.end); hm_free(map); }); @@ -961,6 +962,7 @@ CMC_CREATE_UNIT(HashMapIter, true, { cmc_assert_equals(size_t, 3, it.cursor); cmc_assert_equals(size_t, 1, it.first); cmc_assert_equals(size_t, 3, it.last); + cmc_assert_equals(bool, false, it.start); hm_free(map); }); diff --git a/tests/main/unt/hashmultimap.c b/tests/main/unt/hashmultimap.c index 613be92..443b5c1 100644 --- a/tests/main/unt/hashmultimap.c +++ b/tests/main/unt/hashmultimap.c @@ -520,6 +520,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { cmc_assert_equals(size_t, 1, it.cursor); cmc_assert_equals(size_t, 1, it.first); cmc_assert_equals(size_t, 3, it.last); + cmc_assert_equals(bool, false, it.end); hmm_free(map); }); @@ -554,6 +555,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { cmc_assert_equals(size_t, 3, it.cursor); cmc_assert_equals(size_t, 1, it.first); cmc_assert_equals(size_t, 3, it.last); + cmc_assert_equals(bool, false, it.start); hmm_free(map); }); diff --git a/tests/main/unt/hashmultiset.c b/tests/main/unt/hashmultiset.c index 6b5b0ce..0bc59fc 100644 --- a/tests/main/unt/hashmultiset.c +++ b/tests/main/unt/hashmultiset.c @@ -463,6 +463,7 @@ CMC_CREATE_UNIT(HashMultiSetIter, true, { cmc_assert_equals(size_t, 1, it.cursor); cmc_assert_equals(size_t, 1, it.first); cmc_assert_equals(size_t, 3, it.last); + cmc_assert_equals(bool, false, it.end); hms_free(set); }); @@ -496,6 +497,7 @@ CMC_CREATE_UNIT(HashMultiSetIter, true, { cmc_assert_equals(size_t, 3, it.cursor); cmc_assert_equals(size_t, 1, it.first); cmc_assert_equals(size_t, 3, it.last); + cmc_assert_equals(bool, false, it.start); hms_free(set); }); diff --git a/tests/main/unt/hashset.c b/tests/main/unt/hashset.c index 7cacd24..2e3560e 100644 --- a/tests/main/unt/hashset.c +++ b/tests/main/unt/hashset.c @@ -663,6 +663,7 @@ CMC_CREATE_UNIT(HashSetIter, true, { cmc_assert_equals(size_t, 1, it.cursor); cmc_assert_equals(size_t, 1, it.first); cmc_assert_equals(size_t, 3, it.last); + cmc_assert_equals(bool, false, it.end); hs_free(set); }); @@ -696,6 +697,7 @@ CMC_CREATE_UNIT(HashSetIter, true, { cmc_assert_equals(size_t, 3, it.cursor); cmc_assert_equals(size_t, 1, it.first); cmc_assert_equals(size_t, 3, it.last); + cmc_assert_equals(bool, false, it.start); hs_free(set); }); diff --git a/tests/main/unt/heap.c b/tests/main/unt/heap.c index b8a11d0..2a3fe60 100644 --- a/tests/main/unt/heap.c +++ b/tests/main/unt/heap.c @@ -292,7 +292,427 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_UNIT(HeapIter, true, { + CMC_CREATE_TEST(PFX##_iter_start(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_start(h); + + cmc_assert_equals(ptr, h, it.target); + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, true, it.start); + cmc_assert_equals(bool, true, it.end); + + cmc_assert(h_iter_at_start(&it)); + cmc_assert(h_iter_at_end(&it)); + + cmc_assert(h_insert(h, 1)); + cmc_assert(h_insert(h, 2)); + + it = h_iter_start(h); + + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, false, it.end); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_end(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_end(h); + + cmc_assert_equals(ptr, h, it.target); + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, true, it.start); + cmc_assert_equals(bool, true, it.end); + + cmc_assert(h_iter_at_start(&it)); + cmc_assert(h_iter_at_end(&it)); + + cmc_assert(h_insert(h, 1)); + cmc_assert(h_insert(h, 2)); + cmc_assert(h_insert(h, 3)); + + it = h_iter_end(h); + + cmc_assert_equals(size_t, h->count - 1, it.cursor); + cmc_assert_equals(bool, false, it.start); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_at_start(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_start(h); + + // Empty checks + cmc_assert(h_iter_at_start(&it)); + it = h_iter_end(h); + cmc_assert(h_iter_at_start(&it)); + + // Non-empty check + cmc_assert(h_insert(h, 1)); + it = h_iter_end(h); + cmc_assert(!h_iter_at_start(&it)); + it = h_iter_start(h); + cmc_assert(h_iter_at_start(&it)); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_at_end(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_start(h); + + // Empty check + cmc_assert(h_iter_at_end(&it)); + it = h_iter_end(h); + cmc_assert(h_iter_at_end(&it)); + + // Non-empty check + cmc_assert(h_insert(h, 1)); + it = h_iter_end(h); + cmc_assert(h_iter_at_end(&it)); + it = h_iter_start(h); + cmc_assert(!h_iter_at_end(&it)); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_to_start(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_start(h); + + cmc_assert(!h_iter_to_start(&it)); + + for (size_t i = 1; i <= 100; i++) + { + if (i % 2 == 0) + h_insert(h, i); + else + h_insert(h, i); + } + + cmc_assert_equals(size_t, 100, h->count); + + it = h_iter_end(h); + cmc_assert(!h_iter_at_start(&it)); + cmc_assert(h_iter_at_end(&it)); + cmc_assert_equals(size_t, 99, it.cursor); + + cmc_assert(h_iter_to_start(&it)); + cmc_assert(h_iter_at_start(&it)); + cmc_assert(!h_iter_at_end(&it)); + cmc_assert_equals(size_t, 0, it.cursor); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_to_end(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_end(h); + + cmc_assert(!h_iter_to_end(&it)); + + for (size_t i = 1; i <= 100; i++) + { + if (i % 2 == 0) + h_insert(h, i); + else + h_insert(h, i); + } + + it = h_iter_start(h); + cmc_assert(h_iter_at_start(&it)); + cmc_assert(!h_iter_at_end(&it)); + + cmc_assert(h_iter_to_end(&it)); + cmc_assert(!h_iter_at_start(&it)); + cmc_assert(h_iter_at_end(&it)); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_next(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_start(h); + + cmc_assert(!h_iter_next(&it)); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + h_insert(h, i); + else + h_insert(h, i); + } + + size_t sum = 0; + for (it = h_iter_start(h); !h_iter_at_end(&it); h_iter_next(&it)) + { + sum += h_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + h_iter_to_start(&it); + do + { + sum += h_iter_value(&it); + } while (h_iter_next(&it)); + + cmc_assert_equals(size_t, 500500, sum); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_prev(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_end(h); + + cmc_assert(!h_iter_prev(&it)); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + h_insert(h, i); + else + h_insert(h, i); + } + + size_t sum = 0; + for (it = h_iter_end(h); !h_iter_at_start(&it); h_iter_prev(&it)) + { + sum += h_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + h_iter_to_end(&it); + do + { + sum += h_iter_value(&it); + } while (h_iter_prev(&it)); + + cmc_assert_equals(size_t, 500500, sum); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_advance(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_start(h); + + cmc_assert(!h_iter_advance(&it, 1)); + + for (size_t i = 1; i <= 1000; i++) + h_insert(h, i); + + it = h_iter_start(h); + + cmc_assert(!h_iter_advance(&it, 0)); + cmc_assert(!h_iter_advance(&it, h->count)); + + size_t sum = 0; + for (it = h_iter_start(h);;) + { + sum += h_iter_value(&it); + + if (!h_iter_advance(&it, 2)) + break; + + cmc_assert_equals(size_t, 0, h_iter_index(&it) % 2); + } + + cmc_assert(h_iter_to_start(&it)); + cmc_assert(h_iter_next(&it)); + + cmc_assert_equals(size_t, 1, h_iter_index(&it)); + + for (;;) + { + sum += h_iter_value(&it); + + if (!h_iter_advance(&it, 2)) + break; + + cmc_assert_equals(size_t, 1, h_iter_index(&it) % 2); + } + + cmc_assert_equals(size_t, 500500, sum); + + h_iter_to_start(&it); + cmc_assert(h_iter_advance(&it, h->count - 1)); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_rewind(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_end(h); + + cmc_assert(!h_iter_rewind(&it, 1)); + + for (size_t i = 0; i <= 1000; i++) + h_insert(h, i); + + it = h_iter_end(h); + + cmc_assert(!h_iter_rewind(&it, 0)); + cmc_assert(!h_iter_rewind(&it, h->count)); + + size_t sum = 0; + for (it = h_iter_end(h);;) + { + sum += h_iter_value(&it); + + if (!h_iter_rewind(&it, 2)) + break; + + cmc_assert_equals(size_t, 0, h_iter_index(&it) % 2); + } + + cmc_assert(h_iter_to_end(&it)); + cmc_assert(h_iter_prev(&it)); + + cmc_assert_equals(size_t, h->count - 2, h_iter_index(&it)); + + for (;;) + { + sum += h_iter_value(&it); + + if (!h_iter_rewind(&it, 2)) + break; + + cmc_assert_equals(size_t, 1, h_iter_index(&it) % 2); + } + + cmc_assert_equals(size_t, 500500, sum); + + h_iter_to_end(&it); + cmc_assert(h_iter_rewind(&it, h->count - 1)); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_go_to(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_end(h); + cmc_assert(!h_iter_go_to(&it, 0)); + + it = h_iter_start(h); + cmc_assert(!h_iter_go_to(&it, 0)); + + for (size_t i = 0; i <= 1000; i++) + h_insert(h, i); + + cmc_assert_equals(size_t, 1001, h->count); + + it = h_iter_start(h); + + size_t sum = 0; + for (size_t i = 0; i < 1001; i++) + { + h_iter_go_to(&it, i); + + sum += h_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + for (size_t i = 1001; i > 0; i--) + { + cmc_assert(h_iter_go_to(&it, i - 1)); + + sum += h_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_value(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + struct heap_iter it = h_iter_end(h); + + cmc_assert_equals(size_t, (size_t){ 0 }, h_iter_value(&it)); + + cmc_assert(h_insert(h, 1)); + cmc_assert(h_insert(h, 3)); + cmc_assert(h_insert(h, 2)); + + it = h_iter_start(h); + + cmc_assert_equals(size_t, 3, h_iter_value(&it)); + + h_free(h); + }); + + CMC_CREATE_TEST(PFX##_iter_index(), { + struct heap *h = h_new(100, cmc_max_heap, h_fval); + + cmc_assert_not_equals(ptr, NULL, h); + + for (size_t i = 0; i <= 1000; i++) + h_insert(h, i); + + struct heap_iter it = h_iter_start(h); + + for (size_t i = 0; i < 1001; i++) + { + cmc_assert_equals(size_t, i, h_iter_index(&it)); + h_iter_next(&it); + } + + it = h_iter_end(h); + for (size_t i = 1001; i > 0; i--) + { + cmc_assert_equals(size_t, i - 1, h_iter_index(&it)); + h_iter_prev(&it); + } + + h_free(h); + }); }); #ifdef CMC_TEST_MAIN @@ -300,10 +720,12 @@ int main(void) { int result = Heap() + HeapIter(); - printf(" +---------------------------------------------------------------+"); + printf( + " +---------------------------------------------------------------+"); printf("\n"); printf(" | Heap Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); + printf( + " +---------------------------------------------------------------+"); printf("\n\n\n"); return result;