breadth_first_search.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // Copyright 2008-2010 Gordon Woodhull
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #ifndef BOOST_MSM_MPL_GRAPH_BREADTH_FIRST_SEARCH_HPP_INCLUDED
  5. #define BOOST_MSM_MPL_GRAPH_BREADTH_FIRST_SEARCH_HPP_INCLUDED
  6. #include <boost/msm/mpl_graph/mpl_graph.hpp>
  7. #include <boost/mpl/has_key.hpp>
  8. #include <boost/mpl/insert.hpp>
  9. #include <boost/mpl/pair.hpp>
  10. #include <boost/mpl/map.hpp>
  11. #include <boost/mpl/has_key.hpp>
  12. #include <boost/mpl/pop_front.hpp>
  13. #include <boost/mpl/empty.hpp>
  14. #include <boost/mpl/remove.hpp>
  15. #include "search_colors.hpp"
  16. namespace boost {
  17. namespace msm {
  18. namespace mpl_graph {
  19. // bfs takes a visitor which has all the bgl-like metafunctions encapsulated in an
  20. // "operations" member class, and also a state. the operations are expected to return a new state
  21. struct bfs_default_visitor_operations {
  22. template<typename Vertex, typename Graph, typename State>
  23. struct initialize_vertex {
  24. typedef State type;
  25. };
  26. template<typename Vertex, typename Graph, typename State>
  27. struct discover_vertex {
  28. typedef State type;
  29. };
  30. template<typename Vertex, typename Graph, typename State>
  31. struct examine_vertex {
  32. typedef State type;
  33. };
  34. template<typename Vertex, typename Graph, typename State>
  35. struct examine_edge {
  36. typedef State type;
  37. };
  38. template<typename Edge, typename Graph, typename State>
  39. struct tree_edge {
  40. typedef State type;
  41. };
  42. template<typename Edge, typename Graph, typename State>
  43. struct non_tree_edge {
  44. typedef State type;
  45. };
  46. template<typename Edge, typename Graph, typename State>
  47. struct gray_target {
  48. typedef State type;
  49. };
  50. template<typename Edge, typename Graph, typename State>
  51. struct black_target {
  52. typedef State type;
  53. };
  54. template<typename Vertex, typename Graph, typename State>
  55. struct finish_vertex {
  56. typedef State type;
  57. };
  58. };
  59. namespace detail {
  60. template<typename Graph, typename VisitorOps, typename VCQState, typename Edge>
  61. struct bfs_run_queue_examine_edge {
  62. typedef typename VisitorOps::template examine_edge<Edge, Graph, typename mpl::at_c<VCQState, 0>::type>::type visitor_state;
  63. typedef typename mpl::at_c<VCQState, 1>::type color_state;
  64. typedef typename mpl::at_c<VCQState, 2>::type vertex_queue;
  65. typedef typename mpl::if_<typename boost::is_same<typename search_color_map_ops::template get_color<typename mpl_graph::target<Edge, Graph>::type, color_state>::type, search_colors::White>::type,
  66. // unseen target: tree edge, discover target, paint it gray, and enqueue
  67. mpl::vector<typename VisitorOps::template discover_vertex<typename mpl_graph::target<Edge, Graph>::type, Graph,
  68. typename VisitorOps::template tree_edge<Edge, Graph, visitor_state>::type>::type,
  69. typename search_color_map_ops::template set_color<typename mpl_graph::target<Edge, Graph>::type, search_colors::Gray, color_state>::type,
  70. typename mpl::push_back<vertex_queue, typename mpl_graph::target<Edge, Graph>::type >::type >,
  71. // seen
  72. mpl::vector<typename mpl::if_<typename boost::is_same<typename search_color_map_ops::template get_color<mpl_graph::target<Edge, Graph>, color_state>,
  73. search_colors::Gray>::type,
  74. typename VisitorOps::template gray_target<Edge, Graph, visitor_state>::type,
  75. typename VisitorOps::template black_target<Edge, Graph, visitor_state>::type>::type,
  76. color_state,
  77. vertex_queue>
  78. >::type type;
  79. };
  80. // runs bfs on a queue, passing the new queue forward on recursion
  81. // returns pair<visitor_state, color_state>
  82. template<typename Graph, typename VertexQueue, typename VisitorOps, typename VisitorState, typename ColorMap>
  83. struct bfs_run_queue {
  84. // enter vertex
  85. typedef typename mpl::front<VertexQueue>::type Vertex;
  86. typedef typename mpl::pop_front<VertexQueue>::type Tail;
  87. typedef typename VisitorOps::template examine_vertex<Vertex, Graph, VisitorState>::type examined_state;
  88. // loop over out edges
  89. typedef typename mpl::template
  90. fold<typename mpl_graph::out_edges<Vertex, Graph>::type,
  91. mpl::vector<examined_state, ColorMap, Tail>,
  92. bfs_run_queue_examine_edge<Graph, VisitorOps, mpl::_1, mpl::_2>
  93. >::type did_edges;
  94. typedef typename VisitorOps::template
  95. finish_vertex<Vertex, Graph, typename mpl::at_c<did_edges, 0>::type>::type
  96. finished_vertex;
  97. // does map insert always overwrite? i seem to remember this not working on msvc once
  98. typedef typename search_color_map_ops::template
  99. set_color<Vertex, search_colors::Black, typename mpl::at_c<did_edges, 1>::type>::type
  100. colored_vertex;
  101. typedef typename mpl::at_c<did_edges, 2>::type queued_targets;
  102. typedef typename
  103. mpl::if_<typename mpl::empty<queued_targets>::type,
  104. mpl::pair<finished_vertex, colored_vertex>,
  105. bfs_run_queue<Graph, queued_targets,
  106. VisitorOps, finished_vertex,
  107. colored_vertex> >::type::type type;
  108. };
  109. } // namespace detail
  110. template<typename Graph, typename VisitorOps, typename VisitorState,
  111. typename Vertex,
  112. typename ColorMap = create_search_color_map::type >
  113. struct breadth_first_search {
  114. typedef typename VisitorOps::template
  115. discover_vertex<Vertex, Graph, VisitorState>::type
  116. discovered_state;
  117. typedef typename search_color_map_ops::template
  118. set_color<Vertex, search_colors::Gray, ColorMap>::type
  119. discovered_colors;
  120. typedef typename detail::
  121. bfs_run_queue<Graph, mpl::vector<Vertex>,
  122. VisitorOps, discovered_state,
  123. discovered_colors>::type type;
  124. };
  125. template<typename Graph, typename VisitorOps, typename VisitorState,
  126. typename FirstVertex = typename mpl::front<typename mpl_graph::vertices<Graph>::type>::type,
  127. typename ColorMap = create_search_color_map::type>
  128. struct breadth_first_search_all : // visit "first" first, then visit any still white
  129. mpl::fold<typename mpl_graph::vertices<Graph>::type,
  130. typename breadth_first_search<Graph, VisitorOps, VisitorState, FirstVertex, ColorMap>::type,
  131. mpl::if_<boost::is_same<search_color_map_ops::template get_color<mpl::_2, mpl::second<mpl::_1> >,
  132. search_colors::White>,
  133. breadth_first_search<Graph, VisitorOps, mpl::first<mpl::_1>,
  134. mpl::_2, mpl::second<mpl::_1> >,
  135. mpl::_1> >
  136. {};
  137. } // namespace mpl_graph
  138. } // namespace msm
  139. } // namespace boost
  140. #endif // BOOST_MSM_MPL_GRAPH_BREADTH_FIRST_SEARCH_HPP_INCLUDED