improve dlist/slist

This commit is contained in:
lixianjing 2025-04-13 16:05:47 +08:00
parent b62ab24184
commit d580a30260
3 changed files with 72 additions and 55 deletions

View File

@ -1,5 +1,8 @@
# 最新动态
2025/04/13
* 完善slist/dlist(感谢兆坤提供补丁)
2025/04/10
* 去除克隆combo_box时不必要的打印信息(感谢福明提供补丁)
* 增加注释描述和修复nanovg不支持缩放后设置裁剪区的问题(感谢智明提供补丁)

View File

@ -23,19 +23,24 @@
#include "tkc/utils.h"
#include "tkc/dlist.h"
static dlist_node_t* dlist_node_create(void* data) {
dlist_node_t* node = TKMEM_ZALLOC(dlist_node_t);
return_value_if_fail(node != NULL, NULL);
static dlist_node_t* dlist_create_node(dlist_t* dlist, void* data) {
dlist_node_t* ret = NULL;
return_value_if_fail(dlist != NULL, NULL);
node->data = data;
ret = TKMEM_ZALLOC(dlist_node_t);
return_value_if_fail(ret != NULL, NULL);
return node;
ret->data = data;
return ret;
}
static ret_t dlist_node_destroy(dlist_node_t* node, tk_destroy_t destroy) {
return_value_if_fail(node != NULL && destroy != NULL, RET_OK);
static ret_t dlist_destroy_node(dlist_t* dlist, dlist_node_t* node) {
return_value_if_fail(dlist != NULL && node != NULL, RET_OK);
destroy(node->data);
if (node->data != NULL) {
dlist->destroy(node->data);
}
TKMEM_FREE(node);
return RET_OK;
@ -50,9 +55,9 @@ dlist_t* dlist_create(tk_destroy_t destroy, tk_compare_t compare) {
dlist_t* dlist_init(dlist_t* dlist, tk_destroy_t destroy, tk_compare_t compare) {
return_value_if_fail(dlist != NULL, NULL);
dlist->first = NULL;
dlist->last = NULL;
dlist->size = 0;
memset(dlist, 0, sizeof(dlist_t));
dlist->destroy = destroy != NULL ? destroy : dummy_destroy;
dlist->compare = compare != NULL ? compare : pointer_compare;
@ -94,28 +99,28 @@ void* dlist_find_last(dlist_t* dlist, void* ctx) {
return dlist_find_ex(dlist, NULL, ctx, TRUE);
}
static ret_t dlist_insert_node(dlist_t* dlist, dlist_node_t* node, dlist_node_t* iter) {
static ret_t dlist_insert_node(dlist_t* dlist, dlist_node_t* node, dlist_node_t* next) {
return_value_if_fail(dlist != NULL && node != NULL, RET_BAD_PARAMS);
if (dlist->first == NULL || dlist->last == NULL) {
dlist->first = dlist->last = node;
} else if (iter == NULL) {
} else if (next == NULL) {
/* append */
dlist->last->next = node;
node->prev = dlist->last;
dlist->last = node;
} else if (iter == dlist->first) {
} else if (next == dlist->first) {
/* prepend */
dlist->first->prev = node;
node->next = dlist->first;
dlist->first = node;
} else {
node->next = iter;
node->prev = iter->prev;
node->next = next;
node->prev = next->prev;
ENSURE(iter->prev != NULL);
iter->prev->next = node;
iter->prev = node;
ENSURE(next->prev != NULL);
next->prev->next = node;
next->prev = node;
}
dlist->size++;
@ -160,7 +165,7 @@ ret_t dlist_remove_ex(dlist_t* dlist, tk_compare_t compare, void* ctx, int32_t r
if (compare(iter->data, ctx) == 0) {
dlist_node_t* next = iter->next;
dlist_remove_node(dlist, iter);
dlist_node_destroy(iter, dlist->destroy);
dlist_destroy_node(dlist, iter);
iter = next;
if (--n == 0) {
return RET_OK;
@ -175,7 +180,7 @@ ret_t dlist_remove_ex(dlist_t* dlist, tk_compare_t compare, void* ctx, int32_t r
if (compare(iter->data, ctx) == 0) {
dlist_node_t* prev = iter->prev;
dlist_remove_node(dlist, iter);
dlist_node_destroy(iter, dlist->destroy);
dlist_destroy_node(dlist, iter);
iter = prev;
if (--n == 0) {
return RET_OK;
@ -201,7 +206,7 @@ ret_t dlist_append(dlist_t* dlist, void* data) {
dlist_node_t* node = NULL;
return_value_if_fail(dlist != NULL, RET_BAD_PARAMS);
node = dlist_node_create(data);
node = dlist_create_node(dlist, data);
return_value_if_fail(node != NULL, RET_OOM);
return dlist_insert_node(dlist, node, NULL);
@ -211,7 +216,7 @@ ret_t dlist_prepend(dlist_t* dlist, void* data) {
dlist_node_t* node = NULL;
return_value_if_fail(dlist != NULL, RET_BAD_PARAMS);
node = dlist_node_create(data);
node = dlist_create_node(dlist, data);
return_value_if_fail(node != NULL, RET_OOM);
return dlist_insert_node(dlist, node, dlist->first);
@ -228,7 +233,7 @@ ret_t dlist_foreach(dlist_t* dlist, tk_visit_t visit, void* ctx) {
if (ret == RET_REMOVE) {
dlist_node_t* next = iter->next;
dlist_remove_node(dlist, iter);
dlist_node_destroy(iter, dlist->destroy);
dlist_destroy_node(dlist, iter);
iter = next;
continue;
} else if (ret != RET_OK) {
@ -251,7 +256,7 @@ ret_t dlist_foreach_reverse(dlist_t* dlist, tk_visit_t visit, void* ctx) {
if (ret == RET_REMOVE) {
dlist_node_t* prev = iter->prev;
dlist_remove_node(dlist, iter);
dlist_node_destroy(iter, dlist->destroy);
dlist_destroy_node(dlist, iter);
iter = prev;
continue;
} else if (ret != RET_OK) {
@ -276,7 +281,8 @@ static void* dlist_pop(dlist_t* dlist, bool_t head) {
dlist_remove_node(dlist, iter);
data = iter->data;
TKMEM_FREE(iter);
iter->data = NULL;
dlist_destroy_node(dlist, iter);
return data;
}
@ -350,7 +356,7 @@ ret_t dlist_remove_all(dlist_t* dlist) {
while (iter != NULL) {
dlist_node_t* next = iter->next;
dlist_node_destroy(iter, dlist->destroy);
dlist_destroy_node(dlist, iter);
iter = next;
}
@ -381,7 +387,7 @@ ret_t dlist_insert(dlist_t* dlist, uint32_t index, void* data) {
iter = iter->next;
}
node = dlist_node_create(data);
node = dlist_create_node(dlist, data);
return_value_if_fail(node != NULL, RET_OOM);
return dlist_insert_node(dlist, node, iter);

View File

@ -23,19 +23,24 @@
#include "tkc/utils.h"
#include "tkc/slist.h"
static slist_node_t* slist_node_create(void* data) {
slist_node_t* node = TKMEM_ZALLOC(slist_node_t);
return_value_if_fail(node != NULL, NULL);
static slist_node_t* slist_create_node(slist_t* slist, void* data) {
slist_node_t* ret = NULL;
return_value_if_fail(slist != NULL, NULL);
node->data = data;
ret = TKMEM_ZALLOC(slist_node_t);
return_value_if_fail(ret != NULL, NULL);
return node;
ret->data = data;
return ret;
}
static ret_t slist_node_destroy(slist_node_t* node, tk_destroy_t destroy) {
return_value_if_fail(node != NULL && destroy != NULL, RET_OK);
static ret_t slist_destroy_node(slist_t* slist, slist_node_t* node) {
return_value_if_fail(slist != NULL && node != NULL, RET_OK);
destroy(node->data);
if (node->data != NULL) {
slist->destroy(node->data);
}
TKMEM_FREE(node);
return RET_OK;
@ -50,9 +55,9 @@ slist_t* slist_create(tk_destroy_t destroy, tk_compare_t compare) {
slist_t* slist_init(slist_t* slist, tk_destroy_t destroy, tk_compare_t compare) {
return_value_if_fail(slist != NULL, NULL);
slist->first = NULL;
slist->last = NULL;
slist->size = 0;
memset(slist, 0, sizeof(slist_t));
slist->destroy = destroy != NULL ? destroy : dummy_destroy;
slist->compare = compare != NULL ? compare : pointer_compare;
@ -107,16 +112,16 @@ static ret_t slist_insert_node(slist_t* slist, slist_node_t* node, slist_node_t*
return RET_OK;
}
static ret_t slist_remove_node(slist_t* slist, slist_node_t* prev, slist_node_t* iter) {
return_value_if_fail(slist != NULL, RET_BAD_PARAMS);
static ret_t slist_remove_node(slist_t* slist, slist_node_t* node, slist_node_t* prev) {
return_value_if_fail(slist != NULL && node != NULL, RET_BAD_PARAMS);
return_value_if_fail(slist->size > 0, RET_FAIL);
if (slist->first == slist->last) {
slist->first = slist->last = NULL;
} else if (prev == NULL || iter == slist->first) {
} else if (prev == NULL || node == slist->first) {
/* head_pop */
slist->first = slist->first->next;
} else if (prev->next == slist->last || iter == slist->last) {
} else if (prev->next == slist->last || node == slist->last) {
/* tail_pop */
prev->next = NULL;
slist->last = prev;
@ -139,8 +144,8 @@ ret_t slist_remove_ex(slist_t* slist, tk_compare_t compare, void* ctx, int32_t r
while (iter != NULL) {
if (compare(iter->data, ctx) == 0) {
slist_node_t* next = iter->next;
slist_remove_node(slist, prev, iter);
slist_node_destroy(iter, slist->destroy);
slist_remove_node(slist, iter, prev);
slist_destroy_node(slist, iter);
iter = next;
if (--n == 0) {
return RET_OK;
@ -161,7 +166,8 @@ ret_t slist_remove(slist_t* slist, void* ctx) {
ret_t slist_append(slist_t* slist, void* data) {
slist_node_t* node = NULL;
return_value_if_fail(slist != NULL, RET_BAD_PARAMS);
node = slist_node_create(data);
node = slist_create_node(slist, data);
return_value_if_fail(node != NULL, RET_OOM);
return slist_insert_node(slist, node, slist->last);
@ -171,7 +177,7 @@ ret_t slist_prepend(slist_t* slist, void* data) {
slist_node_t* node = NULL;
return_value_if_fail(slist != NULL, RET_BAD_PARAMS);
node = slist_node_create(data);
node = slist_create_node(slist, data);
return_value_if_fail(node != NULL, RET_OOM);
return slist_insert_node(slist, node, NULL);
@ -188,8 +194,8 @@ ret_t slist_foreach(slist_t* slist, tk_visit_t visit, void* ctx) {
ret = visit(ctx, iter->data);
if (ret == RET_REMOVE) {
slist_node_t* next = iter->next;
slist_remove_node(slist, prev, iter);
slist_node_destroy(iter, slist->destroy);
slist_remove_node(slist, iter, prev);
slist_destroy_node(slist, iter);
iter = next;
continue;
} else if (ret != RET_OK) {
@ -217,10 +223,11 @@ void* slist_tail_pop(slist_t* slist) {
prev = iter;
iter = iter->next;
}
slist_remove_node(slist, prev, iter);
slist_remove_node(slist, iter, prev);
data = iter->data;
TKMEM_FREE(iter);
iter->data = NULL;
slist_destroy_node(slist, iter);
return data;
}
@ -235,10 +242,11 @@ void* slist_head_pop(slist_t* slist) {
return NULL;
}
slist_remove_node(slist, NULL, iter);
slist_remove_node(slist, iter, NULL);
data = iter->data;
TKMEM_FREE(iter);
iter->data = NULL;
slist_destroy_node(slist, iter);
return data;
}
@ -304,7 +312,7 @@ ret_t slist_remove_all(slist_t* slist) {
while (iter != NULL) {
slist_node_t* next = iter->next;
slist_node_destroy(iter, slist->destroy);
slist_destroy_node(slist, iter);
iter = next;
}
@ -337,7 +345,7 @@ ret_t slist_insert(slist_t* slist, uint32_t index, void* data) {
iter = iter->next;
}
node = slist_node_create(data);
node = slist_create_node(slist, data);
return_value_if_fail(node != NULL, RET_OOM);
return slist_insert_node(slist, node, prev);