graph_as_tree.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. {
  22. template < class Graph, class Node, class ChIt, class Derived >
  23. class graph_as_tree_base
  24. {
  25. typedef Derived Tree;
  26. public:
  27. typedef Node node_descriptor;
  28. typedef ChIt children_iterator;
  29. graph_as_tree_base(Graph& g, Node root) : _g(g), _root(root) {}
  30. friend Node root(const Tree& t) { return t._root; }
  31. template < class N >
  32. friend std::pair< ChIt, ChIt > children(N n, const Tree& t)
  33. {
  34. return adjacent_vertices(n, t._g);
  35. }
  36. template < class N > friend Node parent(N n, const Tree& t)
  37. {
  38. return boost::get(t.parent_pa(), n);
  39. }
  40. Graph& _g;
  41. Node _root;
  42. };
  43. struct graph_as_tree_tag
  44. {
  45. };
  46. template < class Graph, class ParentMap,
  47. class Node = typename graph_traits< Graph >::vertex_descriptor,
  48. class ChIt = typename graph_traits< Graph >::adjacency_iterator >
  49. class graph_as_tree : public graph_as_tree_base< Graph, Node, ChIt,
  50. graph_as_tree< Graph, ParentMap, Node, ChIt > >
  51. {
  52. typedef graph_as_tree self;
  53. typedef graph_as_tree_base< Graph, Node, ChIt, self > super;
  54. public:
  55. graph_as_tree(Graph& g, Node root) : super(g, root) {}
  56. graph_as_tree(Graph& g, Node root, ParentMap p) : super(g, root), _p(p)
  57. {
  58. breadth_first_search(g, root,
  59. visitor(make_bfs_visitor(
  60. record_predecessors(p, boost::on_tree_edge()))));
  61. }
  62. ParentMap parent_pa() const { return _p; }
  63. typedef graph_as_tree_tag graph_tag; // for property_map
  64. protected:
  65. ParentMap _p;
  66. };
  67. namespace detail
  68. {
  69. struct graph_as_tree_vertex_property_selector
  70. {
  71. template < typename GraphAsTree, typename Property, typename Tag >
  72. struct bind_
  73. {
  74. typedef typename GraphAsTree::base_type Graph;
  75. typedef property_map< Graph, Tag > PMap;
  76. typedef typename PMap::type type;
  77. typedef typename PMap::const_type const_type;
  78. };
  79. };
  80. struct graph_as_tree_edge_property_selector
  81. {
  82. template < typename GraphAsTree, typename Property, typename Tag >
  83. struct bind_
  84. {
  85. typedef typename GraphAsTree::base_type Graph;
  86. typedef property_map< Graph, Tag > PMap;
  87. typedef typename PMap::type type;
  88. typedef typename PMap::const_type const_type;
  89. };
  90. };
  91. } // namespace detail
  92. template <> struct vertex_property_selector< graph_as_tree_tag >
  93. {
  94. typedef detail::graph_as_tree_vertex_property_selector type;
  95. };
  96. template <> struct edge_property_selector< graph_as_tree_tag >
  97. {
  98. typedef detail::graph_as_tree_edge_property_selector type;
  99. };
  100. template < typename Graph, typename P, typename N, typename C,
  101. typename Property >
  102. typename property_map< Graph, Property >::type get(
  103. Property p, graph_as_tree< Graph, P, N, C >& g)
  104. {
  105. return get(p, g._g);
  106. }
  107. template < typename Graph, typename P, typename N, typename C,
  108. typename Property >
  109. typename property_map< Graph, Property >::const_type get(
  110. Property p, const graph_as_tree< Graph, P, N, C >& g)
  111. {
  112. const Graph& gref = g._g; // in case GRef is non-const
  113. return get(p, gref);
  114. }
  115. template < typename Graph, typename P, typename N, typename C,
  116. typename Property, typename Key >
  117. typename property_traits<
  118. typename property_map< Graph, Property >::const_type >::value_type
  119. get(Property p, const graph_as_tree< Graph, P, N, C >& g, const Key& k)
  120. {
  121. return get(p, g._g, k);
  122. }
  123. template < typename Graph, typename P, typename N, typename C,
  124. typename Property, typename Key, typename Value >
  125. void put(Property p, const graph_as_tree< Graph, P, N, C >& g, const Key& k,
  126. const Value& val)
  127. {
  128. put(p, g._g, k, val);
  129. }
  130. } // namespace boost
  131. #endif // BOOST_GRAPH_GRAPH_AS_TREE_HPP