24 #ifndef __DepthFirstTreeIterator__ 25 #define __DepthFirstTreeIterator__ 28 #include "boost/graph/graph_traits.hpp" 29 #include "boost/graph/properties.hpp" 30 #include "boost/iterator_adaptors.hpp" 31 #include "boost/optional.hpp" 40 enum graph_tree_root_t { graph_tree_root = 9901 };
41 enum graph_tree_end_t { graph_tree_end = 9902 };
43 BOOST_INSTALL_PROPERTY(graph, tree_root);
44 BOOST_INSTALL_PROPERTY(graph, tree_end);
55 template <
class Graph,
class VisitChildrenPredicate,
class VisitNodePredicate>
56 struct DepthFirstTreeIteratorPolicies :
public boost::default_iterator_policies
58 DepthFirstTreeIteratorPolicies() : fGraph(NULL) {}
59 DepthFirstTreeIteratorPolicies(
const Graph& g ) : fGraph(&g) {}
64 template <
class IteratorAdaptor>
65 typename IteratorAdaptor::reference dereference(IteratorAdaptor x)
const 66 {
return *
get(x.base()); }
70 template <
class IteratorAdaptor>
71 void increment(IteratorAdaptor& x) { advance(x, 1); }
77 template <
class IteratorAdaptor,
class DifferenceType>
78 void advance(IteratorAdaptor& x, DifferenceType n)
const;
87 template <
class IteratorAdaptor>
88 typename boost::graph_traits<Graph>::vertex_descriptor getParentVertex(IteratorAdaptor x)
const 90 return source(*
get(x.base()), *fGraph);
108 template <
class Graph,
class VisitChildrenPredicate,
class VisitNodePredicate>
109 template <
class IteratorAdaptor,
class DifferenceType>
110 void DepthFirstTreeIteratorPolicies<Graph, VisitChildrenPredicate, VisitNodePredicate>::advance(IteratorAdaptor& x, DifferenceType n)
const 114 VisitChildrenPredicate should_visit_children;
115 VisitNodePredicate should_visit_me;
116 using namespace boost;
119 bool ranOutOfCandidates(
false);
121 typename boost::graph_traits<Graph>::out_edge_iterator e, end;
122 boost::tie(e, end) = out_edges(target(*
get(x.base()), *fGraph), *fGraph);
123 ranOutOfCandidates =
false;
124 if(e != end && should_visit_children(target(*
get(x.base()), *fGraph), *fGraph)){
129 bool parentIsRoot(
false);
130 bool foundNonSingularCandidate(
false);
131 ranOutOfCandidates =
false;
132 typename boost::graph_traits<Graph>::vertex_descriptor parentVertex;
133 while(!(foundNonSingularCandidate || ranOutOfCandidates)){
134 typename boost::graph_traits<Graph>::out_edge_iterator parentEndEdge(out_edges(getParentVertex(x), *fGraph).second);
135 foundNonSingularCandidate = boost::next(
get(x.base())) != parentEndEdge;
136 if(foundNonSingularCandidate){
141 parentVertex = getParentVertex(x);
142 parentIsRoot = parentVertex ==
get(boost::graph_tree_root, *fGraph);
146 typename boost::graph_traits<Graph>::in_edge_iterator in_i, in_end;
147 tie(in_i, in_end) = in_edges(parentVertex, *fGraph);
148 ASSERT(in_i != in_end && boost::next(in_i) == in_end);
149 typename boost::graph_traits<Graph>::out_edge_iterator out_i, out_end;
150 tie(out_i, out_end) = out_edges(source(*in_i, *fGraph), *fGraph);
151 get(x.base()) = std::find(out_i, out_end, *in_i);
152 ASSERT(
get(x.base()) != out_end);
155 ranOutOfCandidates =
true;
163 done = ranOutOfCandidates || should_visit_me(target(*
get(x.base()), *fGraph), *fGraph);
165 if(ranOutOfCandidates){
170 x.policies() = DepthFirstTreeIteratorPolicies<Graph, VisitChildrenPredicate, VisitNodePredicate>();
183 template <
class Graph>
185 bool operator()(
typename boost::graph_traits<Graph>::vertex_descriptor v,
const Graph&)
199 template <
class Graph,
class VisitChildrenPred = VisitTruePred<Graph>,
class VisitElementPred = VisitTruePred<Graph> >
201 typedef boost::iterator_adaptor<
202 boost::optional<typename boost::graph_traits<Graph>::out_edge_iterator> ,
203 boost::optional<typename boost::graph_traits<Graph>::out_edge_iterator>,
204 typename boost::graph_traits<Graph>::edge_descriptor ,
205 boost::forward_traversal_tag,
206 typename boost::graph_traits<Graph>::edge_descriptor ,
212 #endif //__DepthFirstTreeIterator__