From: Elias Fleckenstein Date: Wed, 13 Apr 2022 17:53:15 +0000 (+0200) Subject: Rework get,add,del return values X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=c3bbe99d5c2a712789485b92c02826b19820a92f;p=dragonstd.git Rework get,add,del return values --- diff --git a/bits/wrappers.h b/bits/wrappers.h index 66093a2..652becb 100644 --- a/bits/wrappers.h +++ b/bits/wrappers.h @@ -1,12 +1,13 @@ #define WRAP_NODE_FUNCTIONS(Type, prefix) \ - void *prefix ## add(Type *self, void *dat, Comparator cmp, Transformer trans) \ + bool prefix ## add(Type *self, void *dat, Comparator cmp, Transformer trans) \ { \ Type ## Node **node = prefix ## nfd(self, dat, cmp); \ \ - if (! *node) \ - prefix ## nmk(self, node, trans ? trans(dat) : dat); \ + if (*node) \ + return false; \ \ - return (*node)->dat; \ + prefix ## nmk(self, node, trans ? trans(dat) : dat); \ + return true; \ } \ \ void *prefix ## get(Type *self, void *key, Comparator cmp, Transformer trans) \ @@ -19,14 +20,16 @@ return trans ? trans((*node)->dat) : (*node)->dat; \ } \ \ - void *prefix ## del(Type *self, void *key, Comparator cmp, Transformer trans) \ + bool prefix ## del(Type *self, void *key, Comparator cmp, Callback call) \ { \ Type ## Node **node = prefix ## nfd(self, key, cmp); \ \ if (! *node) \ - return NULL; \ + return false; \ + \ + if (call) \ + call((*node)->dat); \ \ - void *dat = trans ? trans((*node)->dat) : (*node)->dat; \ prefix ## nrm(self, node); \ - return dat; \ + return true; \ } diff --git a/list.h b/list.h index e9f3b4b..94bacf2 100644 --- a/list.h +++ b/list.h @@ -8,7 +8,8 @@ #ifndef _DRAGONSTD_LIST_H_ // include guard #define _DRAGONSTD_LIST_H_ -#include "bits/callback.h" // for Iterator, Comparator +#include // for bool +#include "bits/callback.h" // for Iterator, Comparator, Transformer, Callback #include "bits/compare.h" // for cmp_ref (not used in file) #define LIST_ITERATE(list, node) for (ListNode *node = (list)->fst; node != NULL; node = node->nxt) @@ -34,12 +35,12 @@ void list_ini(List *list); This function should be called before any other function is called on the list. */ -void *list_add(List *list, void *dat, Comparator cmp, Transformer trans); +bool list_add(List *list, void *dat, Comparator cmp, Transformer trans); /* Add an element to the list. - If an equal element is already on the list, return it and don't add anything. - Otherwise, return added element. + If an equal element is already in the list, don't add anything. + Return whether an element has been added. */ void *list_get(List *list, void *key, Comparator cmp, Transformer trans); @@ -49,12 +50,12 @@ void *list_get(List *list, void *key, Comparator cmp, Transformer trans); The first matching element is returned, or NULL if none found. */ -void *list_del(List *list, void *key, Comparator cmp, Transformer trans); +bool list_del(List *list, void *key, Comparator cmp, Callback call); /* - Delete an element from the list. + Delete an element from the list if it is found. + Return whether an element has been deleted. - The first matching element is returned (after being removed from the list), or NULL - if none found. + The first matching element is deleted. */ void list_apd(List *list, void *dat); diff --git a/map.c b/map.c index 61e971c..c45069f 100644 --- a/map.c +++ b/map.c @@ -45,20 +45,20 @@ void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversi pthread_rwlock_unlock(&map->tlk); } -#define WRAP_TREE_FUNC(name, write) \ - void *map_ ## name(Map *map, void *dat, Comparator cmp, Transformer trans) \ +#define WRAP_TREE_FUNC(type, name, write, CallbackType, null) \ + type map_ ## name(Map *map, void *dat, Comparator cmp, CallbackType func) \ { \ if (! get_lock(map, write)) \ - return NULL; \ + return null; \ \ - dat = tree_ ## name(&map->tre, dat, cmp, trans); \ + type ret = tree_ ## name(&map->tre, dat, cmp, func); \ pthread_rwlock_unlock(&map->tlk); \ - return dat; \ + return ret; \ } -WRAP_TREE_FUNC(add, true) -WRAP_TREE_FUNC(get, false) -WRAP_TREE_FUNC(del, true) +WRAP_TREE_FUNC(bool, add, true, Transformer, false) +WRAP_TREE_FUNC(void *, get, false, Transformer, NULL) +WRAP_TREE_FUNC(bool, del, true, Callback, false) void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order) { diff --git a/map.h b/map.h index 08d3fd0..b74441c 100644 --- a/map.h +++ b/map.h @@ -52,13 +52,13 @@ void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversi If no callback is given, the traversion order is irrelevant. */ -void *map_add(Map *map, void *dat, Comparator cmp, Transformer trans); +bool map_add(Map *map, void *dat, Comparator cmp, Transformer trans); /* [Thread Safe] Add an element to the map. - If an equal element is already in the tree, return it and don't add anything. - Otherwise, return added element. + If an equal element is already in the map, don't add anything. + Return whether an element has been added. */ void *map_get(Map *map, void *key, Comparator cmp, Transformer trans); @@ -67,10 +67,11 @@ void *map_get(Map *map, void *key, Comparator cmp, Transformer trans); Get an element from the map, or return NULL if none found. */ -void *map_del(Map *map, void *key, Comparator cmp, Transformer trans); +bool map_del(Map *map, void *key, Comparator cmp, Callback call); /* [Thread Safe] - Delete an element from the map and return it, or NULL if none found. + Delete an element from the map if it is found. + Return whether an element has been deleted. */ void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order); diff --git a/refcount.c b/refcount.c index e0b354c..8473787 100644 --- a/refcount.c +++ b/refcount.c @@ -1,6 +1,6 @@ #include "refcount.h" -void refcount_ini(Refcount *refcount, void *obj, Transformer del) +void refcount_ini(Refcount *refcount, void *obj, Callback del) { refcount->obj = obj; refcount->del = del; @@ -28,7 +28,7 @@ void *refcount_grb(void *refcount) return refcount_obj(refcount_inc(refcount)); } -void *refcount_drp(void *refcount) +void refcount_drp(void *refcount) { Refcount *rc = refcount; @@ -37,9 +37,7 @@ void *refcount_drp(void *refcount) pthread_mutex_unlock(&rc->mtx); if (! count) - return rc->del(rc->obj); - - return rc->obj; + rc->del(rc->obj); } void *refcount_obj(void *refcount) diff --git a/refcount.h b/refcount.h index 9c1d6d1..f551b57 100644 --- a/refcount.h +++ b/refcount.h @@ -14,17 +14,17 @@ #define _DRAGONSTD_REFCOUNT_H_ #include // for pthread_mutex_t -#include "bits/callback.h" // for Transformer +#include "bits/callback.h" // for Callback typedef struct { /* private */ void *obj; - Transformer del; + Callback del; unsigned short cnt; // counter pthread_mutex_t mtx; // lock to protect count } Refcount; -void refcount_ini(Refcount *refcount, void *obj, Transformer del); +void refcount_ini(Refcount *refcount, void *obj, Callback del); /* Initializes the refcount. @@ -60,7 +60,7 @@ void *refcount_grb(void *refcount); refcount. */ -void *refcount_drp(void *refcount); +void refcount_drp(void *refcount); /* [Thread Safe] Drop a reference to the object. @@ -68,8 +68,6 @@ void *refcount_drp(void *refcount); convenient to use the function as callback. May delete the object using the del function if the counter gets down to zero. - Returns the return value of the del function if it has been called; returns the object - otherwise. */ void *refcount_obj(void *refcount); diff --git a/test/test_list.c b/test/test_list.c index 7ba8992..18c5cf4 100644 --- a/test/test_list.c +++ b/test/test_list.c @@ -25,10 +25,10 @@ int main() int e = 3; printf("testing add\n"); - assert(list_add(&list, &a, &cmp_int, NULL) == &a); - assert(list_add(&list, &b, &cmp_int, NULL) == &b); - assert(list_add(&list, &c, &cmp_int, NULL) == &c); - assert(list_add(&list, &d, &cmp_int, NULL) == &c); + assert(list_add(&list, &a, &cmp_int, NULL)); + assert(list_add(&list, &b, &cmp_int, NULL)); + assert(list_add(&list, &c, &cmp_int, NULL)); + assert(!list_add(&list, &d, &cmp_int, NULL)); printf("testing get\n"); assert(list_get(&list, &a, &cmp_int, NULL) == &a); @@ -38,7 +38,7 @@ int main() assert(list_get(&list, &e, &cmp_int, NULL) == NULL); printf("testing del\n"); - assert(list_del(&list, &a, &cmp_int, NULL) == &a); + assert(list_del(&list, &a, &cmp_int, NULL)); assert(list_get(&list, &a, &cmp_int, NULL) == NULL); printf("testing clr\n"); diff --git a/test/test_refcount_map.c b/test/test_refcount_map.c index 642f15b..84dc1ab 100644 --- a/test/test_refcount_map.c +++ b/test/test_refcount_map.c @@ -16,11 +16,10 @@ typedef struct { Refcount rc; } DataObject; -void *data_object_delete(DataObject *obj) +void data_object_delete(DataObject *obj) { refcount_dst(&obj->rc); free(obj); - return obj; } int rand_id() @@ -50,7 +49,7 @@ static void *thread_create(unsigned int *result) refcount_ini(&obj->rc, obj, (void *) &data_object_delete); - if (map_add(&map, &obj->rc, &data_object_compare, &refcount_inc) == &obj->rc) + if (map_add(&map, &obj->rc, &data_object_compare, &refcount_inc)) (*result)++; refcount_drp(&obj->rc); diff --git a/test/test_tree.c b/test/test_tree.c index ae5ec5b..7267162 100644 --- a/test/test_tree.c +++ b/test/test_tree.c @@ -38,10 +38,10 @@ int main() int e = 3; printf("testing add\n"); - assert(tree_add(&tree, &a, &cmp_int, NULL) == &a); - assert(tree_add(&tree, &b, &cmp_int, NULL) == &b); - assert(tree_add(&tree, &c, &cmp_int, NULL) == &c); - assert(tree_add(&tree, &d, &cmp_int, NULL) == &c); + assert(tree_add(&tree, &a, &cmp_int, NULL)); + assert(tree_add(&tree, &b, &cmp_int, NULL)); + assert(tree_add(&tree, &c, &cmp_int, NULL)); + assert(!tree_add(&tree, &d, &cmp_int, NULL)); printf("testing get\n"); assert(tree_get(&tree, &a, &cmp_int, NULL) == &a); @@ -51,7 +51,7 @@ int main() assert(tree_get(&tree, &e, &cmp_int, NULL) == NULL); printf("testing del\n"); - assert(tree_del(&tree, &a, &cmp_int, NULL) == &a); + assert(tree_del(&tree, &a, &cmp_int, NULL)); assert(tree_get(&tree, &a, &cmp_int, NULL) == NULL); printf("testing clr\n"); @@ -63,7 +63,7 @@ int main() int *n = malloc(sizeof *n); *n = rand(); - if (tree_add(&tree, n, &cmp_int, NULL) != n) + if (!tree_add(&tree, n, &cmp_int, NULL)) free(n); } diff --git a/tree.h b/tree.h index 94fce31..4df0e01 100644 --- a/tree.h +++ b/tree.h @@ -14,7 +14,8 @@ #ifndef _DRAGONSTD_TREE_H_ // include guard #define _DRAGONSTD_TREE_H_ -#include "bits/callback.h" // for Iterator, Comparator +#include // for bool +#include "bits/callback.h" // for Iterator, Comparator, Transformer, Callback #include "bits/compare.h" // for cmp_ref (not used in file) typedef struct TreeNode { @@ -44,12 +45,12 @@ void tree_ini(Tree *tree); This function should be called before any other function is called on the tree. */ -void *tree_add(Tree *tree, void *dat, Comparator cmp, Transformer trans); +bool tree_add(Tree *tree, void *dat, Comparator cmp, Transformer trans); /* Add an element to the tree. - If an equal element is already in the tree, return it and don't add anything. - Otherwise, return added element. + If an equal element is already in the tree, don't add anything. + Return whether an element has been added. */ void *tree_get(Tree *tree, void *key, Comparator cmp, Transformer trans); @@ -57,9 +58,10 @@ void *tree_get(Tree *tree, void *key, Comparator cmp, Transformer trans); Get an element from the tree, or return NULL if none found. */ -void *tree_del(Tree *tree, void *key, Comparator cmp, Transformer trans); +bool tree_del(Tree *tree, void *key, Comparator cmp, Callback call); /* - Delete an element from the tree and return it, or NULL if none found. + Delete an element from the tree if it is found. + Return whether an element has been deleted. */ TreeNode **tree_nfd(Tree *tree, void *key, Comparator cmp);