Fun TreeDepthFirstTraverse(TTreeNode& tree_node, Fun func) { int delta_level = 0; ETreeTraverseCode stop_scan; stop_scan = func(tree_node, delta_level); switch (stop_scan) { case eTreeTraverseStop: case eTreeTraverseStepOver: return func; case eTreeTraverse: break; } if (stop_scan) return func; delta_level = 1; TTreeNode* tr = &tree_node; typedef typename TTreeNode::TNodeList_I TTreeNodeIterator; TTreeNodeIterator it = tr->SubNodeBegin(); TTreeNodeIterator it_end = tr->SubNodeEnd(); if (it == it_end) return func; stack<TTreeNodeIterator> tree_stack; while (true) { tr = (TTreeNode*)*it; stop_scan = eTreeTraverse; if (tr) { stop_scan = func(*tr, delta_level); switch (stop_scan) { case eTreeTraverseStop: return func; case eTreeTraverse: case eTreeTraverseStepOver: break; } } if ( (stop_scan != eTreeTraverseStepOver) && (delta_level >= 0) && (!tr->IsLeaf())) { // sub-node, going down tree_stack.push(it); it = tr->SubNodeBegin(); it_end = tr->SubNodeEnd(); delta_level = 1; continue; } ++it; if (it == it_end) { // end of level, going up if (tree_stack.empty()) { break; } it = tree_stack.top(); tree_stack.pop(); tr = (TTreeNode*)*it; it_end = tr->GetParent()->SubNodeEnd(); delta_level = -1; continue; } // same level delta_level = 0; } // while func(tree_node, -1); return func; }