]> git.lizzy.rs Git - dragonstd.git/commitdiff
Rework get,add,del return values
authorElias Fleckenstein <eliasfleckenstein@web.de>
Wed, 13 Apr 2022 17:53:15 +0000 (19:53 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Wed, 13 Apr 2022 17:53:15 +0000 (19:53 +0200)
bits/wrappers.h
list.h
map.c
map.h
refcount.c
refcount.h
test/test_list.c
test/test_refcount_map.c
test/test_tree.c
tree.h

index 66093a212deec4df5ed56c01b70763cf62f96af2..652becbc7f1178bc80bdb533a5d394c131c37c32 100644 (file)
@@ -1,12 +1,13 @@
 #define WRAP_NODE_FUNCTIONS(Type, prefix) \
 #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); \
  \
        { \
                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) \
        } \
  \
        void *prefix ## get(Type *self, void *key, Comparator cmp, Transformer trans) \
                return trans ? trans((*node)->dat) : (*node)->dat; \
        } \
  \
                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) \
        { \
                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); \
                prefix ## nrm(self, node); \
-               return dat; \
+               return true; \
        }
        }
diff --git a/list.h b/list.h
index e9f3b4b68a0f095fde1f2d8c923e3504c8f2e85d..94bacf2f591418328cf5e13cf811ae79adadca9d 100644 (file)
--- a/list.h
+++ b/list.h
@@ -8,7 +8,8 @@
 #ifndef _DRAGONSTD_LIST_H_ // include guard
 #define _DRAGONSTD_LIST_H_
 
 #ifndef _DRAGONSTD_LIST_H_ // include guard
 #define _DRAGONSTD_LIST_H_
 
-#include "bits/callback.h" // for Iterator, Comparator
+#include <stdbool.h>       // 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)
 #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.
 */
 
        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.
 
 /*
        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);
 */
 
 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.
 */
 
        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);
 */
 
 void list_apd(List *list, void *dat);
diff --git a/map.c b/map.c
index 61e971cd24368098a86fbefb1b4076550c2b5b2e..c45069fdef5945bf5f9ec201ba3c61cc0685d53d 100644 (file)
--- 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);
 }
 
        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)) \
        { \
                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); \
                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)
 {
 
 void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
 {
diff --git a/map.h b/map.h
index 08d3fd08ab3d56c2b69c89571aa4313335ff204e..b74441caf714e9e368a14bced2fc6a7f6ca95a05 100644 (file)
--- 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.
 */
 
        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.
 
 /*
        [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);
 */
 
 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.
 */
 
        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]
 /*
        [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);
 */
 
 void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
index e0b354cfcf571e8f556c085ccf05b573ec5111ae..8473787e7ba1ec7b6a4b5c23aa40de507d0813bc 100644 (file)
@@ -1,6 +1,6 @@
 #include "refcount.h"
 
 #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;
 {
        refcount->obj = obj;
        refcount->del = del;
@@ -28,7 +28,7 @@ void *refcount_grb(void *refcount)
        return refcount_obj(refcount_inc(refcount));
 }
 
        return refcount_obj(refcount_inc(refcount));
 }
 
-void *refcount_drp(void *refcount)
+void refcount_drp(void *refcount)
 {
        Refcount *rc = refcount;
 
 {
        Refcount *rc = refcount;
 
@@ -37,9 +37,7 @@ void *refcount_drp(void *refcount)
        pthread_mutex_unlock(&rc->mtx);
 
        if (! count)
        pthread_mutex_unlock(&rc->mtx);
 
        if (! count)
-               return rc->del(rc->obj);
-
-       return rc->obj;
+               rc->del(rc->obj);
 }
 
 void *refcount_obj(void *refcount)
 }
 
 void *refcount_obj(void *refcount)
index 9c1d6d1ed7b12dd34c6c82a6528b2c409293ce8f..f551b57c7ce47ef96e491cdd17cb26e92372cd94 100644 (file)
 #define _DRAGONSTD_REFCOUNT_H_
 
 #include <pthread.h>       // for pthread_mutex_t
 #define _DRAGONSTD_REFCOUNT_H_
 
 #include <pthread.h>       // for pthread_mutex_t
-#include "bits/callback.h" // for Transformer
+#include "bits/callback.h" // for Callback
 
 typedef struct {
        /* private */
        void *obj;
 
 typedef struct {
        /* private */
        void *obj;
-       Transformer del;
+       Callback del;
        unsigned short cnt;  // counter
        pthread_mutex_t mtx; // lock to protect count
 } Refcount;
 
        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.
 
 /*
        Initializes the refcount.
 
@@ -60,7 +60,7 @@ void *refcount_grb(void *refcount);
                refcount.
 */
 
                refcount.
 */
 
-void *refcount_drp(void *refcount);
+void refcount_drp(void *refcount);
 /*
        [Thread Safe]
        Drop a reference to the object.
 /*
        [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.
                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);
 */
 
 void *refcount_obj(void *refcount);
index 7ba89927a3705562b0fbf7b363f44360b51c1c62..18c5cf4a78da8a0d509175344f034e52900b0e60 100644 (file)
@@ -25,10 +25,10 @@ int main()
        int e = 3;
 
        printf("testing add\n");
        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);
 
        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_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");
        assert(list_get(&list, &a, &cmp_int, NULL) == NULL);
 
        printf("testing clr\n");
index 642f15b6bd799eb2f8de73db17ad80e2b765cb0b..84dc1abecf7d55b5c0c8c895af56c370d12fc2b6 100644 (file)
@@ -16,11 +16,10 @@ typedef struct {
        Refcount rc;
 } DataObject;
 
        Refcount rc;
 } DataObject;
 
-void *data_object_delete(DataObject *obj)
+void data_object_delete(DataObject *obj)
 {
        refcount_dst(&obj->rc);
        free(obj);
 {
        refcount_dst(&obj->rc);
        free(obj);
-       return obj;
 }
 
 int rand_id()
 }
 
 int rand_id()
@@ -50,7 +49,7 @@ static void *thread_create(unsigned int *result)
 
                refcount_ini(&obj->rc, obj, (void *) &data_object_delete);
 
 
                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);
                        (*result)++;
 
                refcount_drp(&obj->rc);
index ae5ec5b950071fef18629053e88040794427c02a..7267162c60be4dca4357822c6749429fd203afbf 100644 (file)
@@ -38,10 +38,10 @@ int main()
        int e = 3;
 
        printf("testing add\n");
        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);
 
        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_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");
        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();
 
                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);
        }
 
                        free(n);
        }
 
diff --git a/tree.h b/tree.h
index 94fce315c8a7ddc1b955d1a3e57f783db3ed8f94..4df0e016e30e0de2ea6c7da1001dab5e26ed6d6d 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -14,7 +14,8 @@
 #ifndef _DRAGONSTD_TREE_H_ // include guard
 #define _DRAGONSTD_TREE_H_
 
 #ifndef _DRAGONSTD_TREE_H_ // include guard
 #define _DRAGONSTD_TREE_H_
 
-#include "bits/callback.h" // for Iterator, Comparator
+#include <stdbool.h>       // 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 {
 #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.
 */
 
        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.
 
 /*
        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);
 */
 
 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.
 */
 
        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);
 */
 
 TreeNode **tree_nfd(Tree *tree, void *key, Comparator cmp);