From 2f59d5fcafee076de030f39cf84dfa981377cbbf Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sat, 9 May 2020 07:58:03 -0300 Subject: [PATCH] Updatating intervalheap iterator and other smaller things --- src/cmc/heap.h | 6 +- src/cmc/intervalheap.h | 100 ++++---- tests/main/main.c | 8 + tests/main/src/heap.c | 4 +- tests/main/src/intervalheap.c | 83 +++---- tests/main/unt/intervalheap.c | 422 ++++++++++++++++++++++++++++++++++ 6 files changed, 507 insertions(+), 116 deletions(-) diff --git a/src/cmc/heap.h b/src/cmc/heap.h index de17b72..bb5caa3 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -561,9 +561,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " iter.end = true; \ \ if (!PFX##_empty(target)) \ - { \ iter.cursor = target->count - 1; \ - } \ \ return iter; \ } \ @@ -657,11 +655,11 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " if (steps == 0 || iter->cursor + steps >= iter->target->count) \ return false; \ \ - iter->start = PFX##_empty(iter->target); \ - \ if (iter->end) \ return false; \ \ + iter->start = PFX##_empty(iter->target); \ + \ iter->cursor += steps; \ \ return true; \ diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index 445b943..2609b19 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -165,17 +165,15 @@ static const char *cmc_string_fmt_intervalheap = "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); \ @@ -195,8 +193,6 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " static void PFX##_impl_float_up_min(struct SNAME *_heap_); \ static void PFX##_impl_float_down_max(struct SNAME *_heap_); \ static void PFX##_impl_float_down_min(struct SNAME *_heap_); \ - 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, struct SNAME##_fval *f_val) \ { \ @@ -230,8 +226,6 @@ static const char *cmc_string_fmt_intervalheap = "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_; \ } \ @@ -271,8 +265,6 @@ static const char *cmc_string_fmt_intervalheap = "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_; \ } \ @@ -730,8 +722,6 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " result->f_val = _heap_->f_val; \ result->alloc = _heap_->alloc; \ result->callbacks = _heap_->callbacks; \ - result->it_start = PFX##_impl_it_start; \ - result->it_end = PFX##_impl_it_end; \ \ _heap_->flag = cmc_flags.OK; \ \ @@ -782,60 +772,69 @@ static const char *cmc_string_fmt_intervalheap = "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) \ @@ -880,15 +879,18 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " if (iter->end) \ return false; \ \ - if (iter->cursor == 0) \ + if (iter->cursor + 1 == iter->target->count) \ { \ - iter->start = true; \ + iter->end = true; \ return false; \ } \ \ if (steps == 0 || iter->cursor + steps >= iter->target->count) \ return false; \ \ + if (iter->end) \ + return false; \ + \ iter->start = PFX##_empty(iter->target); \ \ iter->cursor += steps; \ @@ -1173,26 +1175,6 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " index = child; \ curr_node = child_node; \ } \ - } \ - \ - 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_INTERVALHEAP_H */ diff --git a/tests/main/main.c b/tests/main/main.c index 06191c2..d6c93fd 100644 --- a/tests/main/main.c +++ b/tests/main/main.c @@ -63,13 +63,21 @@ int main(void) cmc_run(Heap, units, tests); cmc_run(HeapIter, units, tests); cmc_run(IntervalHeap, units, tests); + cmc_run(IntervalHeapIter, units, tests); cmc_run(LinkedList, units, tests); + cmc_run(LinkedListIter, units, tests); cmc_run(List, units, tests); + cmc_run(ListIter, units, tests); cmc_run(Queue, units, tests); + cmc_run(QueueIter, units, tests); cmc_run(SortedList, units, tests); + cmc_run(SortedListIter, units, tests); cmc_run(Stack, units, tests); + cmc_run(StackIter, units, tests); cmc_run(TreeMap, units, tests); + cmc_run(TreeMapIter, units, tests); cmc_run(TreeSet, units, tests); + cmc_run(TreeSetIter, units, tests); cmc_timer_stop(timer); diff --git a/tests/main/src/heap.c b/tests/main/src/heap.c index 6ebb2b7..2ff27d2 100644 --- a/tests/main/src/heap.c +++ b/tests/main/src/heap.c @@ -333,9 +333,7 @@ struct heap_iter h_iter_end(struct heap *target) iter.start = h_empty(target); iter.end = 1; if (!h_empty(target)) - { iter.cursor = target->count - 1; - } return iter; } _Bool h_iter_at_start(struct heap_iter *iter) @@ -405,9 +403,9 @@ _Bool h_iter_advance(struct heap_iter *iter, size_t steps) } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; - iter->start = h_empty(iter->target); if (iter->end) return 0; + iter->start = h_empty(iter->target); iter->cursor += steps; return 1; } diff --git a/tests/main/src/intervalheap.c b/tests/main/src/intervalheap.c index 2b0ab22..d15e63f 100644 --- a/tests/main/src/intervalheap.c +++ b/tests/main/src/intervalheap.c @@ -56,13 +56,12 @@ struct intervalheap *ih_copy_of(struct intervalheap *_set_); _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 *ih_iter_new(struct intervalheap *target); -void ih_iter_free(struct intervalheap_iter *iter); -void ih_iter_init(struct intervalheap_iter *iter, struct intervalheap *target); -_Bool ih_iter_start(struct intervalheap_iter *iter); -_Bool ih_iter_end(struct intervalheap_iter *iter); -void ih_iter_to_start(struct intervalheap_iter *iter); -void ih_iter_to_end(struct intervalheap_iter *iter); +struct intervalheap_iter ih_iter_start(struct intervalheap *target); +struct intervalheap_iter ih_iter_end(struct intervalheap *target); +_Bool ih_iter_at_start(struct intervalheap_iter *iter); +_Bool ih_iter_at_end(struct intervalheap_iter *iter); +_Bool ih_iter_to_start(struct intervalheap_iter *iter); +_Bool ih_iter_to_end(struct intervalheap_iter *iter); _Bool ih_iter_next(struct intervalheap_iter *iter); _Bool ih_iter_prev(struct intervalheap_iter *iter); _Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps); @@ -74,8 +73,6 @@ 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_); -static struct intervalheap_iter ih_impl_it_start(struct intervalheap *_heap_); -static struct intervalheap_iter ih_impl_it_end(struct intervalheap *_heap_); struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val) { struct cmc_alloc_node *alloc = &cmc_alloc_node_default; @@ -100,8 +97,6 @@ struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val) _heap_->f_val = f_val; _heap_->alloc = alloc; _heap_->callbacks = ((void *)0); - _heap_->it_start = ih_impl_it_start; - _heap_->it_end = ih_impl_it_end; return _heap_; } struct intervalheap *ih_new_custom(size_t capacity, @@ -132,8 +127,6 @@ struct intervalheap *ih_new_custom(size_t capacity, _heap_->f_val = f_val; _heap_->alloc = alloc; _heap_->callbacks = callbacks; - _heap_->it_start = ih_impl_it_start; - _heap_->it_end = ih_impl_it_end; return _heap_; } void ih_clear(struct intervalheap *_heap_) @@ -465,8 +458,6 @@ struct intervalheap *ih_copy_of(struct intervalheap *_heap_) result->f_val = _heap_->f_val; result->alloc = _heap_->alloc; result->callbacks = _heap_->callbacks; - result->it_start = ih_impl_it_start; - result->it_end = ih_impl_it_end; _heap_->flag = cmc_flags.OK; return result; } @@ -504,51 +495,55 @@ _Bool ih_print(struct intervalheap *_heap_, FILE *fptr) } return 1; } -struct intervalheap_iter *ih_iter_new(struct intervalheap *target) +struct intervalheap_iter ih_iter_start(struct intervalheap *target) { - struct intervalheap_iter *iter = - target->alloc->malloc(sizeof(struct intervalheap_iter)); - if (!iter) - return ((void *)0); - ih_iter_init(iter, target); + struct intervalheap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = 1; + iter.end = ih_empty(target); return iter; } -void ih_iter_free(struct intervalheap_iter *iter) +struct intervalheap_iter ih_iter_end(struct intervalheap *target) { - iter->target->alloc->free(iter); + 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; } -void ih_iter_init(struct intervalheap_iter *iter, struct intervalheap *target) -{ - iter->target = target; - iter->cursor = 0; - iter->start = 1; - iter->end = ih_empty(target); -} -_Bool ih_iter_start(struct intervalheap_iter *iter) +_Bool ih_iter_at_start(struct intervalheap_iter *iter) { return ih_empty(iter->target) || iter->start; } -_Bool ih_iter_end(struct intervalheap_iter *iter) +_Bool ih_iter_at_end(struct intervalheap_iter *iter) { return ih_empty(iter->target) || iter->end; } -void ih_iter_to_start(struct intervalheap_iter *iter) +_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; } -void ih_iter_to_end(struct intervalheap_iter *iter) +_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) { @@ -580,13 +575,15 @@ _Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps) { if (iter->end) return 0; - if (iter->cursor == 0) + if (iter->cursor + 1 == iter->target->count) { - iter->start = 1; + 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; @@ -761,17 +758,3 @@ static void ih_impl_float_down_min(struct intervalheap *_heap_) curr_node = child_node; } } -static struct intervalheap_iter ih_impl_it_start(struct intervalheap *_heap_) -{ - struct intervalheap_iter iter; - ih_iter_init(&iter, _heap_); - ih_iter_to_start(&iter); - return iter; -} -static struct intervalheap_iter ih_impl_it_end(struct intervalheap *_heap_) -{ - struct intervalheap_iter iter; - ih_iter_init(&iter, _heap_); - ih_iter_to_end(&iter); - return iter; -} diff --git a/tests/main/unt/intervalheap.c b/tests/main/unt/intervalheap.c index bda59b7..0eed15a 100644 --- a/tests/main/unt/intervalheap.c +++ b/tests/main/unt/intervalheap.c @@ -614,7 +614,429 @@ CMC_CREATE_UNIT(IntervalHeap, true, { }); CMC_CREATE_UNIT(IntervalHeapIter, true, { + CMC_CREATE_TEST(PFX##_iter_start(), { + struct intervalheap *ih = ih_new(100, ih_fval); + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_start(ih); + + cmc_assert_equals(ptr, ih, 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(ih_iter_at_start(&it)); + cmc_assert(ih_iter_at_end(&it)); + + cmc_assert(ih_insert(ih, 1)); + cmc_assert(ih_insert(ih, 2)); + + it = ih_iter_start(ih); + + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, false, it.end); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_end(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_end(ih); + + cmc_assert_equals(ptr, ih, 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(ih_iter_at_start(&it)); + cmc_assert(ih_iter_at_end(&it)); + + cmc_assert(ih_insert(ih, 1)); + cmc_assert(ih_insert(ih, 2)); + cmc_assert(ih_insert(ih, 3)); + + it = ih_iter_end(ih); + + cmc_assert_equals(size_t, ih->count - 1, it.cursor); + cmc_assert_equals(bool, false, it.start); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_at_start(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_start(ih); + + // Empty checks + cmc_assert(ih_iter_at_start(&it)); + it = ih_iter_end(ih); + cmc_assert(ih_iter_at_start(&it)); + + // Non-empty check + cmc_assert(ih_insert(ih, 1)); + it = ih_iter_end(ih); + cmc_assert(!ih_iter_at_start(&it)); + it = ih_iter_start(ih); + cmc_assert(ih_iter_at_start(&it)); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_at_end(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_start(ih); + + // Empty check + cmc_assert(ih_iter_at_end(&it)); + it = ih_iter_end(ih); + cmc_assert(ih_iter_at_end(&it)); + + // Non-empty check + cmc_assert(ih_insert(ih, 1)); + it = ih_iter_end(ih); + cmc_assert(ih_iter_at_end(&it)); + it = ih_iter_start(ih); + cmc_assert(!ih_iter_at_end(&it)); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_to_start(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_start(ih); + + cmc_assert(!ih_iter_to_start(&it)); + + for (size_t i = 1; i <= 100; i++) + { + if (i % 2 == 0) + ih_insert(ih, i); + else + ih_insert(ih, i); + } + + cmc_assert_equals(size_t, 100, ih->count); + + it = ih_iter_end(ih); + cmc_assert(!ih_iter_at_start(&it)); + cmc_assert(ih_iter_at_end(&it)); + cmc_assert_equals(size_t, 99, it.cursor); + + cmc_assert(ih_iter_to_start(&it)); + cmc_assert(ih_iter_at_start(&it)); + cmc_assert(!ih_iter_at_end(&it)); + cmc_assert_equals(size_t, 0, it.cursor); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_to_end(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_end(ih); + + cmc_assert(!ih_iter_to_end(&it)); + + for (size_t i = 1; i <= 100; i++) + { + if (i % 2 == 0) + ih_insert(ih, i); + else + ih_insert(ih, i); + } + + it = ih_iter_start(ih); + cmc_assert(ih_iter_at_start(&it)); + cmc_assert(!ih_iter_at_end(&it)); + + cmc_assert(ih_iter_to_end(&it)); + cmc_assert(!ih_iter_at_start(&it)); + cmc_assert(ih_iter_at_end(&it)); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_next(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_start(ih); + + cmc_assert(!ih_iter_next(&it)); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + ih_insert(ih, i); + else + ih_insert(ih, i); + } + + size_t sum = 0; + for (it = ih_iter_start(ih); !ih_iter_at_end(&it); ih_iter_next(&it)) + { + sum += ih_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + ih_iter_to_start(&it); + do + { + sum += ih_iter_value(&it); + } while (ih_iter_next(&it)); + + cmc_assert_equals(size_t, 500500, sum); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_prev(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_end(ih); + + cmc_assert(!ih_iter_prev(&it)); + + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + ih_insert(ih, i); + else + ih_insert(ih, i); + } + + size_t sum = 0; + for (it = ih_iter_end(ih); !ih_iter_at_start(&it); ih_iter_prev(&it)) + { + sum += ih_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + ih_iter_to_end(&it); + do + { + sum += ih_iter_value(&it); + } while (ih_iter_prev(&it)); + + cmc_assert_equals(size_t, 500500, sum); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_advance(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_start(ih); + + cmc_assert(!ih_iter_advance(&it, 1)); + + for (size_t i = 1; i <= 1000; i++) + ih_insert(ih, i); + + it = ih_iter_start(ih); + + cmc_assert(!ih_iter_advance(&it, 0)); + cmc_assert(!ih_iter_advance(&it, ih->count)); + + size_t sum = 0; + for (it = ih_iter_start(ih);;) + { + sum += ih_iter_value(&it); + + if (!ih_iter_advance(&it, 2)) + break; + + cmc_assert_equals(size_t, 0, ih_iter_index(&it) % 2); + } + + cmc_assert(ih_iter_to_start(&it)); + cmc_assert(ih_iter_next(&it)); + + cmc_assert_equals(size_t, 1, ih_iter_index(&it)); + + for (;;) + { + sum += ih_iter_value(&it); + + if (!ih_iter_advance(&it, 2)) + break; + + cmc_assert_equals(size_t, 1, ih_iter_index(&it) % 2); + } + + cmc_assert_equals(size_t, 500500, sum); + + ih_iter_to_start(&it); + cmc_assert(ih_iter_advance(&it, ih->count - 1)); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_rewind(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_end(ih); + + cmc_assert(!ih_iter_rewind(&it, 1)); + + for (size_t i = 0; i <= 1000; i++) + ih_insert(ih, i); + + it = ih_iter_end(ih); + + cmc_assert(!ih_iter_rewind(&it, 0)); + cmc_assert(!ih_iter_rewind(&it, ih->count)); + + size_t sum = 0; + for (it = ih_iter_end(ih);;) + { + sum += ih_iter_value(&it); + + if (!ih_iter_rewind(&it, 2)) + break; + + cmc_assert_equals(size_t, 0, ih_iter_index(&it) % 2); + } + + cmc_assert(ih_iter_to_end(&it)); + cmc_assert(ih_iter_prev(&it)); + + cmc_assert_equals(size_t, ih->count - 2, ih_iter_index(&it)); + + for (;;) + { + sum += ih_iter_value(&it); + + if (!ih_iter_rewind(&it, 2)) + break; + + cmc_assert_equals(size_t, 1, ih_iter_index(&it) % 2); + } + + cmc_assert_equals(size_t, 500500, sum); + + ih_iter_to_end(&it); + cmc_assert(ih_iter_rewind(&it, ih->count - 1)); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_go_to(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_end(ih); + cmc_assert(!ih_iter_go_to(&it, 0)); + + it = ih_iter_start(ih); + cmc_assert(!ih_iter_go_to(&it, 0)); + + for (size_t i = 0; i <= 1000; i++) + ih_insert(ih, i); + + cmc_assert_equals(size_t, 1001, ih->count); + + it = ih_iter_start(ih); + + size_t sum = 0; + for (size_t i = 0; i < 1001; i++) + { + ih_iter_go_to(&it, i); + + sum += ih_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + for (size_t i = 1001; i > 0; i--) + { + cmc_assert(ih_iter_go_to(&it, i - 1)); + + sum += ih_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_value(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + struct intervalheap_iter it = ih_iter_end(ih); + + cmc_assert_equals(size_t, (size_t){ 0 }, ih_iter_value(&it)); + + cmc_assert(ih_insert(ih, 1)); + cmc_assert(ih_insert(ih, 3)); + cmc_assert(ih_insert(ih, 2)); + + it = ih_iter_start(ih); + + cmc_assert_equals(size_t, 1, ih_iter_value(&it)); + cmc_assert(ih_iter_next(&it)); + cmc_assert_equals(size_t, 3, ih_iter_value(&it)); + + ih_free(ih); + }); + + CMC_CREATE_TEST(PFX##_iter_index(), { + struct intervalheap *ih = ih_new(100, ih_fval); + + cmc_assert_not_equals(ptr, NULL, ih); + + for (size_t i = 0; i <= 1000; i++) + ih_insert(ih, i); + + struct intervalheap_iter it = ih_iter_start(ih); + + for (size_t i = 0; i < 1001; i++) + { + cmc_assert_equals(size_t, i, ih_iter_index(&it)); + ih_iter_next(&it); + } + + it = ih_iter_end(ih); + for (size_t i = 1001; i > 0; i--) + { + cmc_assert_equals(size_t, i - 1, ih_iter_index(&it)); + ih_iter_prev(&it); + } + + ih_free(ih); + }); }); #ifdef CMC_TEST_MAIN