From 51d7a584243d57a669de4be652d5ef0d439c9a1a Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 12 May 2020 16:02:42 -0300 Subject: [PATCH] Updating stack iterators --- src/cmc/stack.h | 108 +++----- tests/main/src/stack.c | 88 +++--- tests/main/unt/stack.c | 589 ++++++++++++++++++++++++----------------- 3 files changed, 419 insertions(+), 366 deletions(-) diff --git a/src/cmc/stack.h b/src/cmc/stack.h index a25121e..1efa5f0 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -85,12 +85,6 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " \ /* Custom callback functions */ \ struct cmc_callbacks *callbacks; \ - \ - /* Function that returns an iterator to the start of the stack */ \ - struct SNAME##_iter (*it_start)(struct SNAME *); \ - \ - /* Function that returns an iterator to the end of the stack */ \ - struct SNAME##_iter (*it_end)(struct SNAME *); \ }; \ \ /* Value struct function table */ \ @@ -162,17 +156,15 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " bool PFX##_print(struct SNAME *_stack_, 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); \ @@ -189,8 +181,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " #define CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ - static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_stack_); \ - static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_stack_); \ + /* None */ \ \ struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \ { \ @@ -221,8 +212,6 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " _stack_->f_val = f_val; \ _stack_->alloc = alloc; \ _stack_->callbacks = NULL; \ - _stack_->it_start = PFX##_impl_it_start; \ - _stack_->it_end = PFX##_impl_it_end; \ \ return _stack_; \ } \ @@ -258,8 +247,6 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " _stack_->f_val = f_val; \ _stack_->alloc = alloc; \ _stack_->callbacks = callbacks; \ - _stack_->it_start = PFX##_impl_it_start; \ - _stack_->it_end = PFX##_impl_it_end; \ \ return _stack_; \ } \ @@ -505,60 +492,69 @@ static const char *cmc_string_fmt_stack = "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; \ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = PFX##_empty(target); \ \ - PFX##_iter_init(iter, target); \ + if (!PFX##_empty(target)) \ + iter.cursor = target->count - 1; \ \ 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; \ + \ + return iter; \ } \ \ - void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \ - { \ - iter->target = target; \ - iter->cursor = PFX##_empty(target) ? 0 : iter->target->count - 1; \ - 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 = iter->target->count - 1; \ 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 = 0; \ iter->start = PFX##_empty(iter->target); \ iter->end = true; \ + \ + return true; \ } \ + \ + return false; \ } \ \ bool PFX##_iter_next(struct SNAME##_iter *iter) \ @@ -584,7 +580,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " if (iter->start) \ return false; \ \ - if (iter->cursor + 1 == PFX##_count(iter->target)) \ + if (iter->cursor + 1 == iter->target->count) \ { \ iter->start = true; \ return false; \ @@ -625,13 +621,13 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " if (iter->start) \ return false; \ \ - if (iter->cursor + 1 == PFX##_count(iter->target)) \ + if (iter->cursor + 1 == iter->target->count) \ { \ iter->start = 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->end = PFX##_empty(iter->target); \ @@ -645,13 +641,13 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " /* 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) \ - return PFX##_iter_rewind(iter, iter->cursor - index); \ + return PFX##_iter_advance(iter, iter->cursor - index); \ else if (iter->cursor < index) \ - return PFX##_iter_advance(iter, index - iter->cursor); \ + return PFX##_iter_rewind(iter, index - iter->cursor); \ \ return true; \ } \ @@ -678,26 +674,6 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return 0; \ \ return iter->target->count - 1 - iter->cursor; \ - } \ - \ - static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_stack_) \ - { \ - struct SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _stack_); \ - PFX##_iter_to_start(&iter); \ - \ - return iter; \ - } \ - \ - static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_stack_) \ - { \ - struct SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _stack_); \ - PFX##_iter_to_end(&iter); \ - \ - return iter; \ } #endif /* CMC_STACK_H */ diff --git a/tests/main/src/stack.c b/tests/main/src/stack.c index b2aa78f..63ec793 100644 --- a/tests/main/src/stack.c +++ b/tests/main/src/stack.c @@ -9,8 +9,6 @@ struct stack struct stack_fval *f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; - struct stack_iter (*it_start)(struct stack *); - struct stack_iter (*it_end)(struct stack *); }; struct stack_fval { @@ -50,13 +48,12 @@ 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 *s_iter_new(struct stack *target); -void s_iter_free(struct stack_iter *iter); -void s_iter_init(struct stack_iter *iter, struct stack *target); -_Bool s_iter_start(struct stack_iter *iter); -_Bool s_iter_end(struct stack_iter *iter); -void s_iter_to_start(struct stack_iter *iter); -void s_iter_to_end(struct stack_iter *iter); +struct stack_iter s_iter_start(struct stack *target); +struct stack_iter s_iter_end(struct stack *target); +_Bool s_iter_at_start(struct stack_iter *iter); +_Bool s_iter_at_end(struct stack_iter *iter); +_Bool s_iter_to_start(struct stack_iter *iter); +_Bool s_iter_to_end(struct stack_iter *iter); _Bool s_iter_next(struct stack_iter *iter); _Bool s_iter_prev(struct stack_iter *iter); _Bool s_iter_advance(struct stack_iter *iter, size_t steps); @@ -65,8 +62,6 @@ _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); -static struct stack_iter s_impl_it_start(struct stack *_stack_); -static struct stack_iter s_impl_it_end(struct stack *_stack_); struct stack *s_new(size_t capacity, struct stack_fval *f_val) { struct cmc_alloc_node *alloc = &cmc_alloc_node_default; @@ -89,8 +84,6 @@ struct stack *s_new(size_t capacity, struct stack_fval *f_val) _stack_->f_val = f_val; _stack_->alloc = alloc; _stack_->callbacks = ((void *)0); - _stack_->it_start = s_impl_it_start; - _stack_->it_end = s_impl_it_end; return _stack_; } struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, @@ -118,8 +111,6 @@ struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, _stack_->f_val = f_val; _stack_->alloc = alloc; _stack_->callbacks = callbacks; - _stack_->it_start = s_impl_it_start; - _stack_->it_end = s_impl_it_end; return _stack_; } void s_clear(struct stack *_stack_) @@ -303,50 +294,55 @@ _Bool s_print(struct stack *_stack_, FILE *fptr) } return 1; } -struct stack_iter *s_iter_new(struct stack *target) +struct stack_iter s_iter_start(struct stack *target) { - struct stack_iter *iter = target->alloc->malloc(sizeof(struct stack_iter)); - if (!iter) - return ((void *)0); - s_iter_init(iter, target); + struct stack_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = 1; + iter.end = s_empty(target); + if (!s_empty(target)) + iter.cursor = target->count - 1; return iter; } -void s_iter_free(struct stack_iter *iter) +struct stack_iter s_iter_end(struct stack *target) { - iter->target->alloc->free(iter); + struct stack_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = s_empty(target); + iter.end = 1; + return iter; } -void s_iter_init(struct stack_iter *iter, struct stack *target) -{ - iter->target = target; - iter->cursor = s_empty(target) ? 0 : iter->target->count - 1; - iter->start = 1; - iter->end = s_empty(target); -} -_Bool s_iter_start(struct stack_iter *iter) +_Bool s_iter_at_start(struct stack_iter *iter) { return s_empty(iter->target) || iter->start; } -_Bool s_iter_end(struct stack_iter *iter) +_Bool s_iter_at_end(struct stack_iter *iter) { return s_empty(iter->target) || iter->end; } -void s_iter_to_start(struct stack_iter *iter) +_Bool s_iter_to_start(struct stack_iter *iter) { if (!s_empty(iter->target)) { iter->cursor = iter->target->count - 1; iter->start = 1; iter->end = s_empty(iter->target); + return 1; } + return 0; } -void s_iter_to_end(struct stack_iter *iter) +_Bool s_iter_to_end(struct stack_iter *iter) { if (!s_empty(iter->target)) { iter->cursor = 0; iter->start = s_empty(iter->target); iter->end = 1; + return 1; } + return 0; } _Bool s_iter_next(struct stack_iter *iter) { @@ -365,7 +361,7 @@ _Bool s_iter_prev(struct stack_iter *iter) { if (iter->start) return 0; - if (iter->cursor + 1 == s_count(iter->target)) + if (iter->cursor + 1 == iter->target->count) { iter->start = 1; return 0; @@ -393,12 +389,12 @@ _Bool s_iter_rewind(struct stack_iter *iter, size_t steps) { if (iter->start) return 0; - if (iter->cursor + 1 == s_count(iter->target)) + if (iter->cursor + 1 == iter->target->count) { iter->start = 1; return 0; } - if (steps == 0 || iter->cursor + steps >= s_count(iter->target)) + if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; iter->end = s_empty(iter->target); iter->cursor += steps; @@ -406,12 +402,12 @@ _Bool s_iter_rewind(struct stack_iter *iter, size_t steps) } _Bool s_iter_go_to(struct stack_iter *iter, size_t index) { - if (index >= s_count(iter->target)) + if (index >= iter->target->count) return 0; if (iter->cursor > index) - return s_iter_rewind(iter, iter->cursor - index); + return s_iter_advance(iter, iter->cursor - index); else if (iter->cursor < index) - return s_iter_advance(iter, index - iter->cursor); + return s_iter_rewind(iter, index - iter->cursor); return 1; } size_t s_iter_value(struct stack_iter *iter) @@ -432,17 +428,3 @@ size_t s_iter_index(struct stack_iter *iter) return 0; return iter->target->count - 1 - iter->cursor; } -static struct stack_iter s_impl_it_start(struct stack *_stack_) -{ - struct stack_iter iter; - s_iter_init(&iter, _stack_); - s_iter_to_start(&iter); - return iter; -} -static struct stack_iter s_impl_it_end(struct stack *_stack_) -{ - struct stack_iter iter; - s_iter_init(&iter, _stack_); - s_iter_to_end(&iter); - return iter; -} diff --git a/tests/main/unt/stack.c b/tests/main/unt/stack.c index 4861b60..0da4ecb 100644 --- a/tests/main/unt/stack.c +++ b/tests/main/unt/stack.c @@ -406,334 +406,429 @@ CMC_CREATE_UNIT(Stack, true, { }); CMC_CREATE_UNIT(StackIter, true, { - CMC_CREATE_TEST(iter_alloc, { + CMC_CREATE_TEST(PFX##_iter_start(), { struct stack *s = s_new(100, s_fval); cmc_assert_not_equals(ptr, NULL, s); - struct stack_iter *iter = s_iter_new(s); + struct stack_iter it = s_iter_start(s); - cmc_assert_not_equals(ptr, NULL, iter); + cmc_assert_equals(ptr, s, it.target); + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, true, it.start); + cmc_assert_equals(bool, true, it.end); - s_iter_free(iter); - s_free(s); - }); + cmc_assert(s_iter_at_start(&it)); + cmc_assert(s_iter_at_end(&it)); - CMC_CREATE_TEST(iter_init[count = 0], { - struct stack *s = s_new(100, s_fval); + cmc_assert(s_push(s, 1)); + cmc_assert(s_push(s, 2)); - cmc_assert_not_equals(ptr, NULL, s); + it = s_iter_start(s); - struct stack_iter iter; - - s_iter_init(&iter, s); - - cmc_assert_equals(ptr, iter.target, s); - cmc_assert_equals(size_t, iter.cursor, 0); - cmc_assert(iter.start); - cmc_assert(iter.end); + cmc_assert_equals(size_t, s->count - 1, it.cursor); + cmc_assert_equals(bool, false, it.end); s_free(s); }); - CMC_CREATE_TEST(iter_start[count = 0], { + CMC_CREATE_TEST(PFX##_iter_end(), { struct stack *s = s_new(100, s_fval); cmc_assert_not_equals(ptr, NULL, s); - struct stack_iter iter; + struct stack_iter it = s_iter_end(s); - s_iter_init(&iter, s); + cmc_assert_equals(ptr, s, 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(s_iter_start(&iter)); + cmc_assert(s_iter_at_start(&it)); + cmc_assert(s_iter_at_end(&it)); + + cmc_assert(s_push(s, 1)); + cmc_assert(s_push(s, 2)); + cmc_assert(s_push(s, 3)); + + it = s_iter_end(s); + + cmc_assert_equals(size_t, 0, it.cursor); + cmc_assert_equals(bool, false, it.start); s_free(s); }); - CMC_CREATE_TEST(iter_end[count = 0], { + CMC_CREATE_TEST(PFX##_iter_at_start(), { struct stack *s = s_new(100, s_fval); cmc_assert_not_equals(ptr, NULL, s); - struct stack_iter iter; + struct stack_iter it = s_iter_start(s); - s_iter_init(&iter, s); + // Empty checks + cmc_assert(s_iter_at_start(&it)); + it = s_iter_end(s); + cmc_assert(s_iter_at_start(&it)); - cmc_assert(s_iter_end(&iter)); + // Non-empty checks + cmc_assert(s_push(s, 1)); + it = s_iter_end(s); + cmc_assert(!s_iter_at_start(&it)); + it = s_iter_start(s); + cmc_assert(s_iter_at_start(&it)); s_free(s); }); - CMC_CREATE_TEST(iteration, { + CMC_CREATE_TEST(PFX##_iter_at_end(), { struct stack *s = s_new(100, s_fval); cmc_assert_not_equals(ptr, NULL, s); - for (size_t i = 1; i <= 200; i++) - cmc_assert(s_push(s, i)); + struct stack_iter it = s_iter_start(s); - size_t total = 0; + // Empty check + cmc_assert(s_iter_at_end(&it)); + it = s_iter_end(s); + cmc_assert(s_iter_at_end(&it)); - for (struct stack_iter it = s->it_start(s); !s_iter_end(&it); - s_iter_next(&it)) + // Non-empty checks + cmc_assert(s_push(s, 1)); + it = s_iter_end(s); + cmc_assert(s_iter_at_end(&it)); + it = s_iter_start(s); + cmc_assert(!s_iter_at_end(&it)); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_to_start(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_start(s); + + cmc_assert(!s_iter_to_start(&it)); + + for (size_t i = 1; i <= 100; i++) + s_push(s, i); + + cmc_assert_equals(size_t, 100, s->count); + + it = s_iter_end(s); + + cmc_assert(!s_iter_at_start(&it)); + cmc_assert(s_iter_at_end(&it)); + + cmc_assert_equals(size_t, 1, s_iter_value(&it)); + + cmc_assert(s_iter_to_start(&it)); + + cmc_assert(s_iter_at_start(&it)); + cmc_assert(!s_iter_at_end(&it)); + + cmc_assert_equals(size_t, 100, s_iter_value(&it)); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_to_end(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + + cmc_assert(!s_iter_to_end(&it)); + + for (size_t i = 1; i <= 100; i++) + s_push(s, i); + + it = s_iter_start(s); + + cmc_assert(s_iter_at_start(&it)); + cmc_assert(!s_iter_at_end(&it)); + + cmc_assert_equals(size_t, 100, s_iter_value(&it)); + + cmc_assert(s_iter_to_end(&it)); + + cmc_assert(!s_iter_at_start(&it)); + cmc_assert(s_iter_at_end(&it)); + + cmc_assert_equals(size_t, 1, s_iter_value(&it)); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_next(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_start(s); + + cmc_assert(!s_iter_next(&it)); + + for (size_t i = 1; i <= 1000; i++) + s_push(s, i); + + size_t sum = 0; + for (it = s_iter_start(s); !s_iter_at_end(&it); s_iter_next(&it)) { - total += s_iter_value(&it); + sum += s_iter_value(&it); } - cmc_assert_equals(size_t, 20100, total); + cmc_assert_equals(size_t, 500500, sum); - for (struct stack_iter it = s->it_end(s); !s_iter_start(&it); - s_iter_prev(&it)) - { - total += s_iter_value(&it); - } - - cmc_assert_equals(size_t, 40200, total); - - s_free(s); - }); - - CMC_CREATE_TEST(iteration[while loop], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 1; i <= 200; i++) - cmc_assert(s_push(s, i)); - - size_t total = 0; - struct stack_iter it = s->it_start(s); + sum = 0; + s_iter_to_start(&it); do { - total += s_iter_value(&it); + sum += s_iter_value(&it); } while (s_iter_next(&it)); - cmc_assert_equals(size_t, 20100, total); + cmc_assert_equals(size_t, 500500, sum); - it = s->it_end(s); + s_free(s); + }); + CMC_CREATE_TEST(PFX##_iter_prev(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + + cmc_assert(!s_iter_prev(&it)); + + for (size_t i = 1; i <= 1000; i++) + s_push(s, i); + + size_t sum = 0; + for (it = s_iter_end(s); !s_iter_at_start(&it); s_iter_prev(&it)) + { + sum += s_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + + s_iter_to_end(&it); do { - total += s_iter_value(&it); + sum += s_iter_value(&it); } while (s_iter_prev(&it)); - cmc_assert_equals(size_t, 40200, total); + cmc_assert_equals(size_t, 500500, sum); s_free(s); }); - CMC_CREATE_TEST(iteration[count = 1], { + CMC_CREATE_TEST(PFX##_iter_advance(), { struct stack *s = s_new(100, s_fval); cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_start(s); + + cmc_assert(!s_iter_advance(&it, 1)); + + for (size_t i = 0; i <= 1000; i++) + s_push(s, i); + + it = s_iter_start(s); + + cmc_assert(!s_iter_advance(&it, 0)); + cmc_assert(!s_iter_advance(&it, s->count)); + + size_t sum = 0; + for (it = s_iter_start(s);;) + { + sum += s_iter_value(&it); + + if (!s_iter_advance(&it, 2)) + break; + } + + cmc_assert_equals(size_t, 250500, sum); + + s_iter_to_start(&it); + cmc_assert(s_iter_advance(&it, s->count - 1)); + + // sum (1000, 990, 980, 970, ..., 910, 900) + sum = 0; + it = s_iter_start(s); + for (size_t val = s_iter_value(&it); val > 900; s_iter_advance(&it, 10)) + { + val = s_iter_value(&it); + sum += val; + } + + cmc_assert_equals(size_t, 10450, sum); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_rewind(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + + cmc_assert(!s_iter_rewind(&it, 1)); + + for (size_t i = 0; i <= 1000; i++) + s_push(s, i); + + it = s_iter_end(s); + + cmc_assert(!s_iter_rewind(&it, 0)); + cmc_assert(!s_iter_rewind(&it, s->count)); + + size_t sum = 0; + for (it = s_iter_end(s);;) + { + sum += s_iter_value(&it); + + if (!s_iter_rewind(&it, 2)) + break; + } + + cmc_assert_equals(size_t, 250500, sum); + + s_iter_to_end(&it); + cmc_assert(s_iter_rewind(&it, s->count - 1)); + + // sum (0, 10, 20, ..., 90, 100) + sum = 0; + it = s_iter_end(s); + for (size_t val = s_iter_value(&it); val < 100; s_iter_rewind(&it, 10)) + { + val = s_iter_value(&it); + sum += val; + } + + cmc_assert_equals(size_t, 550, sum); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_go_to(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + cmc_assert(!s_iter_go_to(&it, 0)); + + it = s_iter_start(s); + cmc_assert(!s_iter_go_to(&it, 0)); + + for (size_t i = 1001; i > 0; i--) + s_push(s, i - 1); + + it = s_iter_start(s); + + size_t sum = 0; + for (size_t i = 0; i < 1001; i++) + { + s_iter_go_to(&it, i); + + sum += s_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + for (size_t i = 1001; i > 0; i--) + { + cmc_assert(s_iter_go_to(&it, i - 1)); + + sum += s_iter_value(&it); + } + + cmc_assert_equals(size_t, 500500, sum); + + sum = 0; + for (size_t i = 1000; i > 0; i -= 100) + { + cmc_assert(s_iter_go_to(&it, 1000 - i)); + cmc_assert_equals(size_t, i, s_iter_index(&it)); + + sum += s_iter_value(&it); + } + + cmc_assert_equals(size_t, 5500, sum); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_value(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + struct stack_iter it = s_iter_end(s); + + cmc_assert_equals(size_t, (size_t){ 0 }, s_iter_value(&it)); + cmc_assert(s_push(s, 10)); - size_t total = 0; + it = s_iter_start(s); - for (struct stack_iter it = s->it_start(s); !s_iter_end(&it); - s_iter_next(&it)) - { - total += s_iter_value(&it); - } - - for (struct stack_iter it = s->it_end(s); !s_iter_start(&it); - s_iter_prev(&it)) - { - total += s_iter_value(&it); - } - - cmc_assert_equals(size_t, 20, total); + cmc_assert_equals(size_t, 10, s_iter_value(&it)); s_free(s); }); - CMC_CREATE_TEST(iteration[count = capacity], { + CMC_CREATE_TEST(PFX##_iter_rvalue(), { struct stack *s = s_new(100, s_fval); cmc_assert_not_equals(ptr, NULL, s); - while (!s_full(s)) - cmc_assert(s_push(s, 10)); + struct stack_iter it = s_iter_end(s); - cmc_assert_equals(size_t, s_capacity(s), s_count(s)); + cmc_assert_equals(ptr, NULL, s_iter_rvalue(&it)); - size_t total = 0; + cmc_assert(s_push(s, 10)); - for (struct stack_iter it = s->it_start(s); !s_iter_end(&it); - s_iter_next(&it)) + it = s_iter_start(s); + + cmc_assert_not_equals(ptr, NULL, s_iter_rvalue(&it)); + cmc_assert_equals(size_t, 10, *s_iter_rvalue(&it)); + + s_free(s); + }); + + CMC_CREATE_TEST(PFX##_iter_index(), { + struct stack *s = s_new(100, s_fval); + + cmc_assert_not_equals(ptr, NULL, s); + + for (size_t i = 0; i <= 1000; i++) + s_push(s, i); + + struct stack_iter it = s_iter_start(s); + + for (size_t i = 0; i < 1001; i++) { - total += s_iter_value(&it); + cmc_assert_equals(size_t, i, s_iter_index(&it)); + s_iter_next(&it); } - cmc_assert_equals(size_t, 1000, total); - - for (struct stack_iter it = s->it_end(s); !s_iter_start(&it); - s_iter_prev(&it)) + it = s_iter_end(s); + for (size_t i = 1001; i > 0; i--) { - total += *s_iter_rvalue(&it); + cmc_assert_equals(size_t, i - 1, s_iter_index(&it)); + s_iter_prev(&it); } - cmc_assert_equals(size_t, 2000, total); - - s_free(s); - }); - - CMC_CREATE_TEST(iteration[to_start = it_start and to_end = it_end], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 50; i++) - cmc_assert(s_push(s, i)); - - struct stack_iter it1; - struct stack_iter it2; - - memset(&it1, 0, sizeof(struct stack_iter)); - memset(&it2, 0, sizeof(struct stack_iter)); - - s_iter_init(&it2, s); - - it1 = s->it_start(s); - s_iter_to_start(&it2); - - cmc_assert_equals(ptr, it1.target, it2.target); - cmc_assert_equals(size_t, it1.cursor, it2.cursor); - cmc_assert_equals(bool, it1.start, it2.start); - cmc_assert_equals(bool, it1.end, it2.end); - - it1 = s->it_end(s); - s_iter_to_end(&it2); - - cmc_assert_equals(ptr, it1.target, it2.target); - cmc_assert_equals(size_t, it1.cursor, it2.cursor); - cmc_assert_equals(bool, it1.start, it2.start); - cmc_assert_equals(bool, it1.end, it2.end); - - s_free(s); - }); - - CMC_CREATE_TEST(iteration[boundaries count = 0], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter iter; - s_iter_init(&iter, s); - - s_iter_to_end(&iter); - - cmc_assert_equals(bool, false, s_iter_next(&iter)); - - s_iter_to_start(&iter); - - cmc_assert_equals(bool, false, s_iter_prev(&iter)); - - s_free(s); - }); - - CMC_CREATE_TEST(iteration[boundaries count > 0], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 200; i++) - cmc_assert(s_push(s, i)); - - struct stack_iter iter; - s_iter_init(&iter, s); - - s_iter_to_end(&iter); - - cmc_assert_equals(bool, false, s_iter_next(&iter)); - - s_iter_to_start(&iter); - - cmc_assert_equals(bool, false, s_iter_prev(&iter)); - - s_free(s); - }); - - CMC_CREATE_TEST(iter_value[count = 0], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter iter; - - s_iter_init(&iter, s); - - cmc_assert_equals(size_t, (size_t){ 0 }, s_iter_value(&iter)); - - s_free(s); - }); - - CMC_CREATE_TEST(iter_rvalue[count = 0], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter iter; - - s_iter_init(&iter, s); - - cmc_assert_equals(ptr, NULL, s_iter_rvalue(&iter)); - - s_free(s); - }); - - CMC_CREATE_TEST(index, { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 10; i++) - cmc_assert(s_push(s, i)); - - cmc_assert_equals(size_t, 10, s_count(s)); - - size_t total = 0; - - for (struct stack_iter it = s->it_start(s); false;) - { - cmc_assert_equals(size_t, 0, s_iter_index(&it)); - } - - for (struct stack_iter it = s->it_start(s); false;) - { - cmc_assert_equals(size_t, s_count(s) - 1, s_iter_index(&it)); - } - - for (struct stack_iter it = s->it_start(s); !s_iter_end(&it); - s_iter_next(&it)) - { - total += s_iter_index(&it); - } - - cmc_assert_equals(size_t, 45, total); - - for (struct stack_iter it = s->it_end(s); !s_iter_start(&it); - s_iter_prev(&it)) - { - total += s_iter_index(&it); - } - - cmc_assert_equals(size_t, 90, total); - - s_free(s); - }); - - CMC_CREATE_TEST(index[count = 0], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter iter; - s_iter_init(&iter, s); - - cmc_assert_equals(size_t, 0, s_iter_index(&iter)); - s_free(s); }); });