diff --git a/src/stack.h b/src/stack.h index 69ce95b..0e51e42 100644 --- a/src/stack.h +++ b/src/stack.h @@ -50,6 +50,8 @@ { \ struct SNAME##_s *target; \ size_t cursor; \ + bool start; \ + bool end; \ }; \ \ /* HEADER ********************************************************************/ @@ -71,7 +73,12 @@ FMOD size_t PFX##_capacity(SNAME *_stack_); \ \ FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target); \ + FMOD bool PFX##_iter_start(SNAME##_iter *iter); \ + FMOD bool PFX##_iter_end(SNAME##_iter *iter); \ + FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \ + FMOD void PFX##_iter_toend(SNAME##_iter *iter); \ FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index); \ + FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index); \ \ /* SOURCE ********************************************************************/ #define STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, K, T) \ @@ -198,19 +205,67 @@ FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target) \ { \ iter->target = target; \ + iter->cursor = iter->target->count - 1; \ + iter->start = true; \ + iter->end = false; \ + } \ + \ + FMOD bool PFX##_iter_start(SNAME##_iter *iter) \ + { \ + return iter->cursor == iter->target->count - 1 && iter->start; \ + } \ + \ + FMOD bool PFX##_iter_end(SNAME##_iter *iter) \ + { \ + return iter->cursor == 0 && iter->end; \ + } \ + \ + FMOD void PFX##_iter_tostart(SNAME##_iter *iter) \ + { \ + iter->cursor = iter->target->count - 1; \ + iter->start = true; \ + iter->end = false; \ + } \ + \ + FMOD void PFX##_iter_toend(SNAME##_iter *iter) \ + { \ iter->cursor = 0; \ + iter->start = false; \ + iter->end = true; \ } \ \ FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index) \ { \ - if (iter->cursor < iter->target->count) \ - { \ - *index = iter->cursor; \ - *result = iter->target->buffer[iter->cursor++]; \ - return true; \ - } \ + if (iter->end) \ + return false; \ \ - return false; \ + *index = iter->cursor; \ + *result = iter->target->buffer[iter->cursor]; \ + iter->start = false; \ + \ + if (iter->cursor == 0) \ + iter->end = true; \ + else \ + iter->cursor--; \ + \ + return true; \ + } \ + \ + FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index) \ + { \ + if (iter->start) \ + return false; \ + \ + *index = iter->cursor; \ + *result = iter->target->buffer[iter->cursor]; \ + iter->end = false; \ + \ + if (iter->cursor == iter->target->count - 1) \ + iter->start = true; \ + else \ + iter->cursor++; \ + \ + return true; \ } #endif /* CMC_STACK_H */ diff --git a/tests/foreach.c b/tests/foreach.c index f4144fb..fb899a7 100644 --- a/tests/foreach.c +++ b/tests/foreach.c @@ -59,27 +59,49 @@ int main(int argc, char const *argv[]) if (sum0 == 50005000) printf("%10s PASSED\n", "LIST"); - if (sum4 == 50005000) - printf("%10s PASSED\n", "LINKEDLIST"); if (sum1 == 50005000) printf("%10s PASSED\n", "STACK"); if (sum2 == 50005000) printf("%10s PASSED\n", "QUEUE"); if (sum3 == 50005000) printf("%10s PASSED\n", "DEQUE"); + if (sum4 == 50005000) + printf("%10s PASSED\n", "LINKEDLIST"); printf("\n\n"); sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0; + FOR_EACH_REV(l, list, , int, l, { + sum0 += var; + }) + + FOR_EACH_REV(s, stack, , int, s, { + sum1 += var; + }) + + // FOR_EACH_REV(q, queue, , int, q, { + // sum2 += var; + // }) + + // FOR_EACH_REV(d, deque, , int, d, { + // sum3 += var; + // }) + FOR_EACH_REV(ll, linked, , int, ll, { sum4 += var; }) + if (sum0 == 50005000) + printf("%10s PASSED\n", "LIST"); + if (sum1 == 50005000) + printf("%10s PASSED\n", "STACK"); + // if (sum2 == 50005000) + // printf("%10s PASSED\n", "QUEUE"); + // if (sum3 == 50005000) + // printf("%10s PASSED\n", "DEQUE"); if (sum4 == 50005000) printf("%10s PASSED\n", "LINKEDLIST"); - else - printf("%10s ERROR %d", "LINKEDLIST", sum4); l_free(l); ll_free(ll); diff --git a/tests/iterators/stack.c b/tests/iterators/stack.c new file mode 100644 index 0000000..bd8e5d7 --- /dev/null +++ b/tests/iterators/stack.c @@ -0,0 +1,39 @@ +// Checks if the stack iterator can go back and forward in the stack without +// hitting invalid states or a nul pointer. Check is done visually. +#include +#include +#include +#include +#include "../../src/stack.h" + +STACK_GENERATE(s, stack, static, , int) + +int main(int argc, char const *argv[]) +{ + size_t i; + int r; + + // Initliazie stack and add some elements + stack *s = s_new(10); + for (int i = 0; i < 10; i++) + s_push(s, i); + + // Initialize iterator + stack_iter iter; + s_iter(&iter, s); + + // Make the iterator go back and forward + for (int j = 0; j < 4; j++) + { + while (s_iter_next(&iter, &r, &i)) + printf("C[%2d] = %2d\n", i, r); + printf("\n"); + while (s_iter_prev(&iter, &r, &i)) + printf("C[%2d] = %2d\n", i, r); + printf("\n\n"); + } + + s_free(s); + + return 0; +}