first draft of a tree iterator

Fri, 16 Feb 2024 20:23:48 +0100

author
Mike Becker <universe@uap-core.de>
date
Fri, 16 Feb 2024 20:23:48 +0100
changeset 827
13b40a598d16
parent 826
21840975d541
child 828
88fa3381206d

first draft of a tree iterator

see issue #371

src/cx/tree.h file | annotate | diff | comparison | revisions
--- a/src/cx/tree.h	Thu Feb 15 21:54:43 2024 +0100
+++ b/src/cx/tree.h	Fri Feb 16 20:23:48 2024 +0100
@@ -38,10 +38,102 @@
 
 #include "common.h"
 
+#include "iterator.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ * When entering a node.
+ */
+#define CX_TREE_ITERATOR_ENTER      0x1
+/**
+ * When advancing to the next child.
+ */
+#define CX_TREE_ITERATOR_NEXT_CHILD 0x2
+/**
+ * When exiting the node.
+ */
+#define CX_TREE_ITERATOR_EXIT       0x4
+
+/**
+ * Tree iterator.
+ *
+ * This iterator is not position-aware in a strict sense, as it does not assume a particular order of elements in the
+ * tree. However, the iterator keeps track of the number of nodes it has passed in a counter variable.
+ * Each node, regardless of the number of passes, is counted only once.
+ *
+ * @note Objects that are pointed to by an iterator are mutable through that iterator. However, if the
+ * iterator is based on a collection and the underlying collection is mutated by other means than this iterator
+ * (e.g. elements added or removed), the iterator becomes invalid (regardless of what cxIteratorValid() returns)
+ * and MUST be re-obtained from the collection.
+ *
+ * @see CxIterator
+ */
+typedef struct cx_tree_iterator_s {
+    /**
+     * The base properties of this iterator.
+     */
+    struct cx_iterator_base_s base;
+    /**
+     * The passes that are requested by this iterator.
+     * A combination of the flags #CX_TREE_ITERATOR_ENTER, #CX_TREE_ITERATOR_NEXT_CHILD, #CX_TREE_ITERATOR_EXIT.
+     *
+     * Changing the value after beginning the iteration is unspecified.
+     */
+    uint8_t requested_passes;
+    /**
+     * The current pass.
+     *
+     * @see CX_TREE_ITERATOR_ENTER
+     * @see CX_TREE_ITERATOR_NEXT_CHILD
+     * @see CX_TREE_ITERATOR_EXIT
+     */
+    uint8_t current_pass;
+    /**
+     * Offset in the node struct for the children linked list.
+     */
+    off_t loc_children;
+    /**
+     * Offset in the node struct for the next pointer.
+     */
+    off_t loc_next;
+    /**
+     * The total number of distinct nodes that have been passed so far.
+     */
+    size_t counter;
+    /**
+     * The currently observed node.
+     *
+     * This is the same what cxIteratorCurrent() would return.
+     */
+    void *node;
+    /**
+     * The node where we came from.
+     *
+     * - When entering the root node, this is \c NULL.
+     * - When entering another node, this is the node's parent.
+     * - When advancing to the next child, this is the previous child.
+     */
+    void *source;
+    /**
+     * Internal stack.
+     * Will be automatically freed once the iterator becomes invalid.
+     *
+     * If you want to discard the iterator before, you need to manually
+     * call cxTreeIteratorDispose().
+     */
+    void **stack;
+} CxTreeIterator;
+
+/**
+ * Releases internal memory of the given tree iterator.
+ * @param iter the iterator
+ */
+static inline void cxTreeIteratorDispose(CxTreeIterator *iter) {
+    free(iter->stack);
+}
 
 /**
  * Links a node to a (new) parent.

mercurial