From 17a9d514378133ab2e34c6c80c815435722b9758 Mon Sep 17 00:00:00 2001 From: wjf-hs Date: Mon, 11 May 2026 19:05:58 +0800 Subject: [PATCH] =?UTF-8?q?linklist=E5=85=88=E7=85=A7=E6=90=AC=E4=BA=86que?= =?UTF-8?q?ue=EF=BC=8C=E5=90=8E=E7=BB=AD=E7=94=A8=E5=88=B0=E5=86=8D?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=90=A7=E3=80=82=E5=8F=A6=E5=A4=96=EF=BC=8C?= =?UTF-8?q?darray=E4=B8=AD=E7=9A=84=E9=83=A8=E5=88=86=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E4=BC=A0=E5=8F=82=EF=BC=8C=E6=88=91=E6=B7=BB=E5=8A=A0=E4=BA=86?= =?UTF-8?q?const=E4=BF=AE=E9=A5=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/README.md | 20 +++ include/darray.h | 10 +- include/linklist.h | 62 ++++----- include/unicstl.h | 2 +- src/darray.c | 43 +++--- src/linklist.c | 262 +++++++++++++++++++++++++++++++++++ test/test.c | 1 + test/test.h | 4 +- test/test_darray.c | 207 +++++++++++++++++++++++++++- test/test_linklist.c | 321 +++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 872 insertions(+), 60 deletions(-) create mode 100644 doc/README.md create mode 100644 src/linklist.c create mode 100644 test/test_linklist.c diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..a6d4490 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,20 @@ + +# unicstl + +## 架构 +```mermaid +flowchart TB + subgraph bottom + darray + linklist + end + + subgraph mid + deque --> darray + end + + subgraph top + stack --> deque + queue --> deque + end +``` diff --git a/include/darray.h b/include/darray.h index 25bdd24..40e04f1 100644 --- a/include/darray.h +++ b/include/darray.h @@ -33,17 +33,17 @@ struct _darray // kernel bool (*resize)(struct _darray *self, uint32_t capacity); - bool (*append)(struct _darray *self, void *obj); + bool (*append)(struct _darray *self, const void *obj); bool (*pop)(struct _darray *self, void *obj); - bool (*insert)(struct _darray *self, int index, void *obj); + bool (*insert)(struct _darray *self, int index, const void *obj); bool (*remove)(struct _darray *self, int index, void *obj); + bool (*set)(struct _darray *self, int index, const void *obj); bool (*get)(struct _darray *self, int index, void *obj); - bool (*set)(struct _darray *self, int index, void *obj); - int (*index)(struct _darray *self, void *obj); // retval -1 if not found - bool (*contains)(struct _darray *self, void *obj); + int (*index)(struct _darray *self, const void *obj); // retval -1 if not found + bool (*contains)(struct _darray *self, const void *obj); // base uint32_t (*size)(struct _darray *self); diff --git a/include/linklist.h b/include/linklist.h index d4be439..8fbed25 100644 --- a/include/linklist.h +++ b/include/linklist.h @@ -1,12 +1,12 @@ /** * @file linklist.h * @author wenjf (orig5826@163.com) - * @brief + * @brief * @version 0.1 * @date 2026-05-11 - * + * * @copyright Copyright (c) 2026 - * + * */ #ifndef _LINKLIST_H_ #define _LINKLIST_H_ @@ -16,52 +16,52 @@ struct _linklist_node { - void* obj; - struct _linklist_node* next; + void *obj; + struct _linklist_node *next; }; struct _linklist { - // -------------------- private -------------------- - struct _linklist_node* _head; - struct _linklist_node* _tail; + // -------------------- private -------------------- + struct _linklist_node *_front; + struct _linklist_node *_back; + + uint32_t _index_front; + uint32_t _index_back; uint32_t _obj_size; uint32_t _size; - // uint32_t _capacity; - // uint32_t _ratio; + uint32_t _capacity; + uint32_t _ratio; struct _iterator _iter; - void (*_destory)(struct _linklist* self); + void (*_destory)(struct _linklist *self); - // -------------------- public -------------------- + // -------------------- public -------------------- // kernel - bool (*push_back)(struct _linklist* self, void* obj); - bool (*push_front)(struct _linklist* self, void* obj); - bool (*pop_back)(struct _linklist* self, void* obj); - bool (*pop_front)(struct _linklist* self, void* obj); - bool (*back)(struct _linklist* self, void* obj); - bool (*front)(struct _linklist* self, void* obj); - + bool (*push)(struct _linklist *self, void *obj); + bool (*pop)(struct _linklist *self, void *obj); + bool (*back)(struct _linklist *self, void *obj); + bool (*front)(struct _linklist *self, void *obj); + bool (*empty)(struct _linklist *self); + bool (*full)(struct _linklist *self); + // base - uint32_t(*size)(struct _linklist* self); - bool (*clear)(struct _linklist* self); - bool (*empty)(struct _linklist* self); + uint32_t (*size)(struct _linklist *self); + uint32_t (*capacity)(struct _linklist *self); + bool (*clear)(struct _linklist *self); // iter - iterator_t (*iter)(struct _linklist* self); + iterator_t (*iter)(struct _linklist *self); - // -------------------- debug -------------------- - void (*print)(struct _linklist* self); - void (*print_obj)(void* obj); + // -------------------- debug -------------------- + void (*print)(struct _linklist *self); + void (*print_obj)(void *obj); }; -typedef struct _linklist* linklist_t; +typedef struct _linklist *linklist_t; -// create and free deque linklist_t linklist_new(uint32_t obj_size); - -void linklist_free(linklist_t* deque); - +void linklist_free(linklist_t *linklist); #endif diff --git a/include/unicstl.h b/include/unicstl.h index 55403d4..f2f8272 100644 --- a/include/unicstl.h +++ b/include/unicstl.h @@ -13,7 +13,7 @@ #define UNICSTL_VERSION_MAJOR 0 #define UNICSTL_VERSION_MINOR 0 -#define UNICSTL_VERSION_MICRO 2 +#define UNICSTL_VERSION_MICRO 10 #define UNICSTL_VERSION ((UNICSTL_VERSION_MAJOR << 16) | (UNICSTL_VERSION_MINOR << 8) | UNICSTL_VERSION_MICRO) #include "unicstl_internal.h" diff --git a/src/darray.c b/src/darray.c index 22fe401..122a141 100644 --- a/src/darray.c +++ b/src/darray.c @@ -97,7 +97,7 @@ static bool darray_resize(struct _darray *self, uint32_t capacity) return true; } -static bool darray_insert(struct _darray *self, int index, void *obj) +static bool darray_insert(struct _darray *self, int index, const void *obj) { assert(self != NULL); if (index < 0 || index > (int)self->size(self)) @@ -155,7 +155,7 @@ static bool darray_remove(struct _darray *self, int index, void *obj) return true; } -static bool darray_append(struct _darray *self, void *obj) +static bool darray_append(struct _darray *self, const void *obj) { return darray_insert(self, self->size(self), obj); } @@ -165,6 +165,22 @@ static bool darray_pop(struct _darray *self, void *obj) return darray_remove(self, self->size(self) - 1, obj); } +static bool darray_set(struct _darray *self, int index, const void *obj) +{ + assert(self != NULL); + if(obj == NULL) + { + return false; + } + if (index < 0 || index >= self->size(self)) + { + return false; + } + uint32_t offset = index * self->_obj_size; + memmove((char*)self->obj + offset, obj, self->_obj_size); + return true; +} + static bool darray_get(struct _darray *self, int index, void *obj) { assert(self != NULL); @@ -181,23 +197,8 @@ static bool darray_get(struct _darray *self, int index, void *obj) return true; } -static bool darray_set(struct _darray *self, int index, void *obj) -{ - assert(self != NULL); - if(obj == NULL) - { - return false; - } - if (index < 0 || index >= self->size(self)) - { - return false; - } - uint32_t offset = index * self->_obj_size; - memmove((char*)self->obj + offset, obj, self->_obj_size); - return true; -} -static int darray_index(struct _darray *self, void *obj) +static int darray_index(struct _darray *self, const void *obj) { assert(self != NULL); if (obj == NULL) @@ -207,7 +208,7 @@ static int darray_index(struct _darray *self, void *obj) for (int i = 0; i < self->size(self); ++i) { - if (self->compare((char*)self->obj + i * self->_obj_size, obj) == 0) + if (self->compare((char*)self->obj + i * self->_obj_size, (char*)obj) == 0) { return i; } @@ -215,7 +216,7 @@ static int darray_index(struct _darray *self, void *obj) return -1; } -static bool darray_contains(struct _darray *self, void *obj) +static bool darray_contains(struct _darray *self, const void *obj) { return darray_index(self, obj) != -1; } @@ -246,8 +247,8 @@ static bool darray_init(struct _darray *self, uint32_t obj_size, uint32_t capaci self->append = darray_append; self->pop = darray_pop; - self->get = darray_get; self->set = darray_set; + self->get = darray_get; self->index = darray_index; self->contains = darray_contains; diff --git a/src/linklist.c b/src/linklist.c new file mode 100644 index 0000000..a924372 --- /dev/null +++ b/src/linklist.c @@ -0,0 +1,262 @@ +/** + * @file linklist.c + * @author wenjf (orig5826@163.com) + * @brief + * @version 0.1 + * @date 2026-05-11 + * + * @copyright Copyright (c) 2026 + * + */ +#include "linklist.h" + + +static struct _linklist_node * linklist_new_node(void* obj, uint32_t obj_size) +{ + void * new_obj = malloc(obj_size); + if (new_obj == NULL) + { + goto done; + } + memmove(new_obj, obj, obj_size); + + struct _linklist_node* new_node = (struct _linklist_node*)malloc(sizeof(struct _linklist_node)); + if(new_node == NULL) + { + goto done1; + } + new_node->obj = new_obj; + new_node->next = NULL; + + return new_node; +done1: + free(new_obj); +done: + return NULL; +} + +static void linklist_node_free(struct _linklist_node** node) +{ + if(node != NULL && *node != NULL) + { + if((*node)->obj != NULL) + { + free((*node)->obj); + } + free(*node); + *node = NULL; + } +} + +static uint32_t linklist_size(struct _linklist* self) +{ + assert(self != NULL); + return self->_size; +} + +static uint32_t linklist_capacity(struct _linklist* self) +{ + assert(self != NULL); + return self->_capacity; +} + +static bool linklist_clear(struct _linklist* self) +{ + assert(self != NULL); + if(self->empty(self)) + { + return true; + } + + struct _linklist_node* node = self->_front; + struct _linklist_node* next = NULL; + while (node) + { + next = node->next; + linklist_node_free(&node); + node = next; + } + self->_front = NULL; + self->_back = NULL; + self->_size = 0; + return true; +} + +static void linklist_destory(struct _linklist* self) +{ + assert(self != NULL); + self->clear(self); +} + +static bool linklist_push(struct _linklist* self, void* obj) +{ + assert(self != NULL); + assert(obj != NULL); + + struct _linklist_node* new_node = linklist_new_node(obj, self->_obj_size); + if(new_node == NULL) + { + return false; + } + + if(self->empty(self)) + { + self->_front = new_node; + self->_back = new_node; + } + else + { + self->_back->next = new_node; + self->_back = new_node; + } + self->_size++; + + return true; +} + +static bool linklist_pop(struct _linklist* self, void* obj) +{ + assert(self != NULL); + if (self->empty(self)) + { + return false; + } + struct _linklist_node* node = self->_front; + if(obj != NULL) + { + memmove(obj, node->obj, self->_obj_size); + } + self->_front = node->next; + self->_size--; + + linklist_node_free(&node); + return true; +} + +static bool linklist_back(struct _linklist* self, void* obj) +{ + assert(self != NULL); + if (self->empty(self)) + { + return false; + } + memmove(obj, self->_back->obj, self->_obj_size); + return true; +} + +static bool linklist_front(struct _linklist* self, void* obj) +{ + assert(self != NULL); + if (self->empty(self)) + { + return false; + } + memmove(obj, self->_front->obj, self->_obj_size); + return true; +} + +static bool linklist_empty(struct _linklist* self) +{ + assert(self != NULL); + assert(self->size != NULL); + return self->size(self) == 0; +} + +static bool linklist_full(struct _linklist* self) +{ + assert(self != NULL); + assert(self->size != NULL); + assert(self->capacity != NULL); + return self->size(self) == self->capacity(self); +} + +static void linklist_print(struct _linklist* self) +{ + assert(self != NULL); + + struct _linklist_node * node = self->_front; + while (node) + { + self->print_obj(node->obj); + node = node->next; + } +} + + +static bool linklist_init(struct _linklist * self, uint32_t obj_size) +{ + assert(self != NULL); + if(self == NULL || obj_size == 0) + { + return false; + } + + // -------------------- private -------------------- + self->_size = 0; + self->_obj_size = obj_size; + self->_capacity = UINT32_MAX; + self->_ratio = 1; + + // front & back pointer init + self->_front = NULL; + self->_back = NULL; + + // base + self->_destory = linklist_destory; + + // -------------------- public -------------------- + // kernel + self->push = linklist_push; + self->pop = linklist_pop; + self->back = linklist_back; + self->front = linklist_front; + self->empty = linklist_empty; + self->full = linklist_full; + + // base + self->size = linklist_size; + self->capacity = linklist_capacity; + self->clear = linklist_clear; + + // iter + // self->iter = linklist_iter; + + // -------------------- default -------------------- + self->print_obj = default_print_obj; + + // -------------------- debug -------------------- + self->print = linklist_print; + + return true; +} + +linklist_t linklist_new(uint32_t obj_size) +{ + struct _linklist * linklist = NULL; + linklist = (struct _linklist *)calloc(1, sizeof(struct _linklist)); + if(linklist == NULL) + { + return NULL; + } + + if(linklist_init(linklist, obj_size) != true) + { + free(linklist); + return NULL; + } + return linklist; +} + +void linklist_free(linklist_t* linklist) +{ + assert(linklist != NULL); + if(linklist != NULL && *linklist != NULL) + { + if((*linklist)->_destory != NULL) + { + (*linklist)->_destory(*linklist); + } + free(*linklist); + *linklist = NULL; + } +} diff --git a/test/test.c b/test/test.c index 8a87612..04bc7a9 100644 --- a/test/test.c +++ b/test/test.c @@ -79,6 +79,7 @@ int main(int argc, char const *argv[]) UNITY_BEGIN(); TEST_ADD(test_darray); + TEST_ADD(test_linklist); TEST_ADD(test_queue); TEST_ADD(test_stack); diff --git a/test/test.h b/test/test.h index da69ff3..dd3efd2 100644 --- a/test/test.h +++ b/test/test.h @@ -43,11 +43,13 @@ void print_str(void* obj); * */ void test_darray(void); +void test_linklist(void); + +void test_deque(void); void test_queue(void); void test_stack(void); void test_list(void); -void test_deque(void); void test_tree(void); void test_heap(void); void test_graph(void); diff --git a/test/test_darray.c b/test/test_darray.c index 7cfd81c..47dc099 100644 --- a/test/test_darray.c +++ b/test/test_darray.c @@ -51,7 +51,6 @@ static void test_darray_insert(void) darray_free(&darray); } - static void test_darray_append(void) { int temp = 0; @@ -79,6 +78,204 @@ static void test_darray_append(void) darray_free(&darray); } +static void test_darray_remove(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; + + darray_t darray = darray_new(sizeof(int), len); + darray->compare = compare_num; + + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(darray->append(darray, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, darray->size(darray)); + } + + TEST_ASSERT_TRUE(darray->remove(darray, len - 1, &temp)); + TEST_ASSERT_EQUAL_INT(data[len - 1], temp); + TEST_ASSERT_FALSE(darray->full(darray)); + + for (i = 0; i < len - 2; i++) + { + TEST_ASSERT_TRUE(darray->remove(darray, 1, &temp)); + TEST_ASSERT_EQUAL_INT(data[i + 1], temp); + + TEST_ASSERT_FALSE(darray->full(darray)); + } + + TEST_ASSERT_TRUE(darray->remove(darray, 0, &temp)); + TEST_ASSERT_EQUAL_INT(data[0], temp); + TEST_ASSERT_TRUE(darray->empty(darray)); + darray_free(&darray); +} + +static void test_darray_pop(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; + + darray_t darray = darray_new(sizeof(int), len); + darray->compare = compare_num; + + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(darray->append(darray, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, darray->size(darray)); + } + TEST_ASSERT_TRUE(darray->full(darray)); + + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(darray->pop(darray, &temp)); + TEST_ASSERT_EQUAL_INT(data[len -1 - i], temp); + + TEST_ASSERT_FALSE(darray->full(darray)); + } + TEST_ASSERT_TRUE(darray->empty(darray)); + darray_free(&darray); +} + +static void test_darray_set(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; + + darray_t darray = darray_new(sizeof(int), len); + darray->compare = compare_num; + + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(darray->append(darray, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, darray->size(darray)); + + uint32_t index = darray->size(darray) - 1; + TEST_ASSERT_TRUE(darray->get(darray, index, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + } + + temp = 0x11; + TEST_ASSERT_TRUE(darray->set(darray, 0, &temp)); + temp = 0x22; + TEST_ASSERT_TRUE(darray->set(darray, 5, &temp)); + temp = 0x33; + TEST_ASSERT_TRUE(darray->set(darray, 9, &temp)); + + TEST_ASSERT_TRUE(darray->get(darray, 0, &temp)); + TEST_ASSERT_EQUAL_INT(0x11, temp); + TEST_ASSERT_TRUE(darray->get(darray, 5, &temp)); + TEST_ASSERT_EQUAL_INT(0x22, temp); + TEST_ASSERT_TRUE(darray->get(darray, 9, &temp)); + TEST_ASSERT_EQUAL_INT(0x33, temp); + + darray_free(&darray); +} + +static void test_darray_resize(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; + + darray_t darray = darray_new(sizeof(int), 8); + darray->compare = compare_num; + + TEST_ASSERT_EQUAL_INT(8, darray->capacity(darray)); + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(darray->append(darray, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, darray->size(darray)); + } + TEST_ASSERT_EQUAL_INT(16, darray->capacity(darray)); + darray_free(&darray); +} + +static void test_darray_clear(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; + + darray_t darray = darray_new(sizeof(int), len); + darray->compare = compare_num; + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(darray->append(darray, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, darray->size(darray)); + } + TEST_ASSERT_TRUE(darray->full(darray)); + + TEST_ASSERT_TRUE(darray->clear(darray)); + TEST_ASSERT_TRUE(darray->empty(darray)); + + darray_free(&darray); +} + +static void test_darray_dynamic(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; + + darray_t darray = darray_new(sizeof(int), 8); + darray->compare = compare_num; + + TEST_ASSERT_TRUE(darray->dynamic(darray)); + darray->dynamic_enable(darray, false); + TEST_ASSERT_FALSE(darray->dynamic(darray)); + + TEST_ASSERT_EQUAL_INT(8, darray->capacity(darray)); + for(i = 0; i < 8; i++) + { + TEST_ASSERT_TRUE(darray->append(darray, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, darray->size(darray)); + } + TEST_ASSERT_FALSE(darray->append(darray, &data[i])); + darray_free(&darray); +} + +static void test_darray_index(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; + + darray_t darray = darray_new(sizeof(int), len); + darray->compare = compare_num; + for(i = 0; i < len; i++) + { + darray->append(darray, &data[i]); + } + + temp = 1; + TEST_ASSERT_EQUAL_INT(0, darray->index(darray, &temp)); + TEST_ASSERT_TRUE(darray->contains(darray, &temp)); + + temp = 5; + TEST_ASSERT_EQUAL_INT(4, darray->index(darray, &temp)); + TEST_ASSERT_TRUE(darray->contains(darray, &temp)); + + temp = 10; + TEST_ASSERT_EQUAL_INT(9, darray->index(darray, &temp)); + TEST_ASSERT_TRUE(darray->contains(darray, &temp)); + + temp = 11; + TEST_ASSERT_EQUAL_INT(-1, darray->index(darray, &temp)); + TEST_ASSERT_FALSE(darray->contains(darray, &temp)); + + darray_free(&darray); +} + void test_darray(void) { UnitySetTestFile(__FILE__); @@ -86,4 +283,12 @@ void test_darray(void) RUN_TEST(test_darray_new); RUN_TEST(test_darray_insert); RUN_TEST(test_darray_append); + RUN_TEST(test_darray_remove); + RUN_TEST(test_darray_pop); + + RUN_TEST(test_darray_set); + RUN_TEST(test_darray_resize); + RUN_TEST(test_darray_clear); + RUN_TEST(test_darray_dynamic); + RUN_TEST(test_darray_index); } diff --git a/test/test_linklist.c b/test/test_linklist.c new file mode 100644 index 0000000..1296c12 --- /dev/null +++ b/test/test_linklist.c @@ -0,0 +1,321 @@ +/** + * @file test_linklist.c + * @author wenjf (orig5826@163.com) + * @brief + * @version 0.1 + * @date 2026-05-11 + * + * @copyright Copyright (c) 2026 + * + */ +#include "test.h" + +static void test_linklist_new(void) +{ + linklist_t linklist = NULL; + linklist = linklist_new(sizeof(int)); + TEST_ASSERT_NOT_NULL(linklist); + linklist_free(&linklist); + + TEST_ASSERT_NULL(linklist_new(0)); + + // ------------------------------ + TEST_ASSERT_NULL(linklist); + linklist_free(&linklist); +} + +static void test_linklist_push(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; + + linklist_t linklist = NULL; + + // ------------------------------ + linklist = linklist_new(sizeof(int)); + + TEST_ASSERT_TRUE(linklist->empty(linklist)); + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(linklist->push(linklist, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, linklist->size(linklist)); + + TEST_ASSERT_TRUE(linklist->front(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[0], temp); + + TEST_ASSERT_TRUE(linklist->back(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + + TEST_ASSERT_FALSE(linklist->empty(linklist)); + } + linklist_free(&linklist); +} + +static void test_linklist_pop(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; + + linklist_t linklist = NULL; + + // ------------------------------ + linklist = linklist_new(sizeof(int)); + + for(i = 0; i < len; i++) + { + linklist->push(linklist, &data[i]); + } + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(linklist->front(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + + TEST_ASSERT_TRUE(linklist->back(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[len - 1], temp); + + TEST_ASSERT_TRUE(linklist->pop(linklist, &temp)); + + if (!linklist->empty(linklist)) + { + TEST_ASSERT_TRUE(linklist->front(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[i + 1], temp); + + TEST_ASSERT_TRUE(linklist->back(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[len - 1], temp); + } + else + { + TEST_ASSERT_FALSE(linklist->front(linklist, &temp)); + TEST_ASSERT_FALSE(linklist->back(linklist, &temp)); + } + + TEST_ASSERT_FALSE(linklist->full(linklist)); + } + TEST_ASSERT_TRUE(linklist->empty(linklist)); + TEST_ASSERT_FALSE(linklist->pop(linklist, &temp)); + linklist_free(&linklist); +} + +static void test_linklist_clear(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; + + linklist_t linklist = NULL; + + // ------------------------------ + linklist = linklist_new(sizeof(int)); + + for(i = 0; i < len; i++) + { + linklist->push(linklist, &data[i]); + } + TEST_ASSERT_TRUE(linklist->clear(linklist)); + for(i = 0; i < len; i++) + { + linklist->push(linklist, &data[i]); + } + TEST_ASSERT_FALSE(linklist->empty(linklist)); + TEST_ASSERT_TRUE(linklist->clear(linklist)); + TEST_ASSERT_TRUE(linklist->empty(linklist)); + TEST_ASSERT_TRUE(linklist->clear(linklist)); + linklist_free(&linklist); +} + + +static void test_linklist_num(void) +{ + uint32_t i = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + int temp = 0; + uint32_t len = sizeof(data) / sizeof(data[0]); + + linklist_t linklist = NULL; + linklist = linklist_new(sizeof(int)); + TEST_ASSERT_NOT_NULL(linklist); + + linklist->print_obj = print_num; + + TEST_ASSERT_TRUE(linklist->clear(linklist)); + + TEST_ASSERT_FALSE(linklist->front(linklist, &temp)); + TEST_ASSERT_FALSE(linklist->back(linklist, &temp)); + + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(linklist->push(linklist, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, linklist->size(linklist)); + + TEST_ASSERT_TRUE(linklist->front(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[0], temp); + + TEST_ASSERT_TRUE(linklist->back(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + } + + TEST_ASSERT_FALSE(linklist->empty(linklist)); + TEST_ASSERT_TRUE(linklist->clear(linklist)); + TEST_ASSERT_TRUE(linklist->empty(linklist)); + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(linklist->push(linklist, &data[i])); + } + + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(linklist->front(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + + TEST_ASSERT_TRUE(linklist->back(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[len - 1], temp); + + TEST_ASSERT_TRUE(linklist->pop(linklist, &temp)); + + if (!linklist->empty(linklist)) + { + TEST_ASSERT_TRUE(linklist->front(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[i + 1], temp); + + TEST_ASSERT_TRUE(linklist->back(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[len - 1], temp); + } + } + TEST_ASSERT_TRUE(linklist->empty(linklist)); + TEST_ASSERT_FALSE(linklist->pop(linklist, &temp)); + + linklist_free(&linklist); + TEST_ASSERT_NULL(linklist); +} + +static void test_linklist_struct(void) +{ + uint32_t i = 0; + struct _student data[] = { + {"zhao", 1001}, {"qian", 1002}, {"sun", 1003}, {"li", 1004}, + "zhou", 1005, "wu", 1006, "zheng", 1007, "wang", 1008, + }; + struct _student temp; + uint32_t len = sizeof(data) / sizeof(data[0]) - 1; + + linklist_t linklist = linklist_new(sizeof(struct _student)); + TEST_ASSERT_NOT_NULL(linklist); + + linklist->print_obj = print_struct; + + TEST_ASSERT_TRUE(linklist->clear(linklist)); + + TEST_ASSERT_FALSE(linklist->front(linklist, &temp)); + TEST_ASSERT_FALSE(linklist->back(linklist, &temp)); + + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(linklist->push(linklist, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, linklist->size(linklist)); + + TEST_ASSERT_TRUE(linklist->front(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[0].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[0].name, temp.name); + + TEST_ASSERT_TRUE(linklist->back(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[i].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[i].name, temp.name); + } + + TEST_ASSERT_FALSE(linklist->empty(linklist)); + TEST_ASSERT_TRUE(linklist->clear(linklist)); + TEST_ASSERT_TRUE(linklist->empty(linklist)); + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(linklist->push(linklist, &data[i])); + } + + // while (!linklist->empty(linklist)) + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(linklist->front(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[i].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[i].name, temp.name); + + TEST_ASSERT_TRUE(linklist->back(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[len - 1].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[len - 1].name, temp.name); + + TEST_ASSERT_TRUE(linklist->pop(linklist, &temp)); + + if (!linklist->empty(linklist)) + { + TEST_ASSERT_TRUE(linklist->front(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[i + 1].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[i + 1].name, temp.name); + + TEST_ASSERT_TRUE(linklist->back(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[len - 1].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[len - 1].name, temp.name); + } + } + TEST_ASSERT_TRUE(linklist->empty(linklist)); + TEST_ASSERT_FALSE(linklist->pop(linklist, &temp)); + linklist_free(&linklist); + TEST_ASSERT_NULL(linklist); +} + +#if 0 +static void test_linklist_iter(void) +{ + uint32_t i = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + int temp = 0; + uint32_t len = sizeof(data) / sizeof(data[0]); + + linklist_t linklist = NULL; + linklist = linklist_new(sizeof(int)); + TEST_ASSERT_NOT_NULL(linklist); + linklist->print_obj = print_num; + + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(linklist->push(linklist, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, linklist->size(linklist)); + + TEST_ASSERT_TRUE(linklist->front(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[0], temp); + + TEST_ASSERT_TRUE(linklist->back(linklist, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + } + + iterator_t iter = linklist->iter(linklist); + i = 0; + while(iter->hasnext(iter)) + { + temp = *(int *)iter->next(iter); + // printf("%d ", temp); + TEST_ASSERT_EQUAL_INT(data[i], temp); + i++; + } + + linklist_free(&linklist); + TEST_ASSERT_NULL(linklist); +} +#endif + +void test_linklist(void) +{ + UnitySetTestFile(__FILE__); + + RUN_TEST(test_linklist_new); + RUN_TEST(test_linklist_push); + RUN_TEST(test_linklist_pop); + RUN_TEST(test_linklist_clear); + + RUN_TEST(test_linklist_num); + RUN_TEST(test_linklist_struct); + + // RUN_TEST(test_linklist_iter); +}