From 0d6ba144512cff4fcb15b4642c25800207f7c7a4 Mon Sep 17 00:00:00 2001 From: wjf-hs Date: Wed, 23 Apr 2025 18:35:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E5=AE=9E=E6=B5=8B=E6=83=85?= =?UTF-8?q?=E5=86=B5=E6=9D=A5=E7=9C=8B=EF=BC=8Citer=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E6=98=AF=E5=8F=AF=E8=A1=8C=E7=9A=84=EF=BC=8C=E5=90=8E?= =?UTF-8?q?=E7=BB=AD=E5=86=8D=E8=80=83=E8=99=91=E5=AE=9E=E7=8E=B0=E7=BB=86?= =?UTF-8?q?=E8=8A=82=E5=90=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +- include/iter.h | 32 +++++++++++++++++++++ include/list.h | 4 +++ src/list.c | 65 ++++++++++++++++++++++++++++++++++++++++++- test/test_list.c | 43 ++++++++++++++++++++++++++++ 5 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 include/iter.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 4273231..85ec3df 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,6 +24,7 @@ "unity_internals.h": "c", "stdarg.h": "c", "graph.h": "c", - "unicstl_config.h": "c" + "unicstl_config.h": "c", + "iter.h": "c" } } \ No newline at end of file diff --git a/include/iter.h b/include/iter.h new file mode 100644 index 0000000..85c86d5 --- /dev/null +++ b/include/iter.h @@ -0,0 +1,32 @@ +/** + * @file iter.h + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2025-04-23 + * + * @copyright Copyright (c) 2025 + * + */ +#ifndef _ITER_H_ +#define _ITER_H_ + +#include "common.h" + +struct _iterator +{ + void* obj; + void* self; + void* parent; + + void* (*begin)(struct _iterator* self); + void* (*next)(struct _iterator* self); + void* (*end)(struct _iterator* self); + + bool (*hasnext)(struct _iterator* self); + + void* (*data)(struct _iterator* self); +}; +typedef struct _iterator* iterator_t; + +#endif // !_ITER_H_ diff --git a/include/list.h b/include/list.h index d5cf28d..f1171b5 100644 --- a/include/list.h +++ b/include/list.h @@ -12,6 +12,7 @@ #define _LIST_H_ #include "common.h" +#include "iter.h" struct _list { @@ -23,6 +24,9 @@ struct _list uint32_t _ratio; uint32_t _cur; + struct _iterator _iter; + iterator_t (*iter)(struct _list* self); + // kernel bool (*append)(struct _list* self, void* obj); // Append object to the end of the list. bool (*insert)(struct _list* self, int index, void* obj); // Insert object before index. diff --git a/src/list.c b/src/list.c index a8e82dc..6198f0e 100644 --- a/src/list.c +++ b/src/list.c @@ -250,6 +250,57 @@ static bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity) return true; } +iterator_t list_iter(struct _list* self) +{ + self->_cur = 0; + self->_iter.obj = self->obj; + return &self->_iter; +} + +static void* list_iter_begin(struct _iterator* iter) +{ + list_t self = (list_t)iter->parent; + self->_cur = 0; + iter->obj = self->obj; + return iter; +} + +static void* list_iter_end(struct _iterator* iter) +{ + list_t self = (list_t)iter->parent; + iter->obj = (char*)self->obj + self->_size * self->_obj_size; + return iter; +} + +static void* list_iter_next(struct _iterator* iter) +{ + list_t self = (list_t)iter->parent; + + // if add this, can't go to end + // if(self->_cur < self->_size - 1) + { + self->_cur += 1; + } + iter->obj = (char*)self->obj + self->_cur * self->_obj_size; + return iter; +} + +static bool list_iter_hasnext(struct _iterator* iter) +{ + list_t self = (list_t)iter->parent; + + if(self->_cur < self->_size) + { + return true; + } + return false; +} + +static void* list_iter_data(struct _iterator* iter) +{ + return iter->obj; +} + list_t list_new2(uint32_t obj_size, uint32_t capacity) { struct _list* list = NULL; @@ -259,9 +310,21 @@ list_t list_new2(uint32_t obj_size, uint32_t capacity) if(list_init2(list, obj_size, capacity) != true) { free(list); - list = NULL; + // list = NULL; + return NULL; } } + + list->_iter.self = &list->iter; + list->_iter.parent = list; + + list->_iter.begin = list_iter_begin; + list->_iter.next = list_iter_next; + list->_iter.end = list_iter_end; + list->_iter.data = list_iter_data; + list->_iter.hasnext = list_iter_hasnext; + + list->iter = list_iter; return list; } diff --git a/test/test_list.c b/test/test_list.c index 3166999..4c2d29f 100644 --- a/test/test_list.c +++ b/test/test_list.c @@ -328,6 +328,47 @@ static void test_list_iter(void) list_free(&list); } +void list_iter_test(void) +{ + int temp = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + uint32_t len = sizeof(data) / sizeof(data[0]); + uint32_t i = 0; + + list_t list = NULL; + + // ------------------------------ + list = list_new2(sizeof(int), len); + TEST_ASSERT_TRUE(list->empty(list)); + list->print_obj = print_num; + + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->append(list, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, list->size(list)); + + TEST_ASSERT_TRUE(list->get(list, i, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + + TEST_ASSERT_FALSE(list->empty(list)); + } + + iterator_t it = list->iter(list); + printf("iter start\n"); + list->print(list); + + printf("\n"); + while(it->hasnext(it)) + { + int dd = *(int*)it->data(it); + printf("%d ", dd); + it->next(it); + } + printf("\niter end\n"); + + list_free(&list); +} + void test_list(void) { UnitySetTestFile(__FILE__); @@ -341,4 +382,6 @@ void test_list(void) RUN_TEST(test_list_struct); RUN_TEST(test_list_iter); + + RUN_TEST(list_iter_test); }