graph_as_tree.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. //
  2. //=======================================================================
  3. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  4. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //=======================================================================
  10. //
  11. #ifndef BOOST_GRAPH_GRAPH_AS_TREE_HPP
  12. #define BOOST_GRAPH_GRAPH_AS_TREE_HPP
  13. #include <vector>
  14. #include <boost/config.hpp>
  15. #include <boost/property_map/property_map.hpp>
  16. #include <boost/graph/tree_traits.hpp>
  17. #include <boost/graph/graph_traits.hpp>
  18. #include <boost/graph/breadth_first_search.hpp>
  19. #include <boost/graph/visitors.hpp>
  20. namespace boost {
  21. template <class Graph, class Node, class ChIt, class Derived>
  22. class graph_as_tree_base
  23. {
  24. typedef Derived Tree;
  25. public:
  26. typedef Node node_descriptor;
  27. typedef ChIt children_iterator;
  28. graph_as_tree_base(Graph& g, Node root) : _g(g), _root(root) { }
  29. friend Node root(const Tree& t) { return t._root; }
  30. template <class N>
  31. friend std::pair<ChIt,ChIt>
  32. children(N n, const Tree& t) { return adjacent_vertices(n, t._g); }
  33. template<class N>
  34. friend Node parent(N n, const Tree& t) {
  35. return boost::get(t.parent_pa(), n);
  36. }
  37. Graph& _g;
  38. Node _root;
  39. };
  40. struct graph_as_tree_tag { };
  41. template <class Graph, class ParentMap
  42. , class Node
  43. #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  44. = typename graph_traits<Graph>::vertex_descriptor
  45. #endif
  46. , class ChIt
  47. #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  48. = typename graph_traits<Graph>::adjacency_iterator
  49. #endif
  50. >
  51. class graph_as_tree
  52. : public graph_as_tree_base<Graph, Node, ChIt,
  53. graph_as_tree<Graph,ParentMap,Node,ChIt> >
  54. {
  55. typedef graph_as_tree self;
  56. typedef graph_as_tree_base<Graph, Node, ChIt, self> super;
  57. public:
  58. graph_as_tree(Graph& g, Node root) : super(g, root) { }
  59. graph_as_tree(Graph& g, Node root, ParentMap p) : super(g, root), _p(p) {
  60. breadth_first_search(g, root,
  61. visitor(make_bfs_visitor
  62. (record_predecessors(p, boost::on_tree_edge()))));
  63. }
  64. ParentMap parent_pa() const { return _p; }
  65. typedef graph_as_tree_tag graph_tag; // for property_map
  66. protected:
  67. ParentMap _p;
  68. };
  69. namespace detail {
  70. struct graph_as_tree_vertex_property_selector {
  71. template <typename GraphAsTree, typename Property, typename Tag>
  72. struct bind_ {
  73. typedef typename GraphAsTree::base_type Graph;
  74. typedef property_map<Graph, Tag> PMap;
  75. typedef typename PMap::type type;
  76. typedef typename PMap::const_type const_type;
  77. };
  78. };
  79. struct graph_as_tree_edge_property_selector {
  80. template <typename GraphAsTree, typename Property, typename Tag>
  81. struct bind_ {
  82. typedef typename GraphAsTree::base_type Graph;
  83. typedef property_map<Graph, Tag> PMap;
  84. typedef typename PMap::type type;
  85. typedef typename PMap::const_type const_type;
  86. };
  87. };
  88. } // namespace detail
  89. template <>
  90. struct vertex_property_selector<graph_as_tree_tag> {
  91. typedef detail::graph_as_tree_vertex_property_selector type;
  92. };
  93. template <>
  94. struct edge_property_selector<graph_as_tree_tag> {
  95. typedef detail::graph_as_tree_edge_property_selector type;
  96. };
  97. template <typename Graph, typename P, typename N, typename C,
  98. typename Property>
  99. typename property_map<Graph, Property>::type
  100. get(Property p, graph_as_tree<Graph,P,N,C>& g)
  101. {
  102. return get(p, g._g);
  103. }
  104. template <typename Graph, typename P, typename N, typename C,
  105. typename Property>
  106. typename property_map<Graph, Property>::const_type
  107. get(Property p, const graph_as_tree<Graph,P,N,C>& g)
  108. {
  109. const Graph& gref = g._g; // in case GRef is non-const
  110. return get(p, gref);
  111. }
  112. template <typename Graph, typename P, typename N, typename C,
  113. typename Property, typename Key>
  114. typename property_traits<
  115. typename property_map<Graph, Property>::const_type
  116. >::value_type
  117. get(Property p, const graph_as_tree<Graph,P,N,C>& g, const Key& k)
  118. {
  119. return get(p, g._g, k);
  120. }
  121. template <typename Graph, typename P, typename N, typename C,
  122. typename Property, typename Key, typename Value>
  123. void
  124. put(Property p, const graph_as_tree<Graph,P,N,C>& g, const Key& k,
  125. const Value& val)
  126. {
  127. put(p, g._g, k, val);
  128. }
  129. } // namespace boost
  130. #endif // BOOST_GRAPH_GRAPH_AS_TREE_HPP