From f72d799696690e098190d99de9857ab142094a7f Mon Sep 17 00:00:00 2001 From: Bill Morgan Date: Sun, 1 Dec 2024 08:07:33 -0600 Subject: [PATCH] improve Tuple iteration fix #153 --- include/Cello.h | 1 + src/Tuple.c | 24 ++++++++++-------------- tests/test.c | 5 ++++- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/Cello.h b/include/Cello.h index c502a10..436ff2b 100644 --- a/include/Cello.h +++ b/include/Cello.h @@ -264,6 +264,7 @@ struct String { struct Tuple { var* items; size_t len; + size_t iter; }; struct Range { diff --git a/src/Tuple.c b/src/Tuple.c index c1570ab..51a0aa5 100644 --- a/src/Tuple.c +++ b/src/Tuple.c @@ -152,33 +152,29 @@ static size_t Tuple_Len(var self) { static var Tuple_Iter_Init(var self) { struct Tuple* t = self; + t->iter = 0; return t->items[0]; } static var Tuple_Iter_Next(var self, var curr) { struct Tuple* t = self; - size_t i = 0; - while (t->items[i] isnt Terminal) { - if (t->items[i] is curr) { return t->items[i+1]; } - i++; - } - return Terminal; + if (t->items[t->iter] is Terminal) { return Terminal; } + t->iter++; + return t->items[t->iter]; } static var Tuple_Iter_Last(var self) { struct Tuple* t = self; - return t->items[Tuple_Len(t)-1]; + size_t len = Tuple_Len(t); + if (len is 0) { return Terminal; } + return t->items[len-1]; } static var Tuple_Iter_Prev(var self, var curr) { struct Tuple* t = self; - if (curr is t->items[0]) { return Terminal; } - size_t i = 0; - while (t->items[i] isnt Terminal) { - if (t->items[i] is curr) { return t->items[i-1]; } - i++; - } - return Terminal; + if (t->iter is 0) { return Terminal; } + t->iter--; + return t->items[t->iter]; } static var Tuple_Get(var self, var key) { diff --git a/tests/test.c b/tests/test.c index 6db7acd..34e0f74 100644 --- a/tests/test.c +++ b/tests/test.c @@ -2495,10 +2495,13 @@ PT_FUNC(test_tuple_hash) { PT_FUNC(test_tuple_iter) { size_t i = 0; - foreach (x in tuple($I(10), $I(20), $I(30))) { + var y = $I(0); + foreach (x in tuple($I(10), $I(20), $I(30), y, y)) { if (i is 0) { PT_ASSERT(eq(x, $I(10))); } if (i is 1) { PT_ASSERT(eq(x, $I(20))); } if (i is 2) { PT_ASSERT(eq(x, $I(30))); } + if (i is 3) { PT_ASSERT(eq(x, y)); } + if (i is 4) { PT_ASSERT(eq(x, y)); } i++; }