graph_as_tree.hpp 4.5 KB

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