-#include <stdlib.h> // for malloc, realloc, free, qsort
-#include <string.h> // for memmove, memcpy
+#include <stdlib.h> // for malloc, realloc, free, qsort
+#include <string.h> // for memmove, memcpy
#include "array.h"
+#include "bits/callback.h" // for Comparator
void array_ini(Array *array, size_t mbs, size_t ext)
{
array_ini(array, array->mbs, array->ext);
}
-void array_srt(Array *array, Comparator cmp)
+void array_srt(Array *array, void *cmp)
{
qsort(array->ptr, array->siz, array->mbs, cmp);
}
-ssize_t array_fnd(Array *array, const void *ptr, size_t *idx, Comparator cmp)
+ssize_t array_fnd(Array *array, const void *ptr, size_t *idx, void *cmp)
{
size_t low, high, mid;
while (low < high) {
mid = (low + high) / 2;
- int rel = cmp(ptr, array->ptr + mid * array->mbs);
+ int rel = ((Comparator) cmp)(ptr, array->ptr + mid * array->mbs);
if (rel == 0)
return idx ? (*idx = mid) : mid;
return -1;
}
-size_t array_ins(Array *array, const void *ptr, Comparator cmp)
+size_t array_ins(Array *array, const void *ptr, void *cmp)
{
size_t n;
#include <stddef.h> // for size_t
#include <sys/types.h> // for ssize_t
-#include "bits/callback.h" // for Comparator
#include "bits/compare.h" // for cmp_ref (not used in file)
typedef struct {
After this, the array is empty and can be reused.
*/
-void array_srt(Array *array, Comparator cmp);
+void array_srt(Array *array, void *cmp);
/*
Sorts the array using the quicksort algorithm.
Wraps the qsort C-library routine. Please refer to it's documentation.
*/
-ssize_t array_fnd(Array *array, const void *ptr, size_t *idx, Comparator cmp);
+ssize_t array_fnd(Array *array, const void *ptr, size_t *idx, void *cmp);
/*
Searches the sorted array for the element ptr.
Returns the index of the element, or -1 if it wasn't found.
and the order has been kept and the same comparator is used.
*/
-size_t array_ins(Array *array, const void *ptr, Comparator cmp);
+size_t array_ins(Array *array, const void *ptr, void *cmp);
/*
Inserts an element into a sorted array, keeping the order.
Returns the index the element has been inserted at.
+#include "callback.h" // for Transformer, Callback
+
#define WRAP_NODE_FUNCTIONS(Type, prefix) \
- bool prefix ## add(Type *self, void *dat, Comparator cmp, Transformer trans) \
+ bool prefix ## add(Type *self, void *dat, void *cmp, void *trans) \
{ \
Type ## Node **node = prefix ## nfd(self, dat, cmp); \
\
if (*node) \
return false; \
\
- prefix ## nmk(self, node, trans ? trans(dat) : dat); \
+ prefix ## nmk(self, node, trans ? ((Transformer) trans)(dat) : dat); \
return true; \
} \
\
- void *prefix ## get(Type *self, void *key, Comparator cmp, Transformer trans) \
+ void *prefix ## get(Type *self, void *key, void *cmp, void *trans) \
{ \
Type ## Node **node = prefix ## nfd(self, key, cmp); \
\
if (!*node) \
return NULL; \
\
- return trans ? trans((*node)->dat) : (*node)->dat; \
+ return trans ? ((Transformer) trans)((*node)->dat) : (*node)->dat; \
} \
\
- bool prefix ## del(Type *self, void *key, Comparator cmp, Callback call, void *arg, Transformer trans) \
+ bool prefix ## del(Type *self, void *key, void *cmp, void *call, void *arg, void *trans) \
{ \
Type ## Node **node = prefix ## nfd(self, key, cmp); \
\
return false; \
\
if (call) \
- call(trans ? trans((*node)->dat) : (*node)->dat, arg); \
+ ((Callback) call)(trans ? ((Transformer) trans)((*node)->dat) : (*node)->dat, arg); \
\
prefix ## nrm(self, node); \
return true; \
-#include <stdlib.h> // for malloc, free
-#include <string.h> // for strcmp
+#include <stdlib.h> // for malloc, free
+#include <string.h> // for strcmp
+#include "bits/callback.h" // for Callback, Comparator, Transformer
#include "bits/wrappers.h"
#include "list.h"
list->fst->nxt = fst;
}
-ListNode **list_nfd(List *list, void *key, Comparator cmp)
+ListNode **list_nfd(List *list, void *key, void *cmp)
{
ListNode **node;
for (ITER_REFS)
- if (cmp((*node)->dat, key) == 0)
+ if (((Comparator) cmp)((*node)->dat, key) == 0)
return node;
return node;
free(old);
}
-void list_itr(List *list, Callback iter, void *arg, Transformer trans)
+void list_itr(List *list, void *iter, void *arg, void *trans)
{
LIST_ITERATE(list, node)
- iter(trans ? trans(node->dat) : node->dat, arg);
+ ((Callback) iter)(trans ? ((Transformer) trans)(node->dat) : node->dat, arg);
}
-void list_clr(List *list, Callback iter, void *arg, Transformer trans)
+void list_clr(List *list, void *iter, void *arg, void *trans)
{
for (ListNode *node = list->fst; node != NULL;) {
ListNode *next = node->nxt;
if (iter)
- iter(trans ? trans(node->dat) : node->dat, arg);
+ ((Callback) iter)(trans ? ((Transformer) trans)(node->dat) : node->dat, arg);
free(node);
node = next;
#define _DRAGONSTD_LIST_H_
#include <stdbool.h> // for bool
-#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)
This function should be called before any other function is called on the list.
*/
-bool list_add(List *list, void *dat, Comparator cmp, Transformer trans);
+bool list_add(List *list, void *dat, void *cmp, void *trans);
/*
Add an element to the list.
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, void *cmp, void *trans);
/*
Get an element from the list.
The first matching element is returned, or NULL if none found.
*/
-bool list_del(List *list, void *key, Comparator cmp, Callback call, void *arg, Transformer trans);
+bool list_del(List *list, void *key, void *cmp, void *call, void *arg, void *trans);
/*
Delete an element from the list if it is found.
Return whether an element has been deleted.
Prepend an element at the start of the list.
*/
-ListNode **list_nfd(List *list, void *key, Comparator cmp);
+ListNode **list_nfd(List *list, void *key, void *cmp);
/*
Find the location of the first node matching key.
Remove the node at the given location.
*/
-void list_itr(List *list, Callback iter, void *arg, Transformer trans);
+void list_itr(List *list, void *iter, void *arg, void *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, Callback iter, void *arg, Transformer trans);
+void list_clr(List *list, void *iter, void *arg, void *trans);
/*
Iterates over the list and deletes all elements.
Calls iter on every element, with the extra argument arg.
+#include "bits/callback.h" // for Transformer
#include "map.h"
static bool get_lock(Map *map, bool write)
pthread_rwlock_destroy(&map->clk);
}
-void map_cnl(Map *map, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order)
+void map_cnl(Map *map, void *iter, void *arg, void *trans, TreeTraversionOrder order)
{
pthread_rwlock_wrlock(&map->clk);
map->cnl = true;
pthread_rwlock_unlock(&map->tlk);
}
-bool map_add(Map *map, void *dat, Comparator cmp, Transformer trans)
+bool map_add(Map *map, void *dat, void *cmp, void *trans)
{
if (!get_lock(map, true))
return false;
return ret;
}
-void *map_get(Map *map, void *key, Comparator cmp, Transformer trans)
+void *map_get(Map *map, void *key, void *cmp, void *trans)
{
if (!get_lock(map, false))
return NULL;
return ret;
}
-bool map_del(Map *map, void *key, Comparator cmp, Callback call, void *arg, Transformer trans)
+bool map_del(Map *map, void *key, void *cmp, void *call, void *arg, void *trans)
{
if (!get_lock(map, true))
return false;
return ret;
}
-void map_trv(Map *map, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order)
+void map_trv(Map *map, void *iter, void *arg, void *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, 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, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order);
+void map_cnl(Map *map, void *iter, void *arg, void *trans, TreeTraversionOrder order);
/*
[Thread Safe]
Cancels and clears the map.
If no callback is given, the traversion order is irrelevant.
*/
-bool map_add(Map *map, void *dat, Comparator cmp, Transformer trans);
+bool map_add(Map *map, void *dat, void *cmp, void *trans);
/*
[Thread Safe]
Add an element to the map.
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, void *cmp, void *trans);
/*
[Thread Safe]
Get an element from the map, or return NULL if none found.
*/
-bool map_del(Map *map, void *key, Comparator cmp, Callback call, void *arg, Transformer trans);
+bool map_del(Map *map, void *key, void *cmp, void *call, void *arg, void *trans);
/*
[Thread Safe]
Delete an element from the map if it is found.
Return whether an element has been deleted.
*/
-void map_trv(Map *map, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order);
+void map_trv(Map *map, void *iter, void *arg, void *trans, TreeTraversionOrder order);
/*
[Thread Safe]
Traverse the map.
-#include <sched.h>
+#include <sched.h> // for sched_yield
+#include "bits/callback.h" // for Transformer
#include "queue.h"
void queue_ini(Queue *queue)
pthread_mutex_destroy(&queue->mtx);
}
-void queue_clr(Queue *queue, Callback iter, void *arg, Transformer trans)
+void queue_clr(Queue *queue, void *iter, void *arg, void *trans)
{
list_clr(&queue->lst, iter, arg, trans);
}
return success;
}
-void *queue_deq(Queue *queue, Transformer trans)
+void *queue_deq(Queue *queue, void *trans)
{
void *dat = NULL;
list_nrm(&queue->lst, node);
if (trans)
- dat = trans(dat);
+ dat = ((Transformer) trans)(dat);
} else {
pthread_cond_wait(&queue->cnd, &queue->mtx);
}
#include <pthread.h> // for pthread_cond_t, pthread_mutex_t
#include <stdbool.h> // for bool
-#include "bits/callback.h" // for Transformer
#include "list.h" // for List
typedef struct {
list is cleared before calling this function.
*/
-void queue_clr(Queue *queue, Callback iter, void *arg, Transformer trans);
+void queue_clr(Queue *queue, void *iter, void *arg, void *trans);
/*
Clears the queue.
Notifies waiting consumer threads.
*/
-void *queue_deq(Queue *queue, Transformer trans);
+void *queue_deq(Queue *queue, void *trans);
/*
[Thread Safe]
Dequeue an element.
+#include "bits/callback.h" // for SingleCallback
#include "refcount.h"
-void refcount_ini(Refcount *refcount, void *obj, SingleCallback del)
+void refcount_ini(Refcount *refcount, void *obj, void *del)
{
refcount->obj = obj;
refcount->del = del;
pthread_mutex_unlock(&refcount->mtx);
if (!count)
- refcount->del(refcount->obj);
+ ((SingleCallback) refcount->del)(refcount->obj);
}
void *refcount_obj(Refcount *refcount)
#define _DRAGONSTD_REFCOUNT_H_
#include <pthread.h> // for pthread_mutex_t
-#include "bits/callback.h" // for Callback
typedef struct {
/* private */
void *obj;
- SingleCallback del;
+ void *del;
unsigned short cnt; // counter
pthread_mutex_t mtx; // lock to protect count
} Refcount;
-void refcount_ini(Refcount *refcount, void *obj, SingleCallback del);
+void refcount_ini(Refcount *refcount, void *obj, void *del);
/*
Initializes the refcount.
assert(arr.cap == 8);
printf("testing srt\n");
- array_srt(&arr, (void *) &cmp_int);
+ array_srt(&arr, &cmp_int);
printf("testing order: exp: (sorted) got: "); dump(&arr); printf("\n");
assert_in_order(&arr);
for (size_t j = 0; j < arr.siz; j++) {
i = ((int *) arr.ptr)[j];
- ssize_t s = array_fnd(&arr, &i, NULL, (void *) &cmp_int);
+ ssize_t s = array_fnd(&arr, &i, NULL, &cmp_int);
printf("testing fnd at index %lu: exp: >=0 got: %ld\n", j, s);
assert(s >= 0);
printf("testing ins\n");
for (int j = 0; j < 10; j++) {
- i = rand() % 100; array_ins(&arr, &i, (void *) &cmp_int);
+ i = rand() % 100; array_ins(&arr, &i, &cmp_int);
}
printf("testing order: exp: (sorted) got: "); dump(&arr); printf("\n");
#include <stdio.h>
#include "../list.h"
-int cmp_int(const void *ia, const void *ib)
+int cmp_int(const int *ia, const int *ib)
{
- return *(const int *) ia - *(const int *) ib;
+ return *ia - *ib;
}
int main()
Refcount rc;
} DataObject;
-void data_object_delete(DataObject *obj)
+int rand_id()
{
- refcount_dst(&obj->rc);
- free(obj);
+ return rand() % 1000;
}
-int rand_id()
+void delete_obj(DataObject *obj)
{
- return rand() % 1000;
+ refcount_dst(&obj->rc);
+ free(obj);
}
-int data_object_compare(const void *pa, const void *pb)
+int cmp_obj(const Refcount *rc, const int *id)
{
- return
- ((DataObject *) ((const Refcount *) pa)->obj)->id -
- ((DataObject *) ((const Refcount *) pb)->obj)->id;
+ return ((DataObject *) rc->obj)->id - *id;
}
-int data_object_compare_id(const void *pa, const void *pb)
+int cmp_obj_sym(const Refcount *rc1, const Refcount *rc2)
{
- return
- ((DataObject *) ((const Refcount *) pa)->obj)->id -
- *(const int *) pb;
+ return cmp_obj(rc1, &((DataObject *) rc2->obj)->id);
}
static void *thread_create(unsigned int *result)
DataObject *obj = malloc(sizeof *obj);
obj->id = rand_id();
- refcount_ini(&obj->rc, obj, (void *) &data_object_delete);
+ refcount_ini(&obj->rc, obj, &delete_obj);
- if (map_add(&map, &obj->rc, &data_object_compare, (void *) &refcount_inc))
+ if (map_add(&map, &obj->rc, &cmp_obj_sym, &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, (void *) &refcount_grb);
+ objs[i] = map_get(&map, &id, &cmp_obj, &refcount_grb);
}
if (objs[i])
while (!cancel) {
unsigned int id = rand_id();
- if (map_del(&map, &id, &data_object_compare_id, (void *) &refcount_drp, NULL, NULL))
+ if (map_del(&map, &id, &cmp_obj, &refcount_drp, NULL, NULL))
(*result)++;
}
results[i][0] += results[i][j];
}
- map_cnl(&map, (void *) &refcount_drp, NULL, NULL, 0);
+ map_cnl(&map, &refcount_drp, NULL, NULL, 0);
map_dst(&map);
printf("Time: 1 second\n");
#define NUM_ELEMENTS 1e5
-int cmp_int(const void *ia, const void *ib)
+int cmp_int(const int *ia, const int *ib)
{
- return *(const int *) ia - *(const int *) ib;
+ return *ia - *ib;
}
void clear_callback(int *ia, int *ib)
}
int last = -1;
- tree_clr(&tree, (void *) &clear_callback, &last, NULL, TRAVERSION_INORDER);
+ tree_clr(&tree, &clear_callback, &last, NULL, TRAVERSION_INORDER);
}
#include <stdlib.h> // for malloc, free
+#include "bits/callback.h" // for Callback, Comparator, Transformer
#include "bits/wrappers.h"
#include "tree.h"
WRAP_NODE_FUNCTIONS(Tree, tree_)
-TreeNode **tree_nfd(Tree *tree, void *key, Comparator cmp)
+TreeNode **tree_nfd(Tree *tree, void *key, void *cmp)
{
return search(&tree->rot, key, cmp);
}
free(old);
}
-void tree_trv(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order)
+void tree_trv(Tree *tree, void *iter, void *arg, void *trans, TreeTraversionOrder order)
{
traverse(tree->rot, iter, arg, trans, order, 0);
}
-void tree_clr(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order)
+void tree_clr(Tree *tree, void *iter, void *arg, void *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 Callback, 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.
*/
-bool tree_add(Tree *tree, void *dat, Comparator cmp, Transformer trans);
+bool tree_add(Tree *tree, void *dat, void *cmp, void *trans);
/*
Add an element to the tree.
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, void *cmp, void *trans);
/*
Get an element from the tree, or return NULL if none found.
*/
-bool tree_del(Tree *tree, void *key, Comparator cmp, Callback call, void *arg, Transformer trans);
+bool tree_del(Tree *tree, void *key, void *cmp, void *call, void *arg, void *trans);
/*
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, void *cmp);
/*
Find the location of a node matching key.
Remove the node at the given location.
*/
-void tree_trv(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order);
+void tree_trv(Tree *tree, void *iter, void *arg, void *trans, TreeTraversionOrder order);
/*
Traverse the tree.
Calls iter on every element, with the extra argument arg.
*/
-void tree_clr(Tree *tree, Callback iter, void *arg, Transformer trans, TreeTraversionOrder order);
+void tree_clr(Tree *tree, void *iter, void *arg, void *trans, TreeTraversionOrder order);
/*
Traverses the tree and deletes all elements.
Calls iter on every element, with the extra argument arg.