add functions to link/unlink nodes manually

Wed, 02 Oct 2024 19:11:40 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 02 Oct 2024 19:11:40 +0200
changeset 901
109567325fe7
parent 900
793fe631e877
child 902
5ed7f634f046

add functions to link/unlink nodes manually

relates to #166

src/cx/tree.h file | annotate | diff | comparison | revisions
src/tree.c file | annotate | diff | comparison | revisions
--- a/src/cx/tree.h	Mon Sep 30 19:19:44 2024 +0200
+++ b/src/cx/tree.h	Wed Oct 02 19:11:40 2024 +0200
@@ -794,6 +794,16 @@
     offsetof(struct cx_tree_node_base_s, next)
 
 /**
+ * Macro for obtaining the node pointer layout for a specific tree.
+ */
+#define cx_tree_node_layout(tree) \
+    (tree)->loc_parent,\
+    (tree)->loc_children,\
+    (tree)->loc_last_child,\
+    (tree)->loc_prev,  \
+    (tree)->loc_next
+
+/**
  * The class definition for arbitrary trees.
  */
 struct cx_tree_class_s {
@@ -1099,6 +1109,68 @@
     return tree->cl->visitor(tree);
 }
 
+/**
+ * Adds a new node to the tree.
+ *
+ * \attention The node may be externally created, but MUST obey the same rules
+ * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use
+ * the same allocator).
+ *
+ * @param tree the tree
+ * @param parent the parent of the node to add
+ * @param child the node to add
+ */
+__attribute__((__nonnull__))
+static inline void cxTreeAddChildNode(
+        CxTree *tree,
+        void *parent,
+        void *child) {
+    cx_tree_link(parent, child, cx_tree_node_layout(tree));
+    tree->size++;
+}
+
+/**
+ * Creates a new node and adds it to the tree.
+ *
+ * With this function you can decide where exactly the new node shall be added.
+ * If you specified an appropriate search function, you may want to consider
+ * leaving this task to the tree by using #cxTreeInsert().
+ *
+ * Be aware that adding nodes at arbitrary locations in the tree might cause
+ * wrong or undesired results when subsequently invoking #cxTreeInsert() and
+ * the invariant imposed by the search function does not hold any longer.
+ *
+ * @param tree the tree
+ * @param parent the parent node of the new node
+ * @param data the data that will be submitted to the create function
+ * @return zero when the new node was created, non-zero on allocation failure
+ * @see cxTreeInsert()
+ */
+__attribute__((__nonnull__))
+int cxTreeAddChild(
+        CxTree *tree,
+        void *parent,
+        const void *data
+);
+
+/**
+ * Removes a node from the tree.
+ *
+ * If the node is not part of the tree, the behavior is undefined.
+ *
+ * \note The destructor function, if any, will \em not be invoked.
+ *
+ * @param tree the tree
+ * @param node the node to remove
+ */
+__attribute__((__nonnull__))
+static inline void cxTreeRemove(
+        CxTree *tree,
+        void *node) {
+    cx_tree_unlink(node, cx_tree_node_layout(tree));
+    tree->size--;
+}
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
--- a/src/tree.c	Mon Sep 30 19:19:44 2024 +0200
+++ b/src/tree.c	Wed Oct 02 19:11:40 2024 +0200
@@ -666,3 +666,15 @@
                             loc_prev, loc_next);
 }
 
+
+int cxTreeAddChild(
+        CxTree *tree,
+        void *parent,
+        const void *data) {
+    void *node = tree->node_create(data, tree);
+    if (node == NULL) return 1;
+    cx_tree_zero_pointers(node, cx_tree_node_layout(tree));
+    cx_tree_link(parent, node, cx_tree_node_layout(tree));
+    tree->size++;
+    return 0;
+}

mercurial