346 #define cxTreeVisitorContinue(visitor) |
346 #define cxTreeVisitorContinue(visitor) |
347 |
347 |
348 void cxTreeVisitorDispose(CxTreeVisitor *visitor); |
348 void cxTreeVisitorDispose(CxTreeVisitor *visitor); |
349 ``` |
349 ``` |
350 |
350 |
351 There are two different kinds of iterators for trees. |
351 There are two different kinds of iterators for trees: one for depth-first iteration and one for breadth-first iteration. |
|
352 |
352 The `CxTreeIterator` is performing a depth-first iteration with the capability of visiting a node twice: |
353 The `CxTreeIterator` is performing a depth-first iteration with the capability of visiting a node twice: |
353 first when the iterator enters the node coming from its parent, and secondly when the iterator tracks back from its last child. |
354 first when the iterator enters the node coming from its parent, and secondly when the iterator tracks back from its last child. |
354 This behavior is controlled via the `visit_on_exit` argument. |
355 This behavior is controlled via the `visit_on_exit` argument. |
355 When set to `true`, the iterators `exiting` flag can be checked during iteration to see whether the iterator is currently entering or leaving the node. |
356 When set to `true`, the iterators `exiting` flag can be checked during iteration to see whether the iterator is currently entering or leaving the node. |
356 The above [example](#example-for-wrapping-a-libxml2-tree) for iterating through an XML tree illustrates this. |
357 The above [example](#example-for-wrapping-a-libxml2-tree) for iterating through an XML tree illustrates this. |
357 |
358 |
358 On the other hand, the `CxTreeVisitor` performs a breadth-first iteration and visits every node only once. |
359 On the other hand, the `CxTreeVisitor` performs a breadth-first iteration and visits every node only once. |
359 |
360 |
|
361 Both iterators do not support the removal of nodes. |
|
362 |
360 Since tree iteration needs to keep track of a stack (depth-first) or queue (breadth-first), internal memory is allocated. |
363 Since tree iteration needs to keep track of a stack (depth-first) or queue (breadth-first), internal memory is allocated. |
361 This memory is _automatically_ disposed of when the iteration _completes_. |
364 This memory is _automatically_ disposed of when the iteration _completes_. |
362 If you break from the iteration early, you must call `cxTreeIteratorDispose()` or `cxTreeVisitorDispose()`, respectively, to deallocate the memory. |
365 If you break from the iteration early, you must call `cxTreeIteratorDispose()` or `cxTreeVisitorDispose()`, respectively, to deallocate the memory. |
363 |
366 |
364 > It is recommended to always invoke the dispose functions, even when it seems not necessary. |
367 > It is recommended to always invoke the dispose functions, even when it seems not necessary. |