]> git.lizzy.rs Git - dragonstd.git/commitdiff
Add transformers to iterator functions
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sun, 3 Apr 2022 19:45:39 +0000 (21:45 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sun, 3 Apr 2022 19:45:39 +0000 (21:45 +0200)
12 files changed:
bits/wrappers.h
list.c
list.h
map.c
map.h
queue.c
queue.h
test/test_list.c
test/test_refcount_map.c
test/test_tree.c
tree.c
tree.h

index 60d878444b68676690626f1dfeddf1f81bb124e5..66093a212deec4df5ed56c01b70763cf62f96af2 100644 (file)
@@ -1,32 +1,32 @@
 #define WRAP_NODE_FUNCTIONS(Type, prefix) \
-       void *prefix ## add(Type *self, void *dat, Comparator cmp, Transformer func) \
+       void *prefix ## add(Type *self, void *dat, Comparator cmp, Transformer trans) \
        { \
                Type ## Node **node = prefix ## nfd(self, dat, cmp); \
  \
                if (! *node) \
-                       prefix ## nmk(self, node, func ? func(dat) : dat); \
+                       prefix ## nmk(self, node, trans ? trans(dat) : dat); \
  \
                return (*node)->dat; \
        } \
  \
-       void *prefix ## get(Type *self, void *key, Comparator cmp, Transformer func) \
+       void *prefix ## get(Type *self, void *key, Comparator cmp, Transformer trans) \
        { \
                Type ## Node **node = prefix ## nfd(self, key, cmp); \
  \
                if (! *node) \
                        return NULL; \
  \
-               return func ? func((*node)->dat) : (*node)->dat; \
+               return trans ? trans((*node)->dat) : (*node)->dat; \
        } \
  \
-       void *prefix ## del(Type *self, void *key, Comparator cmp, Transformer func) \
+       void *prefix ## del(Type *self, void *key, Comparator cmp, Transformer trans) \
        { \
                Type ## Node **node = prefix ## nfd(self, key, cmp); \
  \
                if (! *node) \
                        return NULL; \
  \
-               void *dat = func ? func((*node)->dat) : (*node)->dat; \
+               void *dat = trans ? trans((*node)->dat) : (*node)->dat; \
                prefix ## nrm(self, node); \
                return dat; \
        }
diff --git a/list.c b/list.c
index f136706196f7ab65909aa671914a9aea760f4a51..d8416d941b6cbd32d87cacd18e70bc21d6a5f09c 100644 (file)
--- a/list.c
+++ b/list.c
@@ -50,19 +50,19 @@ void list_nrm(List *list, ListNode **node)
        free(old);
 }
 
-void list_itr(List *list, Iterator func, void *arg)
+void list_itr(List *list, Iterator iter, void *arg, Transformer trans)
 {
        LIST_ITERATE(list, node)
-               func(node->dat, arg);
+               iter(trans ? trans(node->dat) : node->dat, arg);
 }
 
-void list_clr(List *list, Iterator func, void *arg)
+void list_clr(List *list, Iterator iter, void *arg, Transformer trans)
 {
        for (ListNode *node = list->fst; node != NULL;) {
                ListNode *next = node->nxt;
 
-               if (func)
-                       func(node->dat, arg);
+               if (iter)
+                       iter(trans ? trans(node->dat) : node->dat, arg);
 
                free(node);
                node = next;
diff --git a/list.h b/list.h
index 5adb33e96caae6816bd1162b87df0fc72aed6005..eb8f97b7ec8b109aa576d85f3b4b5eca4032632c 100644 (file)
--- a/list.h
+++ b/list.h
@@ -33,7 +33,7 @@ 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 func);
+void *list_add(List *list, void *dat, Comparator cmp, Transformer trans);
 /*
        Add an element to the list.
 
@@ -41,14 +41,14 @@ void *list_add(List *list, void *dat, Comparator cmp, Transformer func);
        Otherwise, return added element.
 */
 
-void *list_get(List *list, void *key, Comparator cmp, Transformer func);
+void *list_get(List *list, void *key, Comparator cmp, Transformer trans);
 /*
        Get an element from the list.
 
        The first matching element is returned, or NULL if none found.
 */
 
-void *list_del(List *list, void *key, Comparator cmp, Transformer func);
+void *list_del(List *list, void *key, Comparator cmp, Transformer trans);
 /*
        Delete an element from the list.
 
@@ -79,18 +79,18 @@ void list_nrm(List *list, ListNode **node);
        Remove the node at the given location.
 */
 
-void list_itr(List *list, Iterator func, void *arg);
+void list_itr(List *list, Iterator iter, void *arg, Transformer trans);
 /*
        Iterate over the list.
-       Calls func on every element, with the extra argument arg.
+       Calls iter on every element, with the extra argument arg.
 
        Note: the LIST_ITERATE macro can be used to do this without function calls.
 */
 
-void list_clr(List *list, Iterator func, void *arg);
+void list_clr(List *list, Iterator iter, void *arg, Transformer trans);
 /*
        Iterates over the list and deletes all elements.
-       Calls func on every element, with the extra argument arg.
+       Calls iter on every element, with the extra argument arg.
 
        The list is empty afterwards.
 */
diff --git a/map.c b/map.c
index f2593ec076b9c8c25e1487b4d587dca2ddd4abf5..20bccb637057b4b91ab3c9363b5b8daf37d20529 100644 (file)
--- a/map.c
+++ b/map.c
@@ -32,7 +32,7 @@ void map_dst(Map *map)
        pthread_rwlock_destroy(&map->clk);
 }
 
-void map_cnl(Map *map, Iterator func, void *arg, TreeTraversionOrder order)
+void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
 {
        pthread_rwlock_wrlock(&map->clk);
        map->cnl = true;
@@ -40,18 +40,18 @@ void map_cnl(Map *map, Iterator func, void *arg, TreeTraversionOrder order)
        pthread_rwlock_wrlock(&map->tlk);
        pthread_rwlock_unlock(&map->clk);
 
-       tree_clr(&map->tre, func, arg, order);
+       tree_clr(&map->tre, iter, arg, trans, order);
 
        pthread_rwlock_unlock(&map->tlk);
 }
 
 #define WRAP_TREE_FUNC(name, write) \
-       void *map_ ## name(Map *map, void *dat, Comparator cmp, Transformer func) \
+       void *map_ ## name(Map *map, void *dat, Comparator cmp, Transformer trans) \
        { \
                if (! get_lock(map, write)) \
                        return NULL; \
  \
-               dat = tree_ ## name(&map->tre, dat, cmp, func); \
+               dat = tree_ ## name(&map->tre, dat, cmp, trans); \
                pthread_rwlock_unlock(&map->tlk); \
                return dat; \
        }
@@ -59,3 +59,11 @@ void map_cnl(Map *map, Iterator func, void *arg, TreeTraversionOrder order)
 WRAP_TREE_FUNC(add, true)
 WRAP_TREE_FUNC(get, false)
 WRAP_TREE_FUNC(del, true)
+
+void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
+{
+       if (! get_lock(map, false))
+               return;
+
+       tree_trv(&map->tre, iter, arg, trans, order);
+}
diff --git a/map.h b/map.h
index 1a1060672559aa731d682f1222e6eab8b34938ed..08d3fd08ab3d56c2b69c89571aa4313335ff204e 100644 (file)
--- a/map.h
+++ b/map.h
@@ -38,7 +38,7 @@ void map_dst(Map *map);
        Make sure to cancel the map before destroying it, to avoid memory leaks.
 */
 
-void map_cnl(Map *map, Iterator func, void *arg, TreeTraversionOrder order);
+void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
 /*
        [Thread Safe]
        Cancels and clears the map.
@@ -52,7 +52,7 @@ void map_cnl(Map *map, Iterator func, void *arg, TreeTraversionOrder order);
        If no callback is given, the traversion order is irrelevant.
 */
 
-void *map_add(Map *map, void *dat, Comparator cmp, Transformer func);
+void *map_add(Map *map, void *dat, Comparator cmp, Transformer trans);
 /*
        [Thread Safe]
        Add an element to the map.
@@ -61,16 +61,24 @@ void *map_add(Map *map, void *dat, Comparator cmp, Transformer func);
        Otherwise, return added element.
 */
 
-void *map_get(Map *map, void *key, Comparator cmp, Transformer func);
+void *map_get(Map *map, void *key, Comparator cmp, Transformer trans);
 /*
        [Thread Safe]
        Get an element from the map, or return NULL if none found.
 */
 
-void *map_del(Map *map, void *key, Comparator cmp, Transformer func);
+void *map_del(Map *map, void *key, Comparator cmp, Transformer trans);
 /*
        [Thread Safe]
        Delete an element from the map and return it, or NULL if none found.
 */
 
+void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
+/*
+       [Thread Safe]
+       Traverse the map.
+       Calls iter on every element, with the extra argument arg.
+*/
+
+
 #endif
diff --git a/queue.c b/queue.c
index eeba91c4b31e0350c99203d61b49c76aa11be410..ccef905f7ddbcbc9cd91fd06d44239259f31812b 100644 (file)
--- a/queue.c
+++ b/queue.c
@@ -15,9 +15,9 @@ void queue_del(Queue *queue)
        pthread_mutex_destroy(&queue->mtx);
 }
 
-void queue_clr(Queue *queue, Iterator func, void *arg)
+void queue_clr(Queue *queue, Iterator iter, void *arg, Transformer trans)
 {
-       list_clr(&queue->lst, func, arg);
+       list_clr(&queue->lst, iter, arg, trans);
 }
 
 bool queue_enq(Queue *queue, void *dat)
@@ -35,7 +35,7 @@ bool queue_enq(Queue *queue, void *dat)
        return success;
 }
 
-void *queue_deq(Queue *queue, Transformer func)
+void *queue_deq(Queue *queue, Transformer trans)
 {
        void *dat = NULL;
 
@@ -46,8 +46,8 @@ void *queue_deq(Queue *queue, Transformer func)
                        dat = (*node)->dat;
                        list_nrm(&queue->lst, node);
 
-                       if (func)
-                               dat = func(dat);
+                       if (trans)
+                               dat = trans(dat);
                } else {
                        pthread_cond_wait(&queue->cnd, &queue->mtx);
                }
diff --git a/queue.h b/queue.h
index 2a7193064e8412299a843cc604bd0a9a19888bf3..8c758e282a7a553940be3604139e6d559568cd68 100644 (file)
--- a/queue.h
+++ b/queue.h
@@ -40,7 +40,7 @@ void queue_del(Queue *queue);
                list is cleared before calling this function.
 */
 
-void queue_clr(Queue *queue, Iterator func, void *arg);
+void queue_clr(Queue *queue, Iterator iter, void *arg, Transformer trans);
 /*
        Clears the queue.
 
@@ -58,7 +58,7 @@ bool queue_enq(Queue *queue, void *dat);
        Notifies waiting consumer threads.
 */
 
-void *queue_deq(Queue *queue, Transformer func);
+void *queue_deq(Queue *queue, Transformer trans);
 /*
        [Thread Safe]
        Dequeue an element.
index b261dbd2a541f17f433d95baa40b1d0e123ee3c8..7ba89927a3705562b0fbf7b363f44360b51c1c62 100644 (file)
@@ -42,6 +42,6 @@ int main()
        assert(list_get(&list, &a, &cmp_int, NULL) == NULL);
 
        printf("testing clr\n");
-       list_clr(&list, NULL, NULL);
+       list_clr(&list, NULL, NULL, NULL);
        assert(list_get(&list, &b, &cmp_int, NULL) == NULL);
 }
index 75291bf441fb095c5246a8545f840af66dfd0406..9333c00ebbb38ee30e58dbe227bab5935101d6ec 100644 (file)
@@ -137,7 +137,7 @@ int main()
                                results[i][0] += results[i][j];
                }
 
-       map_cnl(&map, (void *) &refcount_drp, NULL, 0);
+       map_cnl(&map, (void *) &refcount_drp, NULL, NULL, 0);
        map_dst(&map);
 
        printf("Time: 10 seconds\n");
index 6166cf07eaf3135eba10819cc4c54d8867cca45f..ae5ec5b950071fef18629053e88040794427c02a 100644 (file)
@@ -11,9 +11,10 @@ int cmp_int(const void *ia, const void *ib)
        return *(const int *) ia - *(const int *) ib;
 }
 
-void clear_callback(void *ia, void *ib)
+void clear_callback(int *ia, int *ib)
 {
-       assert(*(int *) ia > *(int *) ib);
+       assert(*ia >= *ib);
+       *ib = *ia;
        free(ia);
 }
 
@@ -54,7 +55,7 @@ int main()
        assert(tree_get(&tree, &a, &cmp_int, NULL) == NULL);
 
        printf("testing clr\n");
-       tree_clr(&tree, NULL, NULL, 0);
+       tree_clr(&tree, NULL, NULL, NULL, 0);
        assert(tree_get(&tree, &b, &cmp_int, NULL) == NULL);
 
        printf("testing order and speed with %d elements\n", (int) NUM_ELEMENTS);
@@ -67,5 +68,5 @@ int main()
        }
 
        int last = -1;
-       tree_clr(&tree, &clear_callback, &last, TRAVERSION_INORDER);
+       tree_clr(&tree, (void *) &clear_callback, &last, NULL, TRAVERSION_INORDER);
 }
diff --git a/tree.c b/tree.c
index aa55a12726d04e193d978a2a13c9eccec5bfa7f6..e4206b2238a7a83421f2ec3cf8b61ee63be127c5 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -17,16 +17,16 @@ static inline TreeNode **search(TreeNode **node, void *key, Comparator cmp)
                return search(&(*node)->rgt, key, cmp);
 }
 
-static inline void traverse(TreeNode *node, Iterator func, void *arg, TreeTraversionOrder order, int delete)
+static inline void traverse(TreeNode *node, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order, int delete)
 {
        if (! node)
                return;
 
-       if (func && order == TRAVERSION_PREORDER ) func(node->dat, arg);
-       traverse(node->lft, func, arg, order, delete);
-       if (func && order == TRAVERSION_INORDER  ) func(node->dat, arg);
-       traverse(node->rgt, func, arg, order, delete);
-       if (func && order == TRAVERSION_POSTORDER) func(node->dat, arg);
+       if (iter && order == TRAVERSION_PREORDER ) iter(trans ? trans(node->dat) : node->dat, arg);
+       traverse(node->lft, iter, arg, trans, order, delete);
+       if (iter && order == TRAVERSION_INORDER  ) iter(trans ? trans(node->dat) : node->dat, arg);
+       traverse(node->rgt, iter, arg, trans, order, delete);
+       if (iter && order == TRAVERSION_POSTORDER) iter(trans ? trans(node->dat) : node->dat, arg);
 
        if (delete)
                free(node);
@@ -68,13 +68,13 @@ void tree_nrm(__attribute__((unused)) Tree *tree, TreeNode **node)
        free(old);
 }
 
-void tree_trv(Tree *tree, Iterator func, void *arg, TreeTraversionOrder order)
+void tree_trv(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
 {
-       traverse(tree->rot, func, arg, order, 0);
+       traverse(tree->rot, iter, arg, trans, order, 0);
 }
 
-void tree_clr(Tree *tree, Iterator func, void *arg, TreeTraversionOrder order)
+void tree_clr(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
 {
-       traverse(tree->rot, func, arg, order, 1);
+       traverse(tree->rot, iter, arg, trans, order, 1);
        tree_ini(tree);
 }
diff --git a/tree.h b/tree.h
index 5c90e101bb9cad43272f86fcb256773ee0cc420f..d2533214ce5c32dcf475269568757875e03fe0d8 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -43,7 +43,7 @@ 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 func);
+void *tree_add(Tree *tree, void *dat, Comparator cmp, Transformer trans);
 /*
        Add an element to the tree.
 
@@ -51,12 +51,12 @@ void *tree_add(Tree *tree, void *dat, Comparator cmp, Transformer func);
        Otherwise, return added element.
 */
 
-void *tree_get(Tree *tree, void *key, Comparator cmp, Transformer func);
+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 func);
+void *tree_del(Tree *tree, void *key, Comparator cmp, Transformer trans);
 /*
        Delete an element from the tree and return it, or NULL if none found.
 */
@@ -79,16 +79,16 @@ void tree_nrm(Tree *tree, TreeNode **node);
        Remove the node at the given location.
 */
 
-void tree_trv(Tree *tree, Iterator func, void *arg, TreeTraversionOrder order);
+void tree_trv(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
 /*
        Traverse the tree.
-       Calls func on every element, with the extra argument arg.
+       Calls iter on every element, with the extra argument arg.
 */
 
-void tree_clr(Tree *tree, Iterator func, void *arg, TreeTraversionOrder order);
+void tree_clr(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
 /*
        Traverses the tree and deletes all elements.
-       Calls func on every element, with the extra argument arg.
+       Calls iter on every element, with the extra argument arg.
 
        The tree is empty afterwards.
        If no callback is given, the traversion order is irrelevant.