1.1 --- a/src/cx/tree.h Sun Feb 18 13:16:38 2024 +0100 1.2 +++ b/src/cx/tree.h Sun Feb 18 13:38:42 2024 +0100 1.3 @@ -45,28 +45,6 @@ 1.4 #endif 1.5 1.6 /** 1.7 - * When entering a node. 1.8 - * 1.9 - * When this is the first sibling, source is the parent, otherwise it is the previous child. 1.10 - */ 1.11 -#define CX_TREE_ITERATOR_ENTER 0x1 1.12 -/** 1.13 - * When advancing to the next child. 1.14 - * 1.15 - * The visited node is the next child and the source is the previous child. 1.16 - * This pass is triggered after exiting the previous child and before entering the next child. 1.17 - */ 1.18 -#define CX_TREE_ITERATOR_NEXT_CHILD 0x2 1.19 -/** 1.20 - * When exiting the node. 1.21 - * 1.22 - * The visited node is the node being exited and source is the previously entered node 1.23 - * (usually the last child of the exited node, unless it has no children, in which case it is the node itself). 1.24 - * When advancing to the next child in a list of siblings, the previous child is exited, first. 1.25 - */ 1.26 -#define CX_TREE_ITERATOR_EXIT 0x4 1.27 - 1.28 -/** 1.29 * Tree iterator. 1.30 * 1.31 * This iterator is not position-aware in a strict sense, as it does not assume a particular order of elements in the 1.32 @@ -74,9 +52,8 @@ 1.33 * Each node, regardless of the number of passes, is counted only once. 1.34 * 1.35 * @note Objects that are pointed to by an iterator are mutable through that iterator. However, if the 1.36 - * iterator is based on a collection and the underlying collection is mutated by other means than this iterator 1.37 - * (e.g. elements added or removed), the iterator becomes invalid (regardless of what cxIteratorValid() returns) 1.38 - * and MUST be re-obtained from the collection. 1.39 + * underlying data structure is mutated by other means than this iterator (e.g. elements added or removed), 1.40 + * the iterator becomes invalid (regardless of what cxIteratorValid() returns). 1.41 * 1.42 * @see CxIterator 1.43 */ 1.44 @@ -86,20 +63,14 @@ 1.45 */ 1.46 struct cx_iterator_base_s base; 1.47 /** 1.48 - * The passes that are requested by this iterator. 1.49 - * A combination of the flags #CX_TREE_ITERATOR_ENTER, #CX_TREE_ITERATOR_NEXT_CHILD, #CX_TREE_ITERATOR_EXIT. 1.50 - * 1.51 - * Changing the value after beginning the iteration is unspecified. 1.52 + * Set to true, when the iterator shall visit a node again 1.53 + * when all it's children have been processed. 1.54 */ 1.55 - uint8_t requested_passes; 1.56 + bool visit_on_exit; 1.57 /** 1.58 - * The current pass. 1.59 - * 1.60 - * @see CX_TREE_ITERATOR_ENTER 1.61 - * @see CX_TREE_ITERATOR_NEXT_CHILD 1.62 - * @see CX_TREE_ITERATOR_EXIT 1.63 + * True, if this iterator is currently leaving the node. 1.64 */ 1.65 - uint8_t current_pass; 1.66 + bool exiting; 1.67 /** 1.68 * Offset in the node struct for the children linked list. 1.69 */ 1.70 @@ -119,14 +90,6 @@ 1.71 */ 1.72 void *node; 1.73 /** 1.74 - * The node where we came from. 1.75 - * 1.76 - * - When entering the root node, this is \c NULL. 1.77 - * - When entering another node, this is the node's parent. 1.78 - * - When advancing to the next child, this is the previous child. 1.79 - */ 1.80 - void *source; 1.81 - /** 1.82 * Internal stack. 1.83 * Will be automatically freed once the iterator becomes invalid. 1.84 * 1.85 @@ -138,10 +101,16 @@ 1.86 * Internal capacity of the stack. 1.87 */ 1.88 size_t stack_capacity; 1.89 - /** 1.90 - * Current depth. 1.91 - */ 1.92 - size_t depth; 1.93 + union { 1.94 + /** 1.95 + * Internal stack size. 1.96 + */ 1.97 + size_t stack_size; 1.98 + /** 1.99 + * The current depth in the tree. 1.100 + */ 1.101 + size_t depth; 1.102 + }; 1.103 } CxTreeIterator; 1.104 1.105 /** 1.106 @@ -261,17 +230,6 @@ 1.107 /** 1.108 * Creates an iterator for a tree with the specified root node. 1.109 * 1.110 - * The \p passes argument is supposed to be a combination of the flags 1.111 - * #CX_TREE_ITERATOR_ENTER, #CX_TREE_ITERATOR_NEXT_CHILD, and #CX_TREE_ITERATOR_EXIT. 1.112 - * Alternatively, the integer 1 is equivalent to just specifying #CX_TREE_ITERATOR_ENTER 1.113 - * which will cause the iterator to pass every node only once (when entering the node). 1.114 - * 1.115 - * When #CX_TREE_ITERATOR_EXIT is set, the iterator will visit a parent node again, 1.116 - * when \em every of it's children has been visited (including the case when the node does not have any children). 1.117 - * 1.118 - * When #CX_TREE_ITERATOR_NEXT_CHILD is set, the iterator will visit a parent node again, 1.119 - * when advancing from one child to the next. 1.120 - * 1.121 * @note A tree iterator needs to maintain a stack of visited nodes, which is allocated using stdlib malloc(). 1.122 * When the iterator becomes invalid, this memory is automatically released. However, if you wish to cancel the 1.123 * iteration before the iterator becomes invalid by itself, you MUST call cxTreeIteratorDispose() manually to release 1.124 @@ -280,7 +238,7 @@ 1.125 * @remark At the moment, the returned iterator does not support cxIteratorFlagRemoval(). 1.126 * 1.127 * @param root the root node 1.128 - * @param passes the passes this iterator shall perform 1.129 + * @param visit_on_exit set to true, when the iterator shall visit a node again after processing all children 1.130 * @param loc_children offset in the node struct for the children linked list 1.131 * @param loc_next offset in the node struct for the next pointer 1.132 * @return the new tree iterator 1.133 @@ -289,7 +247,7 @@ 1.134 __attribute__((__nonnull__)) 1.135 CxTreeIterator cx_tree_iterator( 1.136 void *root, 1.137 - int passes, 1.138 + bool visit_on_exit, 1.139 ptrdiff_t loc_children, 1.140 ptrdiff_t loc_next 1.141 );