#ifndef _DRAGONSTD_CALLBACK_H_ // include guard
#define _DRAGONSTD_CALLBACK_H_
+typedef void (*SingleCallback)(void *dat);
+typedef void (*Callback)(void *dat, void *arg);
typedef void *(*Transformer)(void *dat);
-typedef void (*Callback)(void *dat);
-typedef void (*Iterator)(void *dat, void *arg);
typedef int (*Comparator)(const void *dat, const void *key);
#endif // _DRAGONSTD_CALLBACK_H_
return trans ? trans((*node)->dat) : (*node)->dat; \
} \
\
- bool prefix ## del(Type *self, void *key, Comparator cmp, Callback call) \
+ bool prefix ## del(Type *self, void *key, Comparator cmp, Callback call, void *arg) \
{ \
Type ## Node **node = prefix ## nfd(self, key, cmp); \
\
return false; \
\
if (call) \
- call((*node)->dat); \
+ call((*node)->dat, arg); \
\
prefix ## nrm(self, node); \
return true; \
void flag_uns(Flag *flag, pthread_cond_t *cnd)
{
pthread_mutex_lock(&flag->mtx);
- list_del(&flag->cvs, cnd, &cmp_ref, NULL);
+ list_del(&flag->cvs, cnd, &cmp_ref, NULL, NULL);
pthread_mutex_unlock(&flag->mtx);
}
free(old);
}
-void list_itr(List *list, Iterator iter, void *arg, Transformer trans)
+void list_itr(List *list, Callback iter, void *arg, Transformer trans)
{
LIST_ITERATE(list, node)
iter(trans ? trans(node->dat) : node->dat, arg);
}
-void list_clr(List *list, Iterator iter, void *arg, Transformer trans)
+void list_clr(List *list, Callback iter, void *arg, Transformer trans)
{
for (ListNode *node = list->fst; node != NULL;) {
ListNode *next = node->nxt;
#define _DRAGONSTD_LIST_H_
#include <stdbool.h> // for bool
-#include "bits/callback.h" // for Iterator, Comparator, Transformer, Callback
+#include "bits/callback.h" // for Callback, 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)
The first matching element is returned, or NULL if none found.
*/
-bool list_del(List *list, void *key, Comparator cmp, Callback call);
+bool list_del(List *list, void *key, Comparator cmp, Callback call, void *arg);
/*
Delete an element from the list if it is found.
Return whether an element has been deleted.
Remove the node at the given location.
*/
-void list_itr(List *list, Iterator iter, void *arg, Transformer trans);
+void list_itr(List *list, Callback iter, void *arg, Transformer trans);
/*
Iterate over the list.
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 iter, void *arg, Transformer trans);
+void list_clr(List *list, Callback iter, void *arg, Transformer trans);
/*
Iterates over the list and deletes all elements.
Calls iter on every element, with the extra argument arg.
pthread_rwlock_destroy(&map->clk);
}
-void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
+void map_cnl(Map *map, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order)
{
pthread_rwlock_wrlock(&map->clk);
map->cnl = true;
pthread_rwlock_unlock(&map->tlk);
}
-#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; \
- \
- type ret = tree_ ## name(&map->tre, dat, cmp, func); \
- pthread_rwlock_unlock(&map->tlk); \
- return ret; \
- }
+bool map_add(Map *map, void *dat, Comparator cmp, Transformer trans)
+{
+ if (!get_lock(map, true))
+ return false;
+
+ bool ret = tree_add(&map->tre, dat, cmp, trans);
+ pthread_rwlock_unlock(&map->tlk);
+ return ret;
+}
+
+void *map_get(Map *map, void *key, Comparator cmp, Transformer trans)
+{
+ if (!get_lock(map, false))
+ return NULL;
-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 *ret = tree_get(&map->tre, key, cmp, trans);
+ pthread_rwlock_unlock(&map->tlk);
+ return ret;
+}
+
+bool map_del(Map *map, void *key, Comparator cmp, Callback call, void *arg)
+{
+ if (!get_lock(map, true))
+ return false;
+
+ bool ret = tree_del(&map->tre, key, cmp, call, arg);
+ pthread_rwlock_unlock(&map->tlk);
+ return ret;
+}
-void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
+void map_trv(Map *map, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order)
{
if (!get_lock(map, false))
return;
#include <stdbool.h> // for bool
#include <pthread.h> // for pthread_rwlock_t
-#include "bits/callback.h" // for Transformer, Comparator, Iterator
+#include "bits/callback.h" // for Transformer, Comparator, Callback
#include "tree.h" // for Tree
typedef struct {
Make sure to cancel the map before destroying it, to avoid memory leaks.
*/
-void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
+void map_cnl(Map *map, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order);
/*
[Thread Safe]
Cancels and clears the map.
Get an element from the map, or return NULL if none found.
*/
-bool map_del(Map *map, void *key, Comparator cmp, Callback call);
+bool map_del(Map *map, void *key, Comparator cmp, Callback call, void *arg);
/*
[Thread Safe]
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, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order);
/*
[Thread Safe]
Traverse the map.
pthread_mutex_destroy(&queue->mtx);
}
-void queue_clr(Queue *queue, Iterator iter, void *arg, Transformer trans)
+void queue_clr(Queue *queue, Callback iter, void *arg, Transformer trans)
{
list_clr(&queue->lst, iter, arg, trans);
}
list is cleared before calling this function.
*/
-void queue_clr(Queue *queue, Iterator iter, void *arg, Transformer trans);
+void queue_clr(Queue *queue, Callback iter, void *arg, Transformer trans);
/*
Clears the queue.
#include "refcount.h"
-void refcount_ini(Refcount *refcount, void *obj, Callback del)
+void refcount_ini(Refcount *refcount, void *obj, SingleCallback del)
{
refcount->obj = obj;
refcount->del = del;
pthread_mutex_destroy(&refcount->mtx);
}
-void *refcount_inc(void *refcount)
+void *refcount_inc(Refcount *refcount)
{
- Refcount *rc = refcount;
-
- pthread_mutex_lock(&rc->mtx);
- rc->cnt++;
- pthread_mutex_unlock(&rc->mtx);
- return rc;
+ pthread_mutex_lock(&refcount->mtx);
+ refcount->cnt++;
+ pthread_mutex_unlock(&refcount->mtx);
+ return refcount;
}
-void *refcount_grb(void *refcount)
+void *refcount_grb(Refcount *refcount)
{
return refcount_obj(refcount_inc(refcount));
}
-void refcount_drp(void *refcount)
+void refcount_drp(Refcount *refcount)
{
- Refcount *rc = refcount;
-
- pthread_mutex_lock(&rc->mtx);
- unsigned short count = --rc->cnt;
- pthread_mutex_unlock(&rc->mtx);
+ pthread_mutex_lock(&refcount->mtx);
+ unsigned short count = --refcount->cnt;
+ pthread_mutex_unlock(&refcount->mtx);
if (!count)
- rc->del(rc->obj);
+ refcount->del(refcount->obj);
}
-void *refcount_obj(void *refcount)
+void *refcount_obj(Refcount *refcount)
{
- return ((Refcount *) refcount)->obj;
+ return refcount->obj;
}
typedef struct {
/* private */
void *obj;
- Callback del;
+ SingleCallback del;
unsigned short cnt; // counter
pthread_mutex_t mtx; // lock to protect count
} Refcount;
-void refcount_ini(Refcount *refcount, void *obj, Callback del);
+void refcount_ini(Refcount *refcount, void *obj, SingleCallback del);
/*
Initializes the refcount.
The refcount is unusable until reinitialized afterwards.
*/
-void *refcount_inc(void *refcount);
+void *refcount_inc(Refcount *refcount);
/*
[Thread Safe]
Grab a reference to the refcount.
- This actually takes a Refcount * as argument, however void * is used to make it more
- convenient to use the function as callback.
Returns the refcount.
*/
-void *refcount_grb(void *refcount);
+void *refcount_grb(Refcount *rc);
/*
[Thread Safe]
Does the same as refcount_inc, except it returns the referenced object instead of the
refcount.
*/
-void refcount_drp(void *refcount);
+void refcount_drp(Refcount *refcount);
/*
[Thread Safe]
Drop a reference to the object.
- This actually takes a Refcount * as argument, however void * is used to make it more
- convenient to use the function as callback.
May delete the object using the del function if the counter gets down to zero.
*/
-void *refcount_obj(void *refcount);
+void *refcount_obj(Refcount *refcount);
/*
[Thread Safe]
Return referenced object.
- This actually takes a Refcount * as argument, however void * is used to make it more
- convenient to use the function as callback.
*/
#endif // _DRAGONSTD_REFCOUNT_H_
assert(list_get(&list, &e, &cmp_int, NULL) == NULL);
printf("testing del\n");
- assert(list_del(&list, &a, &cmp_int, NULL));
+ assert(list_del(&list, &a, &cmp_int, NULL, NULL));
assert(list_get(&list, &a, &cmp_int, NULL) == NULL);
printf("testing clr\n");
refcount_ini(&obj->rc, obj, (void *) &data_object_delete);
- if (map_add(&map, &obj->rc, &data_object_compare, &refcount_inc))
+ if (map_add(&map, &obj->rc, &data_object_compare, (void *) &refcount_inc))
(*result)++;
refcount_drp(&obj->rc);
while (!objs[i] && !cancel) {
int id = rand_id();
- objs[i] = map_get(&map, &id, &data_object_compare_id, &refcount_grb);
+ objs[i] = map_get(&map, &id, &data_object_compare_id, (void *) &refcount_grb);
}
if (objs[i])
while (!cancel) {
unsigned int id = rand_id();
- if (map_del(&map, &id, &data_object_compare_id, &refcount_drp))
+ if (map_del(&map, &id, &data_object_compare_id, (void *) &refcount_drp, NULL))
(*result)++;
}
assert(tree_get(&tree, &e, &cmp_int, NULL) == NULL);
printf("testing del\n");
- assert(tree_del(&tree, &a, &cmp_int, NULL));
+ assert(tree_del(&tree, &a, &cmp_int, NULL, NULL));
assert(tree_get(&tree, &a, &cmp_int, NULL) == NULL);
printf("testing clr\n");
return search(&(*node)->rgt, key, cmp);
}
-static inline void traverse(TreeNode *node, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order, int delete)
+static inline void traverse(TreeNode *node, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order, int delete)
{
if (!node)
return;
free(old);
}
-void tree_trv(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
+void tree_trv(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order)
{
traverse(tree->rot, iter, arg, trans, order, 0);
}
-void tree_clr(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
+void tree_clr(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order)
{
traverse(tree->rot, iter, arg, trans, order, 1);
tree_ini(tree);
#define _DRAGONSTD_TREE_H_
#include <stdbool.h> // for bool
-#include "bits/callback.h" // for Iterator, Comparator, Transformer, Callback
+#include "bits/callback.h" // for Callback, Comparator, Transformer, Callback
#include "bits/compare.h" // for cmp_ref (not used in file)
typedef struct TreeNode {
Get an element from the tree, or return NULL if none found.
*/
-bool tree_del(Tree *tree, void *key, Comparator cmp, Callback call);
+bool tree_del(Tree *tree, void *key, Comparator cmp, Callback call, void *arg);
/*
Delete an element from the tree if it is found.
Return whether an element has been deleted.
Remove the node at the given location.
*/
-void tree_trv(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
+void tree_trv(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order);
/*
Traverse the tree.
Calls iter on every element, with the extra argument arg.
*/
-void tree_clr(Tree *tree, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order);
+void tree_clr(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order);
/*
Traverses the tree and deletes all elements.
Calls iter on every element, with the extra argument arg.