From 7741ac3f409d7a0a4a2e25de14714d9f59340cdf Mon Sep 17 00:00:00 2001 From: jf-home Date: Fri, 15 May 2026 01:10:07 +0800 Subject: [PATCH] =?UTF-8?q?refactor(stack):=20=E7=BB=9F=E4=B8=80=E6=9E=84?= =?UTF-8?q?=E9=80=A0=E5=87=BD=E6=95=B0=E5=B9=B6=E6=B7=BB=E5=8A=A0=E6=89=A9?= =?UTF-8?q?=E5=AE=B9=E4=B8=8E=E6=BB=A1=E6=A0=88=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +- demo/demo_stack.c | 6 +- include/stack.h | 6 +- perf/perf_stack.c | 3 +- src/graph.c | 2 +- src/stack.c | 40 ++- src/tree.c | 6 +- test/test_stack.c | 686 ++++++++++++++++++++++------------------------ 8 files changed, 363 insertions(+), 391 deletions(-) diff --git a/README.md b/README.md index 59bea2c..2ddc384 100644 --- a/README.md +++ b/README.md @@ -156,9 +156,12 @@ bool find_(const void* obj); // [图:顶点、边] 查找元素 - new features - add darray/ringbuf/linlist/dlinklist - add estack/equeue for embedded + - darray add function: search/sort + - add algo: sort and search - refactor: - deque base on ringbuf - - stack base on deque + - stack base on deque + - queue base on deque ### Unicstl 0.0.02 (2025-05-06) - new features diff --git a/demo/demo_stack.c b/demo/demo_stack.c index f24044c..e771d17 100644 --- a/demo/demo_stack.c +++ b/demo/demo_stack.c @@ -17,7 +17,7 @@ static void demo_stack_num(void) int temp = 0; size_t len = sizeof(data) / sizeof(data[0]); - stack_t stack = stack_new(sizeof(int)); + stack_t stack = stack_new(sizeof(int), len); stack->print_obj = print_num; printf("\n\n----- demo_stack_num -----\n"); @@ -77,7 +77,7 @@ static void demo_stack_char(void) char temp = 0; size_t len = sizeof(data) / sizeof(data[0]) - 1; - stack_t stack = stack_new2(sizeof(char), 64); + stack_t stack = stack_new(sizeof(char), 64); stack->print_obj = print_char; printf("\n\n----- demo_stack_char -----\n"); @@ -139,7 +139,7 @@ static void demo_stack_struct(void) struct _student temp = { 0 }; size_t len = sizeof(data) / sizeof(data[0]); - stack_t stack = stack_new(sizeof(struct _student)); + stack_t stack = stack_new(sizeof(struct _student), len); stack->print_obj = print_struct; printf("\n\n----- demo_stack_struct -----\n"); diff --git a/include/stack.h b/include/stack.h index 9e0fb07..e417829 100644 --- a/include/stack.h +++ b/include/stack.h @@ -29,9 +29,11 @@ struct _stack bool (*peek)(struct _stack* self, void* obj); // base + size_t (*resize)(struct _stack* self, size_t new_size); size_t (*size)(struct _stack* self); size_t (*capacity)(struct _stack* self); bool (*empty)(struct _stack* self); + bool (*full)(struct _stack* self); bool (*clear)(struct _stack* self); // iter @@ -44,9 +46,7 @@ struct _stack typedef struct _stack* stack_t; // create and free stack -stack_t stack_new2(size_t obj_size, size_t capacity); +stack_t stack_new(size_t obj_size, size_t capacity); void stack_free(stack_t* stack); -#define stack_new(obj_size) stack_new2(obj_size, 16) - #endif // _STACK_H_ diff --git a/perf/perf_stack.c b/perf/perf_stack.c index 2a7e721..680f391 100644 --- a/perf/perf_stack.c +++ b/perf/perf_stack.c @@ -14,8 +14,7 @@ static stack_t stack = NULL; void perf_stack_new(void) { - // stack = stack_new2(g_test_obj.obj_size, g_test_obj.capacity); - stack = stack_new(g_test_obj.obj_size); + stack = stack_new(g_test_obj.obj_size, g_test_obj.capacity); } void perf_stack_push(void) diff --git a/src/graph.c b/src/graph.c index 57214f8..67f1a26 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1004,7 +1004,7 @@ static bool graph_init(struct _graph *self, size_t obj_size) self->_capacity = UINT32_MAX; self->_ratio = 1; - self->stack = stack_new(sizeof(struct _graph_node *)); + self->stack = stack_new(sizeof(struct _graph_node *), 16); if (self->stack == NULL) { return false; diff --git a/src/stack.c b/src/stack.c index 2a2fe8e..69bea75 100644 --- a/src/stack.c +++ b/src/stack.c @@ -37,6 +37,15 @@ static bool stack_peek(struct _stack* self, void* obj) return deque->back(deque, obj); } +static size_t stack_resize(struct _stack* self, size_t capaticy) +{ + unicstl_assert(self != NULL); + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; + + return deque->resize(deque, capaticy); +} + static size_t stack_size(struct _stack* self) { unicstl_assert(self != NULL); @@ -46,6 +55,15 @@ static size_t stack_size(struct _stack* self) return deque->size(deque); } +static size_t stack_capacity(struct _stack* self) +{ + unicstl_assert(self != NULL); + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; + + return deque->capacity(deque); +} + static bool stack_empty(struct _stack* self) { unicstl_assert(self != NULL); @@ -55,13 +73,13 @@ static bool stack_empty(struct _stack* self) return deque->empty(deque); } -static size_t stack_capacity(struct _stack* self) +static bool stack_full(struct _stack* self) { unicstl_assert(self != NULL); unicstl_assert(self->_deque != NULL); deque_t deque = self->_deque; - return deque->capacity(deque); + return deque->full(deque); } static bool stack_clear(struct _stack* self) @@ -129,12 +147,9 @@ iterator_t stack_iter(struct _stack* self) static bool stack_init(struct _stack* self, size_t obj_size, size_t capacity) { - // unicstl_assert(self != NULL); - if(self == NULL || obj_size == 0 || capacity == 0) - { - return false; - } - + unicstl_assert(self != NULL); + unicstl_assert(obj_size != 0); + // -------------------- private -------------------- self->_deque = deque_new(obj_size, capacity); if(self->_deque == NULL) @@ -142,9 +157,6 @@ static bool stack_init(struct _stack* self, size_t obj_size, size_t capacity) return false; } - self->_iter.next = stack_iter_next; - self->_iter.hasnext = stack_iter_hasnext; - self->_destory = stack_destory; // -------------------- public -------------------- @@ -152,11 +164,13 @@ static bool stack_init(struct _stack* self, size_t obj_size, size_t capacity) self->push = stack_push; self->pop = stack_pop; self->peek = stack_peek; - self->empty = stack_empty; // base + self->resize = stack_resize; self->size = stack_size; self->capacity = stack_capacity; + self->empty = stack_empty; + self->full = stack_full; self->clear = stack_clear; // iter @@ -171,7 +185,7 @@ static bool stack_init(struct _stack* self, size_t obj_size, size_t capacity) return true; } -stack_t stack_new2(size_t obj_size, size_t capacity) +stack_t stack_new(size_t obj_size, size_t capacity) { stack_t stack = NULL; stack = (struct _stack*)calloc(1, sizeof(struct _stack)); diff --git a/src/tree.c b/src/tree.c index b75959f..9ce34e9 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1323,7 +1323,7 @@ static iterator_t tree_iter(struct _tree* self, enum _tree_order order) struct _tree_node* node = self->_root; self->stack->clear(self->stack); - stack_t stack = stack_new(sizeof(struct _tree_node*)); + stack_t stack = stack_new(sizeof(struct _tree_node*), self->size(self)); if (iter->_order == ORDER_POST) { while (!stack->empty(stack) || node != NULL) @@ -1388,7 +1388,7 @@ static bool tree_avl_init(struct _tree* self, size_t obj_size) self->_root = NULL; - self->stack = stack_new(sizeof(struct _tree_node*)); + self->stack = stack_new(sizeof(struct _tree_node*), self->size(self)); if (self->stack == NULL) { return false; @@ -1440,7 +1440,7 @@ static bool tree_rb_init(struct _tree* self, size_t obj_size) self->_root = NULL; - self->stack = stack_new(sizeof(struct _tree_node*)); + self->stack = stack_new(sizeof(struct _tree_node*), self->size(self)); if (self->stack == NULL) { return false; diff --git a/test/test_stack.c b/test/test_stack.c index 30d4f3b..e5f1d21 100644 --- a/test/test_stack.c +++ b/test/test_stack.c @@ -3,158 +3,85 @@ * @author wenjf (Orig5826@163.com) * @brief * @version 0.1 - * @date 2024-08-27 + * @date 2026-05-15 * - * @copyright Copyright (c) 2024 + * @copyright Copyright (c) 2026 * */ #include "test.h" - static void test_stack_new(void) { - stack_t stack = NULL; - // ------------------------------ - stack = stack_new(sizeof(int)); - TEST_ASSERT_NOT_NULL(stack); - stack_free(&stack); - TEST_ASSERT_NULL(stack); + // [invalid param] if obj_size==0, unit test is not needed. because assert will be triggered. + // TEST_ASSERT_NULL(stack_new(0, 0)); + // TEST_ASSERT_NULL(stack_new(0, 1)); - // ------------------------------ - stack = stack_new2(sizeof(int), 10); + stack_t stack = stack_new(sizeof(int), 10); TEST_ASSERT_NOT_NULL(stack); stack_free(&stack); TEST_ASSERT_NULL(stack); - - // ------------------------------ - stack_free(&stack); - TEST_ASSERT_NULL(stack); +} + +static void test_stack_new_lazy(void) +{ + stack_t stack = stack_new(sizeof(int), 0); + TEST_ASSERT_NOT_NULL(stack); + TEST_ASSERT_EQUAL_size_t(0, stack->capacity(stack)); + + int temp = 0; + TEST_ASSERT_TRUE(stack->push(stack, &temp)); + TEST_ASSERT_EQUAL_size_t(UNICSTL_CAPACITY_INIT, stack->capacity(stack)); + stack_free(&stack); } static void test_stack_push(void) { - int temp = 0; - int data[] = { 1,2,3,4,5,6,7,8,9,10 }; - size_t len = sizeof(data) / sizeof(data[0]); size_t i = 0; + int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int temp = 0; + size_t len = sizeof(data) / sizeof(data[0]); - stack_t stack = NULL; + stack_t stack = stack_new(sizeof(int), len); + stack->print_obj = print_num; - // ------------------------------ - stack = stack_new(sizeof(int)); - TEST_ASSERT_TRUE(stack->empty(stack)); - for(i = 0; i < len; i++) + for (i = 0; i < len; i++) { TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); TEST_ASSERT_TRUE(stack->peek(stack, &temp)); TEST_ASSERT_EQUAL_INT(data[i], temp); - TEST_ASSERT_FALSE(stack->empty(stack)); - } - stack_free(&stack); - - // ------------------------------ - stack = stack_new2(sizeof(int), len); - TEST_ASSERT_TRUE(stack->empty(stack)); - for(i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(stack->push(stack, &data[i])); TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); - - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[i], temp); - - TEST_ASSERT_FALSE(stack->empty(stack)); } - stack_free(&stack); + TEST_ASSERT_TRUE(stack->push(stack, &data[0])); + TEST_ASSERT_EQUAL_INT(len + 1, stack->size(stack)); - // ------------------------------ - // if capacity is less than data len - // stack = stack_new2(sizeof(int), len - 2); - // for(i = 0; i < len; i++) - // { - // TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - // TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); - // } + stack_free(&stack); +} + +static void test_stack_push_invalid(void) +{ + stack_t stack = stack_new(sizeof(int), 1); + TEST_ASSERT_FALSE(stack->push(stack, NULL)); stack_free(&stack); } static void test_stack_pop(void) { - int temp = 0; - int data[] = { 1,2,3,4,5,6,7,8,9,10 }; - size_t len = sizeof(data) / sizeof(data[0]); size_t i = 0; + int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int temp = 0; + size_t len = sizeof(data) / sizeof(data[0]); - stack_t stack = NULL; + stack_t stack = stack_new(sizeof(int), len); + stack->print_obj = print_num; -#if 0 - // ------------------------------ - stack = stack_new(sizeof(int)); - for(i = 0; i < len; i++) + TEST_ASSERT_FALSE(stack->peek(stack, &temp)); + for (i = 0; i < len; i++) { stack->push(stack, &data[i]); } - for (i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); - TEST_ASSERT_TRUE(stack->pop(stack, &temp)); - - if (!stack->empty(stack)) - { - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); - } - else - { - TEST_ASSERT_FALSE(stack->peek(stack, &temp)); - } - } - TEST_ASSERT_TRUE(stack->empty(stack)); - TEST_ASSERT_FALSE(stack->pop(stack, &temp)); - stack_free(&stack); -#endif - - // ------------------------------ - stack = stack_new2(sizeof(int), len); - for(i = 0; i < len; i++) - { - stack->push(stack, &data[i]); - } - for (i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); - - TEST_ASSERT_TRUE(stack->pop(stack, &temp)); - - if (!stack->empty(stack)) - { - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); - } - else - { - TEST_ASSERT_FALSE(stack->peek(stack, &temp)); - } - } - TEST_ASSERT_TRUE(stack->empty(stack)); - TEST_ASSERT_FALSE(stack->pop(stack, &temp)); - stack_free(&stack); - - // ------------------------------ - // if capacity is less than data len - stack = stack_new2(sizeof(int), len - 2); - // for(i = 0; i < len; i++) - // { - // TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - // TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); - // } - // size_t capacity = stack->capacity(stack); for (i = 0; i < len; i++) { if (!stack->empty(stack)) @@ -173,128 +100,292 @@ static void test_stack_pop(void) } else { - TEST_ASSERT_FALSE(stack->pop(stack, &temp)); + TEST_ASSERT_FALSE(stack->peek(stack, &temp)); + } + } + TEST_ASSERT_TRUE(stack->empty(stack)); + + // ---------- no return ---------- + for (i = 0; i < 2; i++) + { + stack->push(stack, &data[i]); + } + TEST_ASSERT_TRUE(stack->pop(stack, NULL)); + TEST_ASSERT_TRUE(stack->pop(stack, NULL)); + TEST_ASSERT_FALSE(stack->pop(stack, NULL)); + + stack_free(&stack); +} + +static void test_stack_peek(void) +{ + size_t i = 0; + int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int temp = 0; + size_t len = sizeof(data) / sizeof(data[0]); + + stack_t stack = stack_new(sizeof(int), len); + + TEST_ASSERT_FALSE(stack->peek(stack, &temp)); + for (i = 0; i < len; i++) + { + stack->push(stack, &data[i]); + } + for (i = 0; i < len; i++) + { + stack->pop(stack, &temp); + + if (i != len - 1) + { + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); + } + else + { TEST_ASSERT_FALSE(stack->peek(stack, &temp)); } } stack_free(&stack); } -static void test_stack_clear(void) +static void test_stack_peek_invalid(void) +{ + stack_t stack = stack_new(sizeof(int), 1); + TEST_ASSERT_FALSE(stack->peek(stack, NULL)); + stack_free(&stack); +} + +static void test_stack_iter(void) +{ + size_t i = 0; + int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int temp = 0; + size_t len = sizeof(data) / sizeof(data[0]); + + stack_t stack = stack_new(sizeof(int), len); + stack->print_obj = print_num; + + for (i = 0; i < len; i++) + { + stack->push(stack, &data[i]); + } + + iterator_t iter = stack->iter(stack); + i = 0; + TEST_ASSERT_TRUE(iter->hasnext(iter)); + while(iter->hasnext(iter)) + { + temp = *(int *)iter->next(iter); + TEST_ASSERT_EQUAL_INT(data[i], temp); + i++; + } + TEST_ASSERT_EQUAL_INT(len, i); + + stack_free(&stack); +} + +static void test_stack_resize(void) { int temp = 0; int data[] = { 1,2,3,4,5,6,7,8,9,10 }; size_t len = sizeof(data) / sizeof(data[0]); size_t i = 0; - stack_t stack = NULL; + stack_t stack = stack_new(sizeof(int), len); - // ------------------------------ - stack = stack_new(sizeof(int)); - for(i = 0; i < len; i++) - { - stack->push(stack, &data[i]); - } - TEST_ASSERT_TRUE(stack->clear(stack)); - for(i = 0; i < len; i++) - { - stack->push(stack, &data[i]); - } - TEST_ASSERT_FALSE(stack->empty(stack)); - TEST_ASSERT_TRUE(stack->clear(stack)); - TEST_ASSERT_TRUE(stack->empty(stack)); - TEST_ASSERT_TRUE(stack->clear(stack)); - stack_free(&stack); + TEST_ASSERT_EQUAL_INT(len, stack->capacity(stack)); + TEST_ASSERT_TRUE(stack->resize(stack, 16)); + TEST_ASSERT_EQUAL_INT(16, stack->capacity(stack)); - // ------------------------------ - stack = stack_new2(sizeof(int), len); - TEST_ASSERT_TRUE(stack->clear(stack)); for(i = 0; i < len; i++) { stack->push(stack, &data[i]); } - TEST_ASSERT_FALSE(stack->empty(stack)); - TEST_ASSERT_TRUE(stack->clear(stack)); - TEST_ASSERT_TRUE(stack->empty(stack)); - TEST_ASSERT_TRUE(stack->clear(stack)); + TEST_ASSERT_EQUAL_INT(16, stack->capacity(stack)); + TEST_ASSERT_EQUAL_INT(len, stack->size(stack)); + + TEST_ASSERT_TRUE(stack->resize(stack, 8)); + TEST_ASSERT_EQUAL_INT(8, stack->capacity(stack)); + TEST_ASSERT_EQUAL_INT(8, stack->size(stack)); + + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[7], temp); + + for(i = 0; i < len; i++) + { + if(i < 8) + { + TEST_ASSERT_TRUE(stack->pop(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[7 - i], temp); + } + else + { + TEST_ASSERT_FALSE(stack->pop(stack, &temp)); + } + } + TEST_ASSERT_EQUAL_INT(8, stack->capacity(stack)); + TEST_ASSERT_EQUAL_INT(0, stack->size(stack)); + stack_free(&stack); } -static void test_stack_num(void) +static void test_stack_resize_invalid(void) { - size_t i = 0; - int data[10] = { 1,2,3,4,5,6,7,8,9,10 }; int temp = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; size_t len = sizeof(data) / sizeof(data[0]); + size_t i = 0; - stack_t stack = stack_new(sizeof(int)); - stack->print_obj = print_num; + stack_t stack = stack_new(sizeof(int), len); + + TEST_ASSERT_EQUAL_INT(len, stack->capacity(stack)); + TEST_ASSERT_FALSE(stack->resize(stack, 0)); + TEST_ASSERT_FALSE(stack->resize(stack, -1)); - TEST_ASSERT_FALSE(stack->peek(stack, &temp)); - // TEST_ASSERT_TRUE(stack->clear(stack)); - for (i = 0; i < len; i++) + stack_free(&stack); +} + +static void test_stack_resize_edge(void) +{ + stack_t stack = stack_new(sizeof(int), 10); + + TEST_ASSERT_EQUAL_INT(10, stack->capacity(stack)); + TEST_ASSERT_TRUE(stack->resize(stack, 10)); + TEST_ASSERT_EQUAL_INT(10, stack->capacity(stack)); + + stack_free(&stack); +} + +static void test_stack_dynamic(void) +{ + int temp = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + + size_t i = 0; + size_t len = 2; + stack_t stack = stack_new(sizeof(int), len); + + for(i = 0; i < len; i++) { TEST_ASSERT_TRUE(stack->push(stack, &data[i])); TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); - + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); TEST_ASSERT_EQUAL_INT(data[i], temp); - } - TEST_ASSERT_FALSE(stack->empty(stack)); - TEST_ASSERT_TRUE(stack->clear(stack)); - TEST_ASSERT_TRUE(stack->empty(stack)); - for (i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - } - - for (i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); - - TEST_ASSERT_TRUE(stack->pop(stack, &temp)); - - if (!stack->empty(stack)) + TEST_ASSERT_EQUAL_INT(len, stack->capacity(stack)); + if(i < len - 1) { - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); + TEST_ASSERT_FALSE(stack->full(stack)); + } + else + { + TEST_ASSERT_TRUE(stack->full(stack)); + } + } + + len *= 2; + for(; i < len; i++) + { + TEST_ASSERT_TRUE(stack->push(stack, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); + + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + + TEST_ASSERT_EQUAL_INT(len, stack->capacity(stack)); + if(i < len - 1) + { + TEST_ASSERT_FALSE(stack->full(stack)); + } + else + { + TEST_ASSERT_TRUE(stack->full(stack)); + } + } + + len *= 2; + for(; i < len; i++) + { + TEST_ASSERT_TRUE(stack->push(stack, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); + + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + + TEST_ASSERT_EQUAL_INT(len, stack->capacity(stack)); + if(i < len - 1) + { + TEST_ASSERT_FALSE(stack->full(stack)); + } + else + { + TEST_ASSERT_TRUE(stack->full(stack)); } } - TEST_ASSERT_TRUE(stack->empty(stack)); - TEST_ASSERT_FALSE(stack->pop(stack, &temp)); stack_free(&stack); - TEST_ASSERT_NULL(stack); +} + +static void test_stack_status(void) +{ + size_t i = 0; + int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int temp = 0; + size_t len = sizeof(data) / sizeof(data[0]); + + stack_t stack = stack_new(sizeof(int), len); + stack->print_obj = print_num; + + TEST_ASSERT_EQUAL_INT(len, stack->capacity(stack)); + TEST_ASSERT_EQUAL_INT(0, stack->size(stack)); + + TEST_ASSERT_TRUE(stack->empty(stack)); + TEST_ASSERT_FALSE(stack->full(stack)); + + for (i = 0; i < len - 1; i++) + { + TEST_ASSERT_TRUE(stack->push(stack, &data[i])); + + TEST_ASSERT_FALSE(stack->empty(stack)); + TEST_ASSERT_FALSE(stack->full(stack)); + } + TEST_ASSERT_TRUE(stack->push(stack, &data[i])); + TEST_ASSERT_TRUE(stack->full(stack)); + TEST_ASSERT_TRUE(stack->push(stack, &data[i])); + + TEST_ASSERT_TRUE(stack->clear(stack)); + TEST_ASSERT_TRUE(stack->empty(stack)); + TEST_ASSERT_FALSE(stack->full(stack)); + + stack_free(&stack); } static void test_stack_struct(void) { size_t i = 0; struct _student data[] = { - {"zhao", 1001}, {"qian", 1002}, {"sun", 1003}, {"li", 1004}, - "zhou", 1005, "wu", 1006, "zheng", 1007, "wang", 1008, + "zhao", 1001, "qian", 1002, "sun", 1003, "li", 1004, + "zhou", 1005, "wu", 1006, "zheng", 1007, "wang", 1008, + "feng", 1009, "cheng",1010, }; - struct _student temp; - size_t len = sizeof(data) / sizeof(data[0]) - 1; + struct _student temp = {0}; + size_t len = sizeof(data) / sizeof(data[0]); - stack_t stack = stack_new(sizeof(struct _student)); + stack_t stack = stack_new(sizeof(struct _student), len); TEST_ASSERT_NOT_NULL(stack); stack->print_obj = print_struct; - - TEST_ASSERT_FALSE(stack->peek(stack, &temp)); - TEST_ASSERT_TRUE(stack->clear(stack)); + for (i = 0; i < len; i++) { TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); TEST_ASSERT_TRUE(stack->peek(stack, &temp)); TEST_ASSERT_EQUAL_INT(data[i].id, temp.id); TEST_ASSERT_EQUAL_STRING(data[i].name, temp.name); - } + TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); + } TEST_ASSERT_FALSE(stack->empty(stack)); TEST_ASSERT_TRUE(stack->clear(stack)); TEST_ASSERT_TRUE(stack->empty(stack)); @@ -303,121 +394,9 @@ static void test_stack_struct(void) TEST_ASSERT_TRUE(stack->push(stack, &data[i])); } - for(i = 0; i < len; i++) + for (i = 0; i < len + 1; i++) { - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1].id, temp.id); - TEST_ASSERT_EQUAL_STRING(data[stack->size(stack) - 1].name, temp.name); - - TEST_ASSERT_TRUE(stack->pop(stack, &temp)); - - if (!stack->empty(stack)) - { - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1].id, temp.id); - TEST_ASSERT_EQUAL_STRING(data[stack->size(stack) - 1].name, temp.name); - } - } - TEST_ASSERT_TRUE(stack->empty(stack)); - TEST_ASSERT_FALSE(stack->pop(stack, &temp)); - stack_free(&stack); - TEST_ASSERT_NULL(stack); -} - - -static void test_stack2_num(void) -{ - size_t i = 0; - int data[] = { 1,2,3,4,5,6,7,8,9,10 }; - int temp = 0; - size_t len = sizeof(data) / sizeof(data[0]); - size_t capacity = len; - - stack_t stack = NULL; - stack = stack_new2(sizeof(int), capacity); - TEST_ASSERT_NOT_NULL(stack); - stack->print_obj = print_num; - - TEST_ASSERT_FALSE(stack->peek(stack, &temp)); - TEST_ASSERT_TRUE(stack->clear(stack)); - for (i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); - - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[i], temp); - } - - TEST_ASSERT_FALSE(stack->empty(stack)); - TEST_ASSERT_TRUE(stack->clear(stack)); - TEST_ASSERT_TRUE(stack->empty(stack)); - for (i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - } - - for (i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); - - TEST_ASSERT_TRUE(stack->pop(stack, &temp)); - - if (!stack->empty(stack)) - { - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1], temp); - } - } - TEST_ASSERT_TRUE(stack->empty(stack)); - TEST_ASSERT_FALSE(stack->pop(stack, &temp)); - - stack_free(&stack); - TEST_ASSERT_NULL(stack); -} - -#if 0 -static void test_stack2_struct(void) -{ - size_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; - size_t len = sizeof(data) / sizeof(data[0]) - 1; - size_t capacity = len - 2; - - stack_t stack = NULL; - stack = stack_new2(sizeof(struct _student), capacity); - TEST_ASSERT_NOT_NULL(stack); - stack->print_obj = print_struct; - - TEST_ASSERT_FALSE(stack->peek(stack, &temp)); - TEST_ASSERT_TRUE(stack->empty(stack)); - for (i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); - - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1].id, temp.id); - TEST_ASSERT_EQUAL_STRING(data[stack->size(stack) - 1].name, temp.name); - } - - TEST_ASSERT_FALSE(stack->empty(stack)); - TEST_ASSERT_TRUE(stack->clear(stack)); - TEST_ASSERT_TRUE(stack->empty(stack)); - for (i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); - } - - for(i = 0; i < len; i++) - { - if (!stack->empty(stack)) + if(!stack->empty(stack)) { TEST_ASSERT_TRUE(stack->pop(stack, &temp)); } @@ -425,8 +404,8 @@ static void test_stack2_struct(void) { TEST_ASSERT_FALSE(stack->pop(stack, &temp)); } - - if (!stack->empty(stack)) + + if(!stack->empty(stack)) { TEST_ASSERT_TRUE(stack->peek(stack, &temp)); TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1].id, temp.id); @@ -437,102 +416,79 @@ static void test_stack2_struct(void) TEST_ASSERT_FALSE(stack->peek(stack, &temp)); } } - stack_free(&stack); - TEST_ASSERT_NULL(stack); -} -#endif -static void test_stack_iter(void) -{ - size_t i = 0; - int data[] = { 1,2,3,4,5,6,7,8,9,10 }; - int temp = 0; - size_t len = sizeof(data) / sizeof(data[0]); - - stack_t stack = NULL; - stack = stack_new(sizeof(int)); - TEST_ASSERT_NOT_NULL(stack); - stack->print_obj = print_num; - - TEST_ASSERT_FALSE(stack->peek(stack, &temp)); - TEST_ASSERT_TRUE(stack->clear(stack)); for (i = 0; i < len; i++) { TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[i], temp); + TEST_ASSERT_EQUAL_INT(data[stack->size(stack) - 1].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[stack->size(stack) - 1].name, temp.name); + + TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); } - - iterator_t iter = stack->iter(stack); - TEST_ASSERT_NOT_NULL(iter); - i = 0; - while(iter->hasnext(iter)) - { - temp = *(int *)iter->next(iter); - // printf("%d ", temp); - TEST_ASSERT_EQUAL_INT(data[i], temp); - i++; - } - - stack_free(&stack); - TEST_ASSERT_NULL(stack); -} - -static void test_stack2_iter(void) -{ - size_t i = 0; - int data[] = { 1,2,3,4,5,6,7,8,9,10 }; - int temp = 0; - size_t len = sizeof(data) / sizeof(data[0]); - size_t capacity = len; - - stack_t stack = NULL; - stack = stack_new2(sizeof(int), capacity); - TEST_ASSERT_NOT_NULL(stack); - stack->print_obj = print_num; - - TEST_ASSERT_FALSE(stack->peek(stack, &temp)); TEST_ASSERT_TRUE(stack->clear(stack)); + TEST_ASSERT_TRUE(stack->empty(stack)); for (i = 0; i < len; i++) { TEST_ASSERT_TRUE(stack->push(stack, &data[i])); - TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); - - TEST_ASSERT_TRUE(stack->peek(stack, &temp)); - TEST_ASSERT_EQUAL_INT(data[i], temp); } - iterator_t iter = stack->iter(stack); - TEST_ASSERT_NOT_NULL(iter); - i = 0; - while(iter->hasnext(iter)) + for (i = 0; i < len + 1; i++) { - temp = *(int *)iter->next(iter); - // printf("%d ", temp); - TEST_ASSERT_EQUAL_INT(data[i], temp); - i++; + if(!stack->empty(stack)) + { + TEST_ASSERT_TRUE(stack->pop(stack, &temp)); + } + else + { + TEST_ASSERT_FALSE(stack->pop(stack, &temp)); + } + + if(!stack->empty(stack)) + { + TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + size_t idx = stack->size(stack) - 1; + TEST_ASSERT_EQUAL_INT(data[idx].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[idx].name, temp.name); + } + else + { + TEST_ASSERT_FALSE(stack->peek(stack, &temp)); + } } stack_free(&stack); TEST_ASSERT_NULL(stack); } + void test_stack(void) { UnitySetTestFile(__FILE__); + // ---------- kernel ---------- RUN_TEST(test_stack_new); + RUN_TEST(test_stack_new_lazy); + RUN_TEST(test_stack_push); + RUN_TEST(test_stack_push_invalid); + RUN_TEST(test_stack_pop); - RUN_TEST(test_stack_clear); - RUN_TEST(test_stack_num); - RUN_TEST(test_stack_struct); - - RUN_TEST(test_stack2_num); - // RUN_TEST(test_stack2_struct); + RUN_TEST(test_stack_peek); + RUN_TEST(test_stack_peek_invalid); RUN_TEST(test_stack_iter); - RUN_TEST(test_stack2_iter); + + RUN_TEST(test_stack_resize); + RUN_TEST(test_stack_resize_invalid); + RUN_TEST(test_stack_resize_edge); + + RUN_TEST(test_stack_dynamic); + + // ---------- base ---------- + RUN_TEST(test_stack_status); + + // ---------- ext ---------- + RUN_TEST(test_stack_struct); }