InDesign SDK  20.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
DepthFirstTreeIterator.h
1 //========================================================================================
2 //
3 // $File$
4 //
5 // Owner: Mat Marcus
6 //
7 // $Author$
8 //
9 // $DateTime$
10 //
11 // $Revision$
12 //
13 // $Change$
14 //
15 // Copyright 1997-2010 Adobe Systems Incorporated. All rights reserved.
16 //
17 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance
18 // with the terms of the Adobe license agreement accompanying it. If you have received
19 // this file from a source other than Adobe, then your use, modification, or
20 // distribution of it requires the prior written permission of Adobe.
21 //
22 //========================================================================================
23 
24 #ifndef __DepthFirstTreeIterator__
25 #define __DepthFirstTreeIterator__
26 
27 
28 #include "boost/graph/graph_traits.hpp"
29 #include "boost/graph/properties.hpp"
30 #include "boost/iterator_adaptors.hpp"
31 #include "boost/optional.hpp"
32 
33 #ifndef ASSERT
34 #include <cassert>
35 #define ASSERT assert
36 #endif
37 
38 
39 namespace boost {
40  enum graph_tree_root_t { graph_tree_root = 9901 };
41  enum graph_tree_end_t { graph_tree_end = 9902 };
42 
43  BOOST_INSTALL_PROPERTY(graph, tree_root);
44  BOOST_INSTALL_PROPERTY(graph, tree_end);
45 }
46 
47 
48 #if 0
49 
55 template <class Graph, class VisitChildrenPredicate, class VisitNodePredicate>
56 struct DepthFirstTreeIteratorPolicies : public boost::default_iterator_policies
57 {
58  DepthFirstTreeIteratorPolicies() : fGraph(NULL) {}
59  DepthFirstTreeIteratorPolicies(const Graph& g ) : fGraph(&g) {}
60 
64  template <class IteratorAdaptor>
65  typename IteratorAdaptor::reference dereference(IteratorAdaptor x) const
66  { return *get(x.base()); }
67 
70  template <class IteratorAdaptor>
71  void increment(IteratorAdaptor& x) { advance(x, 1); }
72 
77  template <class IteratorAdaptor, class DifferenceType>
78  void advance(IteratorAdaptor& x, DifferenceType n) const;
79 
80  /*template <class IteratorAdaptor1, class IteratorAdaptor2>
81  bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
82  { return x.base() == y.base() && x.policies().fGraph == y.policies().fGraph; }
83  */
84 
85 
86 private:
87  template <class IteratorAdaptor>
88  typename boost::graph_traits<Graph>::vertex_descriptor getParentVertex(IteratorAdaptor x) const
89  {
90  return source(*get(x.base()), *fGraph);
91  }
92 
93  const Graph* fGraph;
94 };
95 
96 
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
111 {
112  //
113  //extern const char *name[];
114  VisitChildrenPredicate should_visit_children;
115  VisitNodePredicate should_visit_me;
116  using namespace boost;
117  //bool at_end(false);
118  bool done(false);
119  bool ranOutOfCandidates(false);
120  while(!done){
121  typename boost::graph_traits<Graph>::out_edge_iterator e, end; //a.k.a IteratorAdaptor::value_type
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)){ //has children
125  //std::cout << "x.base() 0.5 is " << name[target(get(x.base()), fGraph)] << std::endl;
126  get(x.base()) = e;
127  //std::cout << "x.base() 1 is " << name[target(get(x.base()), fGraph)] << std::endl;
128  }else {
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){
137  //std::cout << "x.base() 1.5 is " << name[target(get(x.base()), fGraph)] << std::endl;
138  ++get(x.base());
139  //std::cout << "x.base() 2 is " << name[target(get(x.base()), fGraph)] << std::endl;
140  }else{
141  parentVertex = getParentVertex(x);
142  parentIsRoot = parentVertex == get(boost::graph_tree_root, *fGraph);
143  if(!parentIsRoot){
144  // then move up to parent and go around again
145  //std::cout << "x.base() 2.5 is " << name[target(get(x.base()), fGraph)] << std::endl;
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);
153  //std::cout << "x.base() 3 is " << name[target(get(x.base()), fGraph)] << std::endl;
154  }else{
155  ranOutOfCandidates = true;
156  //std::cout << "x.base() 3.5 is " << name[target(get(x.base()), fGraph)] << std::endl;
157  //++x.base();
158  //std::cout << "x.base() 4 is " << "end" << std::endl;
159  }
160  }
161  }
162  }
163  done = ranOutOfCandidates || should_visit_me(target(*get(x.base()), *fGraph), *fGraph);
164  }
165  if(ranOutOfCandidates){
166  /*boost::graph_traits<Graph>::out_edge_iterator e,end;
167  boost::tie(e, end) = out_edges(get(boost::graph_tree_root_t(), *fGraph), *fGraph);
168  x.base() = end;
169  */
170  x.policies() = DepthFirstTreeIteratorPolicies<Graph, VisitChildrenPredicate, VisitNodePredicate>();
171  x.base().reset();
172  }
173 
174 
175 }
176 #endif
177 
178 
183 template <class Graph>
185  bool operator()(typename boost::graph_traits<Graph>::vertex_descriptor v, const Graph&)
186  { return true; }
187 };
188 
189 
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> /* DepthFirstTreeIterator */, // derived (???)
203  boost::optional<typename boost::graph_traits<Graph>::out_edge_iterator>, // base
204  typename boost::graph_traits<Graph>::edge_descriptor , // value
205  boost::forward_traversal_tag, // category or traversal
206  typename boost::graph_traits<Graph>::edge_descriptor /*&*/, // reference
207  size_t // difference
208  > type;
209 };
210 
211 
212 #endif //__DepthFirstTreeIterator__
213 
214