#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) \
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; \
}
#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)
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);
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);
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)
{
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);
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);
#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;
return refcount_obj(refcount_inc(refcount));
}
-void *refcount_drp(void *refcount)
+void refcount_drp(void *refcount)
{
Refcount *rc = 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)
#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;
- 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.
refcount.
*/
-void *refcount_drp(void *refcount);
+void refcount_drp(void *refcount);
/*
[Thread Safe]
Drop a reference to the object.
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);
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);
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");
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()
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);
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);
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");
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);
}
#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 {
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);
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);