src/tree.c

changeset 902
5ed7f634f046
parent 901
109567325fe7
child 903
a018f5916d3b
--- a/src/tree.c	Wed Oct 02 19:11:40 2024 +0200
+++ b/src/tree.c	Thu Oct 03 15:38:05 2024 +0200
@@ -666,6 +666,91 @@
                             loc_prev, loc_next);
 }
 
+static void cx_tree_default_destructor(CxTree *tree) {
+    // TODO: destroy the nodes
+    cxFree(tree->allocator, tree);
+}
+
+static CxTreeIterator cx_tree_default_iterator(
+        CxTree *tree,
+        bool visit_on_exit
+) {
+    return cx_tree_iterator(
+            tree->root, visit_on_exit,
+            tree->loc_children, tree->loc_next
+    );
+}
+
+static CxTreeVisitor cx_tree_default_visitor(CxTree *tree) {
+    return cx_tree_visitor(tree->root, tree->loc_children, tree->loc_next);
+}
+
+static cx_tree_class cx_tree_default_class = {
+        cx_tree_default_destructor,
+        NULL,
+        NULL,
+        NULL,
+        cx_tree_default_iterator,
+        cx_tree_default_visitor
+};
+
+CxTree *cxTreeCreate(
+        const CxAllocator *allocator,
+        cx_tree_node_create_func create_func,
+        cx_tree_search_func search_func,
+        ptrdiff_t loc_parent,
+        ptrdiff_t loc_children,
+        ptrdiff_t loc_last_child,
+        ptrdiff_t loc_prev,
+        ptrdiff_t loc_next
+) {
+    CxTree *tree = cxMalloc(allocator, sizeof(CxTree));
+    if (tree == NULL) return NULL;
+
+    tree->cl = &cx_tree_default_class;
+    tree->allocator = allocator;
+    tree->node_create = create_func;
+    tree->search = search_func;
+    tree->advanced_destructor = (cx_destructor_func2) cxFree;
+    tree->destructor_data = (void *) allocator;
+    tree->loc_parent = loc_parent;
+    tree->loc_children = loc_children;
+    tree->loc_last_child = loc_last_child;
+    tree->loc_prev = loc_prev;
+    tree->loc_next = loc_next;
+    tree->root = NULL;
+    tree->size = 0;
+
+    return tree;
+}
+
+CxTree *cxTreeCreateWrapped(
+        void *root,
+        ptrdiff_t loc_parent,
+        ptrdiff_t loc_children,
+        ptrdiff_t loc_last_child,
+        ptrdiff_t loc_prev,
+        ptrdiff_t loc_next
+) {
+    CxTree *tree = malloc(sizeof(CxTree));
+    if (tree == NULL) return NULL;
+
+    tree->cl = &cx_tree_default_class;
+    // set the allocator anyway, just in case...
+    tree->allocator = cxDefaultAllocator;
+    tree->node_create = NULL;
+    tree->search = NULL;
+    tree->advanced_destructor = NULL;
+    tree->destructor_data = NULL;
+    tree->loc_parent = loc_parent;
+    tree->loc_children = loc_children;
+    tree->loc_last_child = loc_last_child;
+    tree->loc_prev = loc_prev;
+    tree->loc_next = loc_next;
+    tree->root = root;
+    tree->size = cxTreeSubtreeSize(tree, root);
+    return tree;
+}
 
 int cxTreeAddChild(
         CxTree *tree,
@@ -678,3 +763,15 @@
     tree->size++;
     return 0;
 }
+
+size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root) {
+    CxTreeVisitor visitor = cx_tree_visitor(
+            subtree_root,
+            tree->loc_children,
+            tree->loc_next
+    );
+    while (cxIteratorValid(visitor)) {
+        cxIteratorNext(visitor);
+    }
+    return visitor.counter;
+}

mercurial