depth_first_search.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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_DEPTH_FIRST_SEARCH_HPP_INCLUDED
  5. #define BOOST_MSM_MPL_GRAPH_DEPTH_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 "search_colors.hpp"
  13. namespace boost {
  14. namespace msm {
  15. namespace mpl_graph {
  16. // dfs takes a visitor which has all the bgl-like metafunctions encapsulated in an
  17. // "operations" member class, and also a state. the operations are expected to return a new state
  18. // in addition, the visitor operations are expected to update the colors of vertices
  19. // and need to support a new metafunction get_color<Vertex, State>
  20. struct dfs_default_visitor_operations {
  21. template<typename Vertex, typename Graph, typename State>
  22. struct initialize_vertex {
  23. typedef State type;
  24. };
  25. template<typename Vertex, typename Graph, typename State>
  26. struct discover_vertex {
  27. typedef State type;
  28. };
  29. template<typename Vertex, typename Graph, typename State>
  30. struct finish_vertex {
  31. typedef State type;
  32. };
  33. template<typename Edge, typename Graph, typename State>
  34. struct tree_edge {
  35. typedef State type;
  36. };
  37. template<typename Edge, typename Graph, typename State>
  38. struct back_edge {
  39. typedef State type;
  40. };
  41. template<typename Edge, typename Graph, typename State>
  42. struct forward_or_cross_edge {
  43. typedef State type;
  44. };
  45. };
  46. // requires IncidenceGraph
  47. // returns pair<VisitorState, ColorState>
  48. template<typename Graph, typename VisitorOps, typename VisitorState,
  49. typename Vertex,
  50. typename ColorState = create_search_color_map::type >
  51. struct depth_first_search {
  52. // enter vertex
  53. typedef typename VisitorOps::template
  54. discover_vertex<Vertex, Graph, VisitorState>::type
  55. discovered_state;
  56. typedef typename search_color_map_ops::template
  57. set_color<Vertex, search_colors::Gray, ColorState>::type
  58. discovered_colors;
  59. // loop over out edges
  60. typedef typename
  61. mpl::fold<typename mpl_graph::out_edges<Vertex, Graph>::type,
  62. mpl::pair<discovered_state, discovered_colors>,
  63. mpl::if_<boost::is_same<search_color_map_ops::get_color<mpl_graph::target<mpl::_2, Graph>, mpl::second<mpl::_1> >,
  64. search_colors::White>,
  65. // unseen target: recurse
  66. depth_first_search<Graph,
  67. VisitorOps, typename VisitorOps::template tree_edge<mpl::_2, Graph, mpl::first<mpl::_1> >,
  68. mpl_graph::target<mpl::_2, Graph>,
  69. mpl::second<mpl::_1> >,
  70. // seen: back or forward edge
  71. mpl::pair<mpl::if_<boost::is_same<typename search_color_map_ops::template
  72. get_color<mpl_graph::target<mpl::_2, Graph>, mpl::second<mpl::_1 > >,
  73. search_colors::Gray>,
  74. typename VisitorOps::template back_edge<mpl::_2, Graph, mpl::first<mpl::_1> >,
  75. typename VisitorOps::template forward_or_cross_edge<mpl::_2, Graph, mpl::first<mpl::_1> > >, // Black
  76. mpl::second<mpl::_1> > >
  77. >::type after_outedges;
  78. // leave vertex, and done!
  79. typedef mpl::pair<typename VisitorOps::template finish_vertex<Vertex, Graph, typename mpl::first<after_outedges>::type >::type,
  80. typename search_color_map_ops::template set_color<Vertex, search_colors::Black, typename mpl::second<after_outedges>::type>::type> type;
  81. };
  82. // requires IncidenceGraph, VertexListGraph
  83. template<typename Graph, typename VisitorOps, typename VisitorState,
  84. typename FirstVertex = typename mpl::front<typename mpl_graph::vertices<Graph>::type>::type,
  85. typename ColorState = create_search_color_map::type>
  86. struct depth_first_search_all : // visit first then rest
  87. mpl::fold<typename mpl_graph::vertices<Graph>::type,
  88. typename depth_first_search<Graph,
  89. VisitorOps, VisitorState,
  90. FirstVertex,
  91. ColorState>::type,
  92. mpl::if_<boost::is_same<search_color_map_ops::get_color<mpl::_2, mpl::second<mpl::_1> >,
  93. search_colors::White>, // visit any yet unvisited
  94. depth_first_search<Graph,
  95. VisitorOps, mpl::first<mpl::_1>,
  96. mpl::_2,
  97. mpl::second<mpl::_1> >,
  98. mpl::_1> >
  99. {};
  100. } // namespace mpl_graph
  101. } // namespace msm
  102. } // namespace boost
  103. #endif // BOOST_MSM_MPL_GRAPH_DEPTH_FIRST_SEARCH_HPP_INCLUDED