src/cx/tree.h

changeset 833
5c926801f052
parent 830
c4dae6fe6d5b
child 835
13068743197f
equal deleted inserted replaced
832:97df2e4c68fb 833:5c926801f052
43 #ifdef __cplusplus 43 #ifdef __cplusplus
44 extern "C" { 44 extern "C" {
45 #endif 45 #endif
46 46
47 /** 47 /**
48 * When entering a node.
49 *
50 * When this is the first sibling, source is the parent, otherwise it is the previous child.
51 */
52 #define CX_TREE_ITERATOR_ENTER 0x1
53 /**
54 * When advancing to the next child.
55 *
56 * The visited node is the next child and the source is the previous child.
57 * This pass is triggered after exiting the previous child and before entering the next child.
58 */
59 #define CX_TREE_ITERATOR_NEXT_CHILD 0x2
60 /**
61 * When exiting the node.
62 *
63 * The visited node is the node being exited and source is the previously entered node
64 * (usually the last child of the exited node, unless it has no children, in which case it is the node itself).
65 * When advancing to the next child in a list of siblings, the previous child is exited, first.
66 */
67 #define CX_TREE_ITERATOR_EXIT 0x4
68
69 /**
70 * Tree iterator. 48 * Tree iterator.
71 * 49 *
72 * This iterator is not position-aware in a strict sense, as it does not assume a particular order of elements in the 50 * This iterator is not position-aware in a strict sense, as it does not assume a particular order of elements in the
73 * tree. However, the iterator keeps track of the number of nodes it has passed in a counter variable. 51 * tree. However, the iterator keeps track of the number of nodes it has passed in a counter variable.
74 * Each node, regardless of the number of passes, is counted only once. 52 * Each node, regardless of the number of passes, is counted only once.
75 * 53 *
76 * @note Objects that are pointed to by an iterator are mutable through that iterator. However, if the 54 * @note Objects that are pointed to by an iterator are mutable through that iterator. However, if the
77 * iterator is based on a collection and the underlying collection is mutated by other means than this iterator 55 * underlying data structure is mutated by other means than this iterator (e.g. elements added or removed),
78 * (e.g. elements added or removed), the iterator becomes invalid (regardless of what cxIteratorValid() returns) 56 * the iterator becomes invalid (regardless of what cxIteratorValid() returns).
79 * and MUST be re-obtained from the collection.
80 * 57 *
81 * @see CxIterator 58 * @see CxIterator
82 */ 59 */
83 typedef struct cx_tree_iterator_s { 60 typedef struct cx_tree_iterator_s {
84 /** 61 /**
85 * The base properties of this iterator. 62 * The base properties of this iterator.
86 */ 63 */
87 struct cx_iterator_base_s base; 64 struct cx_iterator_base_s base;
88 /** 65 /**
89 * The passes that are requested by this iterator. 66 * Set to true, when the iterator shall visit a node again
90 * A combination of the flags #CX_TREE_ITERATOR_ENTER, #CX_TREE_ITERATOR_NEXT_CHILD, #CX_TREE_ITERATOR_EXIT. 67 * when all it's children have been processed.
91 * 68 */
92 * Changing the value after beginning the iteration is unspecified. 69 bool visit_on_exit;
93 */ 70 /**
94 uint8_t requested_passes; 71 * True, if this iterator is currently leaving the node.
95 /** 72 */
96 * The current pass. 73 bool exiting;
97 *
98 * @see CX_TREE_ITERATOR_ENTER
99 * @see CX_TREE_ITERATOR_NEXT_CHILD
100 * @see CX_TREE_ITERATOR_EXIT
101 */
102 uint8_t current_pass;
103 /** 74 /**
104 * Offset in the node struct for the children linked list. 75 * Offset in the node struct for the children linked list.
105 */ 76 */
106 off_t loc_children; 77 off_t loc_children;
107 /** 78 /**
116 * The currently observed node. 87 * The currently observed node.
117 * 88 *
118 * This is the same what cxIteratorCurrent() would return. 89 * This is the same what cxIteratorCurrent() would return.
119 */ 90 */
120 void *node; 91 void *node;
121 /**
122 * The node where we came from.
123 *
124 * - When entering the root node, this is \c NULL.
125 * - When entering another node, this is the node's parent.
126 * - When advancing to the next child, this is the previous child.
127 */
128 void *source;
129 /** 92 /**
130 * Internal stack. 93 * Internal stack.
131 * Will be automatically freed once the iterator becomes invalid. 94 * Will be automatically freed once the iterator becomes invalid.
132 * 95 *
133 * If you want to discard the iterator before, you need to manually 96 * If you want to discard the iterator before, you need to manually
136 void **stack; 99 void **stack;
137 /** 100 /**
138 * Internal capacity of the stack. 101 * Internal capacity of the stack.
139 */ 102 */
140 size_t stack_capacity; 103 size_t stack_capacity;
141 /** 104 union {
142 * Current depth. 105 /**
143 */ 106 * Internal stack size.
144 size_t depth; 107 */
108 size_t stack_size;
109 /**
110 * The current depth in the tree.
111 */
112 size_t depth;
113 };
145 } CxTreeIterator; 114 } CxTreeIterator;
146 115
147 /** 116 /**
148 * Releases internal memory of the given tree iterator. 117 * Releases internal memory of the given tree iterator.
149 * @param iter the iterator 118 * @param iter the iterator
259 ); 228 );
260 229
261 /** 230 /**
262 * Creates an iterator for a tree with the specified root node. 231 * Creates an iterator for a tree with the specified root node.
263 * 232 *
264 * The \p passes argument is supposed to be a combination of the flags
265 * #CX_TREE_ITERATOR_ENTER, #CX_TREE_ITERATOR_NEXT_CHILD, and #CX_TREE_ITERATOR_EXIT.
266 * Alternatively, the integer 1 is equivalent to just specifying #CX_TREE_ITERATOR_ENTER
267 * which will cause the iterator to pass every node only once (when entering the node).
268 *
269 * When #CX_TREE_ITERATOR_EXIT is set, the iterator will visit a parent node again,
270 * when \em every of it's children has been visited (including the case when the node does not have any children).
271 *
272 * When #CX_TREE_ITERATOR_NEXT_CHILD is set, the iterator will visit a parent node again,
273 * when advancing from one child to the next.
274 *
275 * @note A tree iterator needs to maintain a stack of visited nodes, which is allocated using stdlib malloc(). 233 * @note A tree iterator needs to maintain a stack of visited nodes, which is allocated using stdlib malloc().
276 * When the iterator becomes invalid, this memory is automatically released. However, if you wish to cancel the 234 * When the iterator becomes invalid, this memory is automatically released. However, if you wish to cancel the
277 * iteration before the iterator becomes invalid by itself, you MUST call cxTreeIteratorDispose() manually to release 235 * iteration before the iterator becomes invalid by itself, you MUST call cxTreeIteratorDispose() manually to release
278 * the memory. 236 * the memory.
279 * 237 *
280 * @remark At the moment, the returned iterator does not support cxIteratorFlagRemoval(). 238 * @remark At the moment, the returned iterator does not support cxIteratorFlagRemoval().
281 * 239 *
282 * @param root the root node 240 * @param root the root node
283 * @param passes the passes this iterator shall perform 241 * @param visit_on_exit set to true, when the iterator shall visit a node again after processing all children
284 * @param loc_children offset in the node struct for the children linked list 242 * @param loc_children offset in the node struct for the children linked list
285 * @param loc_next offset in the node struct for the next pointer 243 * @param loc_next offset in the node struct for the next pointer
286 * @return the new tree iterator 244 * @return the new tree iterator
287 * @see cxTreeIteratorDispose() 245 * @see cxTreeIteratorDispose()
288 */ 246 */
289 __attribute__((__nonnull__)) 247 __attribute__((__nonnull__))
290 CxTreeIterator cx_tree_iterator( 248 CxTreeIterator cx_tree_iterator(
291 void *root, 249 void *root,
292 int passes, 250 bool visit_on_exit,
293 ptrdiff_t loc_children, 251 ptrdiff_t loc_children,
294 ptrdiff_t loc_next 252 ptrdiff_t loc_next
295 ); 253 );
296 254
297 #ifdef __cplusplus 255 #ifdef __cplusplus

mercurial