aboutsummaryrefslogtreecommitdiff
path: root/src/rb_tree.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rb_tree.h')
-rw-r--r--src/rb_tree.h79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/rb_tree.h b/src/rb_tree.h
index 2f00bf0..7c91cea 100644
--- a/src/rb_tree.h
+++ b/src/rb_tree.h
@@ -28,6 +28,75 @@
#include <stdlib.h>
+#include "type_alias.h"
+
+#define TREE_MAP_DEF(K, V) \
+ typedef struct { \
+ RBNode rbnode; \
+ K key; \
+ V value; \
+ } K##2##V##TreeMapNode; \
+ typedef K##2##V##TreeMapNode *K##2##V##TreeMapIter; \
+ typedef struct { \
+ RBTree tree; \
+ } K##2##V##TreeMap; \
+ void K##2##V##TreeMap_init(K##2##V##TreeMap *self); \
+ K##2##V##TreeMapIter K##2##V##TreeMap_insert(K##2##V##TreeMap *self, K key, V value); \
+ K##2##V##TreeMapIter K##2##V##TreeMap_find(K##2##V##TreeMap *self, K key); \
+ V* K##2##V##TreeMap_get(K##2##V##TreeMap *self, K key); \
+ K##2##V##TreeMapIter K##2##V##TreeMap_next(K##2##V##TreeMap *self, K##2##V##TreeMapIter iter); \
+ void K##2##V##TreeMap_remove(K##2##V##TreeMap *self, K##2##V##TreeMapIter iter); \
+ K##2##V##TreeMapIter K##2##V##TreeMap_min(K##2##V##TreeMap *self); \
+ K##2##V##TreeMapIter K##2##V##TreeMap_max(K##2##V##TreeMap *self); \
+ K##2##V##TreeMapIter K##2##V##TreeMap_left(K##2##V##TreeMapIter iter); \
+ K##2##V##TreeMapIter K##2##V##TreeMap_right(K##2##V##TreeMapIter iter); \
+ K##2##V##TreeMapIter K##2##V##TreeMap_parent(K##2##V##TreeMapIter iter); \
+
+#define TREE_MAP_IMPL(K, V) \
+ static int K##2##V##TreeMap_cmp(void *vlhs, void *vrhs) { \
+ K *lhs = vlhs, *rhs = vrhs; \
+ return K##_cmp(*lhs, *rhs); \
+ } \
+ void K##2##V##TreeMap_init(K##2##V##TreeMap *self) { \
+ self->tree.rbh_root = NULL; \
+ self->tree.cmp = K##2##V##TreeMap_cmp; \
+ self->tree.augment = NULL; \
+ } \
+ K##2##V##TreeMapIter K##2##V##TreeMap_insert(K##2##V##TreeMap *self, K key, V value) { \
+ K##2##V##TreeMapNode *newnode = malloc(sizeof(K##2##V##TreeMapNode)); \
+ newnode->key = key; \
+ newnode->value = value; \
+ return rb_tree_insert(&self->tree, newnode); \
+ } \
+ K##2##V##TreeMapIter K##2##V##TreeMap_find(K##2##V##TreeMap *self, K key) { \
+ return rb_tree_find(&self->tree, &key); \
+ } \
+ V* K##2##V##TreeMap_get(K##2##V##TreeMap *self, K key) { \
+ K##2##V##TreeMapIter iter = rb_tree_find(&self->tree, &key); \
+ return &iter->value; \
+ } \
+ void K##2##V##TreeMap_remove(K##2##V##TreeMap *self, K##2##V##TreeMapIter iter) { \
+ rb_tree_remove(self, iter); \
+ } \
+ K##2##V##TreeMapIter K##2##V##TreeMap_next(K##2##V##TreeMap *self, K##2##V##TreeMapIter iter) { \
+ return rb_tree_next(&self->tree, iter); \
+ } \
+ K##2##V##TreeMapIter K##2##V##TreeMap_min(K##2##V##TreeMap *self) { \
+ return rb_tree_min(&self->tree); \
+ } \
+ K##2##V##TreeMapIter K##2##V##TreeMap_max(K##2##V##TreeMap *self) { \
+ return rb_tree_max(&self->tree); \
+ } \
+ K##2##V##TreeMapIter K##2##V##TreeMap_left(K##2##V##TreeMapIter iter) { \
+ return rb_tree_left(iter); \
+ } \
+ K##2##V##TreeMapIter K##2##V##TreeMap_right(K##2##V##TreeMapIter iter) { \
+ return rb_tree_right(iter); \
+ } \
+ K##2##V##TreeMapIter K##2##V##TreeMap_parent(K##2##V##TreeMapIter iter) { \
+ return rb_tree_parent(iter); \
+ } \
+
struct rb_node {
struct {
struct rb_node *rbe_left;
@@ -60,5 +129,15 @@ void *rb_tree_parent(void *node);
void destroy_rb_tree(RBTree *, void (*freeCb)(void *));
+TREE_MAP_DEF(String, Int);
+TREE_MAP_DEF(String, String);
+TREE_MAP_DEF(String, Double);
+TREE_MAP_DEF(String, VoidPtr);
+TREE_MAP_DEF(Int, Int);
+TREE_MAP_DEF(Int, Double);
+TREE_MAP_DEF(VoidPtr, Int);
+TREE_MAP_DEF(VoidPtr, String);
+TREE_MAP_DEF(VoidPtr, VoidPtr);
+
#endif