24 #ifndef __XMLReferenceGraph__ 25 #define __XMLReferenceGraph__ 28 #include "boost/graph/graph_traits.hpp" 29 #include "boost/iterator/iterator_facade.hpp" 30 #include "boost/iterator_adaptors.hpp" 32 #include "DepthFirstTreeIterator.h" 33 #include "InterfacePtr.h" 34 #include "IIDXMLElement.h" 47 fTargetXMLRef(targetXMLRef),
48 fTrueParentXMLRef(trueParentXMLRef)
50 if (fTargetXMLRef != kInvalidXMLReference && fTrueParentXMLRef == kInvalidXMLReference) {
53 fTrueParentXMLRef = element->GetParent();
56 ASSERT_MSG(fTargetXMLRef != kInvalidXMLReference || fTrueParentXMLRef != kInvalidXMLReference,
"XMLReferenceGraphEdge::XMLReferenceGraphEdge: true parent should be specified when target is kInvalidXMLReference");
60 fTargetXMLRef(other.fTargetXMLRef),
61 fTrueParentXMLRef(other.fTrueParentXMLRef)
64 const XMLReference& GetTargetXMLReference()
const {
return fTargetXMLRef; }
66 const XMLReference& GetTrueParentXMLReference()
const {
return fTrueParentXMLRef; }
70 return (fTargetXMLRef == copy.fTargetXMLRef && fTrueParentXMLRef == copy.fTrueParentXMLRef) ? kTrue : kFalse;
80 struct XMLReferenceIteratorPolicies :
public boost::default_iterator_policies
82 XMLReferenceIteratorPolicies() {}
84 template <
class IteratorAdaptor>
85 typename IteratorAdaptor::reference dereference(
const IteratorAdaptor& x)
const 88 template <
class IteratorAdaptor>
89 void increment(IteratorAdaptor& x) { advance(x, 1); }
94 template <
class IteratorAdaptor,
class DifferenceType>
95 void advance(IteratorAdaptor& x, DifferenceType n);
98 template <
class IteratorAdaptor>
102 template <
class IteratorAdaptor,
class DifferenceType>
103 void XMLReferenceIteratorPolicies::advance(IteratorAdaptor& x, DifferenceType n)
105 ASSERT_MSG(n==1,
"XMLReferenceIteratorPolicies::advance: only single step forward iterator for now");
106 ASSERT_MSG(x.base().GetTargetXMLReference() != kInvalidXMLReference,
"XMLReferenceIteratorPolicies::advance: cannot advance kInvalidXMLReference");
107 if (x.base().GetTargetXMLReference() != kInvalidXMLReference)
110 int32 index = parent->FindChild(x.base().GetTargetXMLReference()) + n;
111 ASSERT(index <= parent->GetChildCount());
116 template <
class IteratorAdaptor>
117 XMLReference XMLReferenceIteratorPolicies::GetParentRef(IteratorAdaptor& x)
119 return (x.base().GetTargetXMLReference() != kInvalidXMLReference) ?
InterfacePtr<IIDXMLElement> (x.base().GetTargetXMLReference().Instantiate())->GetParent() : x.base().GetTrueParentXMLReference();
130 XMLReferenceIterator,
131 XMLReferenceGraphEdge,
132 boost::forward_traversal_tag,
133 XMLReferenceGraphEdge,
147 friend class boost::iterator_core_access;
166 void advance(int32 n)
168 ASSERT_MSG(n >= 0,
"XMLReferenceIterator::advance: only positive increments are supported right now");
169 ASSERT_MSG(n == 1,
"XMLReferenceIterator::advance: warning: only single increment is implemented. large advances are done in a loop and may be inefficient");
170 ASSERT_MSG(fData.GetTargetXMLReference() != kInvalidXMLReference,
"XMLReferenceIterator::advance: cannot advance kInvalidXMLReference");
171 while (--n >= 0 && fData.GetTargetXMLReference() != kInvalidXMLReference) {
173 int32 index(parent->
FindChild(fData.GetTargetXMLReference())+1);
174 ASSERT(index <= parent->GetChildCount());
181 return (fData.GetTargetXMLReference() != kInvalidXMLReference) ?
InterfacePtr<IIDXMLElement> (fData.GetTargetXMLReference().
Instantiate())->GetParent() : fData.GetTrueParentXMLReference();
188 struct XMLInEdgeIteratorPolicies :
public boost::default_iterator_policies
190 XMLInEdgeIteratorPolicies() {}
192 template <
class IteratorAdaptor>
193 typename IteratorAdaptor::reference dereference(
const IteratorAdaptor& x)
const 196 template <
class IteratorAdaptor>
197 void increment(IteratorAdaptor& x) { advance(x, 1); }
202 template <
class IteratorAdaptor,
class DifferenceType>
203 void advance(IteratorAdaptor& x, DifferenceType n);
206 template <
class IteratorAdaptor,
class DifferenceType>
207 void XMLInEdgeIteratorPolicies::advance(IteratorAdaptor& x, DifferenceType n)
220 XMLReferenceGraphEdge,
221 boost::forward_traversal_tag,
222 XMLReferenceGraphEdge,
236 friend class boost::iterator_core_access;
243 bool equal(
XMLInEdgeIterator const& other)
const {
return (fData == other.fData); }
255 void advance(int32 n)
257 ASSERT_MSG(n >= 0,
"XMLInEdgeIterator::advance: only positive increments are supported right now");
258 ASSERT_MSG(fData.GetTargetXMLReference() != kInvalidXMLReference,
"XMLInEdgeIterator::advance: cannot advance past end iterator");
259 while (--n >= 0 && fData.GetTargetXMLReference() != kInvalidXMLReference) {
261 ASSERT_MSG(n == 0 || fData.GetTargetXMLReference() != kInvalidXMLReference,
"XMLInEdgeIterator::advance: cannot advance past end iterator");
273 const XMLReference& preorderEndEdge = kInvalidXMLReference)
274 : fRootVertex(rootVertex), fPreorderEndEdge(preorderEndEdge) {}
275 const XMLReference& RootVertex()
const {
return fRootVertex; }
276 const XMLReference& PreorderEndEdge()
const {
return fPreorderEndEdge; }
288 typedef void adjacency_iterator;
291 typedef void edge_iterator;
292 typedef void vertex_iterator;
293 typedef int32 degree_size_type;
294 typedef int32 vertices_size_type;
295 typedef int32 edges_size_type;
296 typedef boost::directed_tag directed_category;
297 typedef boost::disallow_parallel_edge_tag edge_parallel_category;
298 typedef boost::bidirectional_graph_tag traversal_category;
302 typedef boost::graph_traits<XMLReferenceGraph>::out_edge_iterator XMLOutEdgeIterator;
307 std::pair<XMLOutEdgeIterator, XMLOutEdgeIterator>
308 out_edges(boost::graph_traits<XMLReferenceGraph>::vertex_descriptor v,
const XMLReferenceGraph& g);
310 boost::graph_traits<XMLReferenceGraph>::degree_size_type
313 boost::graph_traits<XMLReferenceGraph>::vertex_descriptor
314 source(
const boost::graph_traits<XMLReferenceGraph>::edge_descriptor& e,
const XMLReferenceGraph& g);
316 boost::graph_traits<XMLReferenceGraph>::vertex_descriptor
317 target(
const boost::graph_traits<XMLReferenceGraph>::edge_descriptor& e,
const XMLReferenceGraph& g);
321 std::pair<boost::graph_traits<XMLReferenceGraph>::in_edge_iterator, boost::graph_traits<XMLReferenceGraph>::in_edge_iterator>
322 in_edges(boost::graph_traits<XMLReferenceGraph>::vertex_descriptor v,
const XMLReferenceGraph& g);
336 incoming_edge(boost::graph_traits<XMLReferenceGraph>::vertex_descriptor v,
const XMLReferenceGraph& g);
340 class XMLDepthFirstTreeIterator: boost::iterator_adaptor<
341 XMLDepthFirstTreeIterator,
342 boost::optional<boost::graph_traits<XMLReferenceGraph>::out_edge_iterator>,
343 boost::graph_traits<XMLReferenceGraph>::edge_descriptor,
344 boost::forward_traversal_tag,
345 boost::graph_traits<XMLReferenceGraph>::edge_descriptor,
350 XMLDepthFirstTreeIterator() :
351 XMLDepthFirstTreeIterator::iterator_adaptor_()
355 XMLDepthFirstTreeIterator::iterator_adaptor_(other)
361 friend class boost::iterator_core_access;
365 ASSERT_FAIL(
"XMLDepthFirstTreeIterator::increment: not yet implemented");
372 XMLVirtualDepthFirstTreeIterator,
373 boost::graph_traits<XMLReferenceGraph>::edge_descriptor,
374 boost::forward_traversal_tag,
375 boost::graph_traits<XMLReferenceGraph>::edge_descriptor,
389 friend class boost::iterator_core_access;
406 const boost::graph_traits<XMLReferenceGraph>::edge_descriptor& dereference()
const {
return fData; }
408 void advance(int32 n)
410 ASSERT_FAIL(
"XMLVirtualDepthFirstTreeIterator::increment: not yet implemented");
414 boost::graph_traits<XMLReferenceGraph>::edge_descriptor fData;
432 virtual_make_iterator(boost::graph_traits<XMLReferenceGraph>::vertex_descriptor v,
const XMLReferenceGraph& g);
436 virtual_make_iterator<XMLVirtualDepthFirstTreeIterator>(boost::graph_traits<XMLReferenceGraph>::vertex_descriptor v,
const XMLReferenceGraph& g);
440 virtual_make_iterator<XMLOutEdgeIterator>(boost::graph_traits<XMLReferenceGraph>::vertex_descriptor v,
const XMLReferenceGraph& g);
444 inline boost::graph_traits<XMLReferenceGraph>::vertex_descriptor
447 return g.RootVertex();;
456 #endif //__XMLReferenceGraph__