Chris@16
|
1 // Copyright 2008-2010 Gordon Woodhull
|
Chris@16
|
2 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
3 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
4
|
Chris@16
|
5 #ifndef BOOST_MSM_MPL_GRAPH_DEPTH_FIRST_SEARCH_HPP_INCLUDED
|
Chris@16
|
6 #define BOOST_MSM_MPL_GRAPH_DEPTH_FIRST_SEARCH_HPP_INCLUDED
|
Chris@16
|
7
|
Chris@16
|
8 #include <boost/msm/mpl_graph/mpl_graph.hpp>
|
Chris@16
|
9
|
Chris@16
|
10 #include <boost/mpl/has_key.hpp>
|
Chris@16
|
11 #include <boost/mpl/insert.hpp>
|
Chris@16
|
12 #include <boost/mpl/pair.hpp>
|
Chris@16
|
13 #include <boost/mpl/map.hpp>
|
Chris@16
|
14 #include <boost/mpl/has_key.hpp>
|
Chris@16
|
15
|
Chris@16
|
16 #include "search_colors.hpp"
|
Chris@16
|
17
|
Chris@16
|
18 namespace boost {
|
Chris@16
|
19 namespace msm {
|
Chris@16
|
20 namespace mpl_graph {
|
Chris@16
|
21
|
Chris@16
|
22 // dfs takes a visitor which has all the bgl-like metafunctions encapsulated in an
|
Chris@16
|
23 // "operations" member class, and also a state. the operations are expected to return a new state
|
Chris@16
|
24 // in addition, the visitor operations are expected to update the colors of vertices
|
Chris@16
|
25 // and need to support a new metafunction get_color<Vertex, State>
|
Chris@16
|
26
|
Chris@16
|
27 struct dfs_default_visitor_operations {
|
Chris@16
|
28 template<typename Vertex, typename Graph, typename State>
|
Chris@16
|
29 struct initialize_vertex {
|
Chris@16
|
30 typedef State type;
|
Chris@16
|
31 };
|
Chris@16
|
32
|
Chris@16
|
33 template<typename Vertex, typename Graph, typename State>
|
Chris@16
|
34 struct discover_vertex {
|
Chris@16
|
35 typedef State type;
|
Chris@16
|
36 };
|
Chris@16
|
37
|
Chris@16
|
38 template<typename Vertex, typename Graph, typename State>
|
Chris@16
|
39 struct finish_vertex {
|
Chris@16
|
40 typedef State type;
|
Chris@16
|
41 };
|
Chris@16
|
42
|
Chris@16
|
43 template<typename Edge, typename Graph, typename State>
|
Chris@16
|
44 struct tree_edge {
|
Chris@16
|
45 typedef State type;
|
Chris@16
|
46 };
|
Chris@16
|
47
|
Chris@16
|
48 template<typename Edge, typename Graph, typename State>
|
Chris@16
|
49 struct back_edge {
|
Chris@16
|
50 typedef State type;
|
Chris@16
|
51 };
|
Chris@16
|
52
|
Chris@16
|
53 template<typename Edge, typename Graph, typename State>
|
Chris@16
|
54 struct forward_or_cross_edge {
|
Chris@16
|
55 typedef State type;
|
Chris@16
|
56 };
|
Chris@16
|
57 };
|
Chris@16
|
58
|
Chris@16
|
59 // requires IncidenceGraph
|
Chris@16
|
60 // returns pair<VisitorState, ColorState>
|
Chris@16
|
61 template<typename Graph, typename VisitorOps, typename VisitorState,
|
Chris@16
|
62 typename Vertex,
|
Chris@16
|
63 typename ColorState = create_search_color_map::type >
|
Chris@16
|
64 struct depth_first_search {
|
Chris@16
|
65 // enter vertex
|
Chris@16
|
66 typedef typename VisitorOps::template
|
Chris@16
|
67 discover_vertex<Vertex, Graph, VisitorState>::type
|
Chris@16
|
68 discovered_state;
|
Chris@16
|
69 typedef typename search_color_map_ops::template
|
Chris@16
|
70 set_color<Vertex, search_colors::Gray, ColorState>::type
|
Chris@16
|
71 discovered_colors;
|
Chris@16
|
72
|
Chris@16
|
73 // loop over out edges
|
Chris@16
|
74 typedef typename
|
Chris@16
|
75 mpl::fold<typename mpl_graph::out_edges<Vertex, Graph>::type,
|
Chris@16
|
76 mpl::pair<discovered_state, discovered_colors>,
|
Chris@16
|
77 mpl::if_<boost::is_same<search_color_map_ops::get_color<mpl_graph::target<mpl::_2, Graph>, mpl::second<mpl::_1> >,
|
Chris@16
|
78 search_colors::White>,
|
Chris@16
|
79 // unseen target: recurse
|
Chris@16
|
80 depth_first_search<Graph,
|
Chris@16
|
81 VisitorOps, typename VisitorOps::template tree_edge<mpl::_2, Graph, mpl::first<mpl::_1> >,
|
Chris@16
|
82 mpl_graph::target<mpl::_2, Graph>,
|
Chris@16
|
83 mpl::second<mpl::_1> >,
|
Chris@16
|
84 // seen: back or forward edge
|
Chris@16
|
85 mpl::pair<mpl::if_<boost::is_same<typename search_color_map_ops::template
|
Chris@16
|
86 get_color<mpl_graph::target<mpl::_2, Graph>, mpl::second<mpl::_1 > >,
|
Chris@16
|
87 search_colors::Gray>,
|
Chris@16
|
88 typename VisitorOps::template back_edge<mpl::_2, Graph, mpl::first<mpl::_1> >,
|
Chris@16
|
89 typename VisitorOps::template forward_or_cross_edge<mpl::_2, Graph, mpl::first<mpl::_1> > >, // Black
|
Chris@16
|
90 mpl::second<mpl::_1> > >
|
Chris@16
|
91 >::type after_outedges;
|
Chris@16
|
92
|
Chris@16
|
93 // leave vertex, and done!
|
Chris@16
|
94 typedef mpl::pair<typename VisitorOps::template finish_vertex<Vertex, Graph, typename mpl::first<after_outedges>::type >::type,
|
Chris@16
|
95 typename search_color_map_ops::template set_color<Vertex, search_colors::Black, typename mpl::second<after_outedges>::type>::type> type;
|
Chris@16
|
96 };
|
Chris@16
|
97
|
Chris@16
|
98 // requires IncidenceGraph, VertexListGraph
|
Chris@16
|
99 template<typename Graph, typename VisitorOps, typename VisitorState,
|
Chris@16
|
100 typename FirstVertex = typename mpl::front<typename mpl_graph::vertices<Graph>::type>::type,
|
Chris@16
|
101 typename ColorState = create_search_color_map::type>
|
Chris@16
|
102 struct depth_first_search_all : // visit first then rest
|
Chris@16
|
103 mpl::fold<typename mpl_graph::vertices<Graph>::type,
|
Chris@16
|
104 typename depth_first_search<Graph,
|
Chris@16
|
105 VisitorOps, VisitorState,
|
Chris@16
|
106 FirstVertex,
|
Chris@16
|
107 ColorState>::type,
|
Chris@16
|
108 mpl::if_<boost::is_same<search_color_map_ops::get_color<mpl::_2, mpl::second<mpl::_1> >,
|
Chris@16
|
109 search_colors::White>, // visit any yet unvisited
|
Chris@16
|
110 depth_first_search<Graph,
|
Chris@16
|
111 VisitorOps, mpl::first<mpl::_1>,
|
Chris@16
|
112 mpl::_2,
|
Chris@16
|
113 mpl::second<mpl::_1> >,
|
Chris@16
|
114 mpl::_1> >
|
Chris@16
|
115 {};
|
Chris@16
|
116
|
Chris@16
|
117 } // namespace mpl_graph
|
Chris@16
|
118 } // namespace msm
|
Chris@16
|
119 } // namespace boost
|
Chris@16
|
120
|
Chris@16
|
121
|
Chris@16
|
122 #endif // BOOST_MSM_MPL_GRAPH_DEPTH_FIRST_SEARCH_HPP_INCLUDED
|