From 61019593c9e15897237f030edd85610b48147970 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Fri, 22 Mar 2019 21:26:16 -0300 Subject: [PATCH] Fixing linked list iterator and renaming example folder names --- examples/{ex2 => for_each}/main.c | 0 examples/{ex3 => iterator}/main.c | 6 ++- .../{ex1 => separate_header_source}/Makefile | 0 .../containers.c | 0 .../containers.h | 0 .../{ex1 => separate_header_source}/main.c | 0 src/linkedlist.h | 51 ++++++++++++++----- tests/iterators/linkedlist.c | 39 ++++++++++++++ 8 files changed, 81 insertions(+), 15 deletions(-) rename examples/{ex2 => for_each}/main.c (100%) rename examples/{ex3 => iterator}/main.c (88%) rename examples/{ex1 => separate_header_source}/Makefile (100%) rename examples/{ex1 => separate_header_source}/containers.c (100%) rename examples/{ex1 => separate_header_source}/containers.h (100%) rename examples/{ex1 => separate_header_source}/main.c (100%) create mode 100644 tests/iterators/linkedlist.c diff --git a/examples/ex2/main.c b/examples/for_each/main.c similarity index 100% rename from examples/ex2/main.c rename to examples/for_each/main.c diff --git a/examples/ex3/main.c b/examples/iterator/main.c similarity index 88% rename from examples/ex3/main.c rename to examples/iterator/main.c index e2069ba..6611f33 100644 --- a/examples/ex3/main.c +++ b/examples/iterator/main.c @@ -24,13 +24,15 @@ int main(int argc, char const *argv[]) ll_iter_toend(&iter); // While there is a previous element on the list while (ll_iter_prev(&iter, &r, &i)) - printf("list[%d] = %d\n", i, r); + printf("list[%2d] = %2d\n", i, r); + + printf("\n"); // Move cursor to the start of the list ll_iter_tostart(&iter); // While there is a next element on the list while (ll_iter_next(&iter, &r, &i)) - printf("list[%d] = %d\n", i, r); + printf("list[%2d] = %2d\n", i, r); ll_free(ll); diff --git a/examples/ex1/Makefile b/examples/separate_header_source/Makefile similarity index 100% rename from examples/ex1/Makefile rename to examples/separate_header_source/Makefile diff --git a/examples/ex1/containers.c b/examples/separate_header_source/containers.c similarity index 100% rename from examples/ex1/containers.c rename to examples/separate_header_source/containers.c diff --git a/examples/ex1/containers.h b/examples/separate_header_source/containers.h similarity index 100% rename from examples/ex1/containers.h rename to examples/separate_header_source/containers.h diff --git a/examples/ex1/main.c b/examples/separate_header_source/main.c similarity index 100% rename from examples/ex1/main.c rename to examples/separate_header_source/main.c diff --git a/src/linkedlist.h b/src/linkedlist.h index ca842f1..c772d62 100644 --- a/src/linkedlist.h +++ b/src/linkedlist.h @@ -19,6 +19,11 @@ #include #include +#define LINKEDLIST_GENERATE(PFX, SNAME, FMOD, K, T) \ + LINKEDLIST_GENERATE_STRUCT(PFX, SNAME, FMOD, K, T) \ + LINKEDLIST_GENERATE_HEADER(PFX, SNAME, FMOD, K, T) \ + LINKEDLIST_GENERATE_SOURCE(PFX, SNAME, FMOD, K, T) + /* PRIVATE *******************************************************************/ #define LINKEDLIST_GENERATE_HEADER_PRIVATE(PFX, SNAME, FMOD, K, T) \ LINKEDLIST_GENERATE_HEADER(PFX, SNAME, FMOD, K, T) @@ -53,6 +58,8 @@ struct SNAME##_s *target; \ struct SNAME##_node_s *cursor; \ intmax_t count; \ + bool start; \ + bool end; \ }; \ \ /* HEADER ********************************************************************/ @@ -372,55 +379,73 @@ { \ iter->target = target; \ iter->cursor = target->head; \ - iter->count = -1; \ + iter->count = 0; \ + iter->start = true; \ + iter->end = false; \ } \ \ FMOD bool PFX##_iter_start(SNAME##_iter *iter) \ { \ - return iter->count < 0; \ + return iter->cursor->prev == NULL && iter->start; \ } \ \ FMOD bool PFX##_iter_end(SNAME##_iter *iter) \ { \ - return iter->count == iter->target->count; \ + return iter->cursor->next == NULL && iter->end; \ } \ \ FMOD void PFX##_iter_tostart(SNAME##_iter *iter) \ { \ iter->cursor = iter->target->head; \ iter->count = 0; \ + iter->start = true; \ + iter->end = false; \ } \ \ FMOD void PFX##_iter_toend(SNAME##_iter *iter) \ { \ iter->cursor = iter->target->tail; \ iter->count = iter->target->count - 1; \ + iter->start = false; \ + iter->end = true; \ } \ \ FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index) \ { \ - if (PFX##_iter_start(iter)) \ - PFX##_iter_tostart(iter); \ - if (PFX##_iter_end(iter)) \ + if (iter->end) \ return false; \ \ - *index = iter->count++; \ + *index = iter->count; \ *result = iter->cursor->data; \ - iter->cursor = iter->cursor->next; \ + iter->start = false; \ + \ + if (iter->cursor->next == NULL) \ + iter->end = true; \ + else \ + { \ + iter->cursor = iter->cursor->next; \ + iter->count++; \ + } \ \ return true; \ } \ \ FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index) \ { \ - if (PFX##_iter_end(iter)) \ - PFX##_iter_toend(iter); \ - if (PFX##_iter_start(iter)) \ + if (iter->start) \ return false; \ \ - *index = iter->count--; \ + *index = iter->count; \ *result = iter->cursor->data; \ - iter->cursor = iter->cursor->prev; \ + iter->end = false; \ + \ + if (iter->cursor->prev == NULL) \ + iter->start = true; \ + else \ + { \ + iter->cursor = iter->cursor->prev; \ + iter->count--; \ + } \ \ return true; \ } diff --git a/tests/iterators/linkedlist.c b/tests/iterators/linkedlist.c new file mode 100644 index 0000000..0e4412a --- /dev/null +++ b/tests/iterators/linkedlist.c @@ -0,0 +1,39 @@ +// Checks if the linked list iterator can go back and forward in the list +// without hitting invalid states or a null pointer. Check is done visually. +#include +#include +#include +#include +#include "../../src/macro_collections.h" + +CONTAINER_GENERATE(LINKEDLIST, PUBLIC, ll, linked, static, , int) + +int main(int argc, char const *argv[]) +{ + size_t i; + int r; + + // Initliazie linked list and add some elements + linked *ll = ll_new(); + for (int i = 0; i < 10; i++) + ll_push_back(ll, i); + + // Initialize iterator + linked_iter iter; + ll_iter(&iter, ll); + + // Make the iterator go back and forward + for (int j = 0; j < 4; j++) + { + while (ll_iter_next(&iter, &r, &i)) + printf("list[%2d] = %2d\n", i, r); + printf("\n"); + while (ll_iter_prev(&iter, &r, &i)) + printf("list[%2d] = %2d\n", i, r); + printf("\n\n"); + } + + ll_free(ll); + + return 0; +}