@@ -30,6 +30,9 @@ namespace tools {
3030// / @param op user-supplied functor, see examples for interface details.
3131// / @param idx optional offset to start sequential node indexing from a
3232// / non-zero index.
33+ // / @param topDown if true, visit parent nodes before their children
34+ // / (pre-order traversal). If false, visit children before
35+ // / their parent nodes (post-order traversal). Defaults to true.
3336// /
3437// / @warning This method is single-threaded. Use the NodeManager or
3538// / DynamicNodeManager for much greater threaded performance.
@@ -173,7 +176,7 @@ namespace tools {
173176// /
174177// / @endcode
175178template <typename TreeT, typename OpT>
176- size_t visitNodesDepthFirst (TreeT& tree, OpT& op, size_t idx = 0 );
179+ size_t visitNodesDepthFirst (TreeT& tree, OpT& op, size_t idx = 0 , bool topDown = true );
177180
178181
179182// / @brief Visit all nodes that are downstream of a specific node in
@@ -199,14 +202,15 @@ struct DepthFirstNodeVisitor
199202 using ChildNodeType = typename CopyConstness<NodeT, NonConstChildType>::Type;
200203
201204 template <typename OpT>
202- static size_t visit (NodeT& node, OpT& op, size_t idx = 0 )
205+ static size_t visit (NodeT& node, OpT& op, size_t idx = 0 , bool topDown = true )
203206 {
204207 size_t offset = 0 ;
205- op (node, idx + offset++);
208+ if (topDown) op (node, idx + offset++);
206209 for (auto iter = node.beginChildOn (); iter; ++iter) {
207210 offset += DepthFirstNodeVisitor<ChildNodeType>::visit (
208- *iter, op, idx + offset);
211+ *iter, op, idx + offset, topDown );
209212 }
213+ if (!topDown) op (node, idx + offset++);
210214 return offset;
211215 }
212216};
@@ -217,7 +221,7 @@ template <typename NodeT>
217221struct DepthFirstNodeVisitor <NodeT, 0 >
218222{
219223 template <typename OpT>
220- static size_t visit (NodeT& node, OpT& op, size_t idx = 0 )
224+ static size_t visit (NodeT& node, OpT& op, size_t idx = 0 , bool /* topDown */ = true )
221225 {
222226 op (node, idx);
223227 return size_t (1 );
@@ -226,12 +230,12 @@ struct DepthFirstNodeVisitor<NodeT, 0>
226230
227231
228232template <typename TreeT, typename OpT>
229- size_t visitNodesDepthFirst (TreeT& tree, OpT& op, size_t idx)
233+ size_t visitNodesDepthFirst (TreeT& tree, OpT& op, size_t idx, bool topDown )
230234{
231235 using NonConstRootNodeType = typename TreeT::RootNodeType;
232236 using RootNodeType = typename CopyConstness<TreeT, NonConstRootNodeType>::Type;
233237
234- return DepthFirstNodeVisitor<RootNodeType>::visit (tree.root (), op, idx);
238+ return DepthFirstNodeVisitor<RootNodeType>::visit (tree.root (), op, idx, topDown );
235239}
236240
237241
0 commit comments