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_BREADTH_FIRST_SEARCH_HPP_INCLUDED
|
Chris@16
|
6 #define BOOST_MSM_MPL_GRAPH_BREADTH_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 #include <boost/mpl/pop_front.hpp>
|
Chris@16
|
16 #include <boost/mpl/empty.hpp>
|
Chris@16
|
17 #include <boost/mpl/remove.hpp>
|
Chris@16
|
18
|
Chris@16
|
19 #include "search_colors.hpp"
|
Chris@16
|
20
|
Chris@16
|
21 namespace boost {
|
Chris@16
|
22 namespace msm {
|
Chris@16
|
23 namespace mpl_graph {
|
Chris@16
|
24
|
Chris@16
|
25 // bfs takes a visitor which has all the bgl-like metafunctions encapsulated in an
|
Chris@16
|
26 // "operations" member class, and also a state. the operations are expected to return a new state
|
Chris@16
|
27 struct bfs_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 examine_vertex {
|
Chris@16
|
40 typedef State type;
|
Chris@16
|
41 };
|
Chris@16
|
42
|
Chris@16
|
43 template<typename Vertex, typename Graph, typename State>
|
Chris@16
|
44 struct examine_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 tree_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 non_tree_edge {
|
Chris@16
|
55 typedef State type;
|
Chris@16
|
56 };
|
Chris@16
|
57
|
Chris@16
|
58 template<typename Edge, typename Graph, typename State>
|
Chris@16
|
59 struct gray_target {
|
Chris@16
|
60 typedef State type;
|
Chris@16
|
61 };
|
Chris@16
|
62
|
Chris@16
|
63 template<typename Edge, typename Graph, typename State>
|
Chris@16
|
64 struct black_target {
|
Chris@16
|
65 typedef State type;
|
Chris@16
|
66 };
|
Chris@16
|
67
|
Chris@16
|
68 template<typename Vertex, typename Graph, typename State>
|
Chris@16
|
69 struct finish_vertex {
|
Chris@16
|
70 typedef State type;
|
Chris@16
|
71 };
|
Chris@16
|
72 };
|
Chris@16
|
73
|
Chris@16
|
74 namespace detail {
|
Chris@16
|
75
|
Chris@16
|
76 template<typename Graph, typename VisitorOps, typename VCQState, typename Edge>
|
Chris@16
|
77 struct bfs_run_queue_examine_edge {
|
Chris@16
|
78 typedef typename VisitorOps::template examine_edge<Edge, Graph, typename mpl::at_c<VCQState, 0>::type>::type visitor_state;
|
Chris@16
|
79 typedef typename mpl::at_c<VCQState, 1>::type color_state;
|
Chris@16
|
80 typedef typename mpl::at_c<VCQState, 2>::type vertex_queue;
|
Chris@16
|
81
|
Chris@16
|
82 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,
|
Chris@16
|
83 // unseen target: tree edge, discover target, paint it gray, and enqueue
|
Chris@16
|
84 mpl::vector<typename VisitorOps::template discover_vertex<typename mpl_graph::target<Edge, Graph>::type, Graph,
|
Chris@16
|
85 typename VisitorOps::template tree_edge<Edge, Graph, visitor_state>::type>::type,
|
Chris@16
|
86 typename search_color_map_ops::template set_color<typename mpl_graph::target<Edge, Graph>::type, search_colors::Gray, color_state>::type,
|
Chris@16
|
87 typename mpl::push_back<vertex_queue, typename mpl_graph::target<Edge, Graph>::type >::type >,
|
Chris@16
|
88 // seen
|
Chris@16
|
89 mpl::vector<typename mpl::if_<typename boost::is_same<typename search_color_map_ops::template get_color<mpl_graph::target<Edge, Graph>, color_state>,
|
Chris@16
|
90 search_colors::Gray>::type,
|
Chris@16
|
91 typename VisitorOps::template gray_target<Edge, Graph, visitor_state>::type,
|
Chris@16
|
92 typename VisitorOps::template black_target<Edge, Graph, visitor_state>::type>::type,
|
Chris@16
|
93 color_state,
|
Chris@16
|
94 vertex_queue>
|
Chris@16
|
95 >::type type;
|
Chris@16
|
96 };
|
Chris@16
|
97
|
Chris@16
|
98 // runs bfs on a queue, passing the new queue forward on recursion
|
Chris@16
|
99 // returns pair<visitor_state, color_state>
|
Chris@16
|
100 template<typename Graph, typename VertexQueue, typename VisitorOps, typename VisitorState, typename ColorMap>
|
Chris@16
|
101 struct bfs_run_queue {
|
Chris@16
|
102 // enter vertex
|
Chris@16
|
103 typedef typename mpl::front<VertexQueue>::type Vertex;
|
Chris@16
|
104 typedef typename mpl::pop_front<VertexQueue>::type Tail;
|
Chris@16
|
105 typedef typename VisitorOps::template examine_vertex<Vertex, Graph, VisitorState>::type examined_state;
|
Chris@16
|
106
|
Chris@16
|
107 // loop over out edges
|
Chris@16
|
108 typedef typename mpl::template
|
Chris@16
|
109 fold<typename mpl_graph::out_edges<Vertex, Graph>::type,
|
Chris@16
|
110 mpl::vector<examined_state, ColorMap, Tail>,
|
Chris@16
|
111 bfs_run_queue_examine_edge<Graph, VisitorOps, mpl::_1, mpl::_2>
|
Chris@16
|
112 >::type did_edges;
|
Chris@16
|
113
|
Chris@16
|
114 typedef typename VisitorOps::template
|
Chris@16
|
115 finish_vertex<Vertex, Graph, typename mpl::at_c<did_edges, 0>::type>::type
|
Chris@16
|
116 finished_vertex;
|
Chris@16
|
117 // does map insert always overwrite? i seem to remember this not working on msvc once
|
Chris@16
|
118 typedef typename search_color_map_ops::template
|
Chris@16
|
119 set_color<Vertex, search_colors::Black, typename mpl::at_c<did_edges, 1>::type>::type
|
Chris@16
|
120 colored_vertex;
|
Chris@16
|
121 typedef typename mpl::at_c<did_edges, 2>::type queued_targets;
|
Chris@16
|
122
|
Chris@16
|
123 typedef typename
|
Chris@16
|
124 mpl::if_<typename mpl::empty<queued_targets>::type,
|
Chris@16
|
125 mpl::pair<finished_vertex, colored_vertex>,
|
Chris@16
|
126 bfs_run_queue<Graph, queued_targets,
|
Chris@16
|
127 VisitorOps, finished_vertex,
|
Chris@16
|
128 colored_vertex> >::type::type type;
|
Chris@16
|
129 };
|
Chris@16
|
130
|
Chris@16
|
131 } // namespace detail
|
Chris@16
|
132
|
Chris@16
|
133 template<typename Graph, typename VisitorOps, typename VisitorState,
|
Chris@16
|
134 typename Vertex,
|
Chris@16
|
135 typename ColorMap = create_search_color_map::type >
|
Chris@16
|
136 struct breadth_first_search {
|
Chris@16
|
137 typedef typename VisitorOps::template
|
Chris@16
|
138 discover_vertex<Vertex, Graph, VisitorState>::type
|
Chris@16
|
139 discovered_state;
|
Chris@16
|
140 typedef typename search_color_map_ops::template
|
Chris@16
|
141 set_color<Vertex, search_colors::Gray, ColorMap>::type
|
Chris@16
|
142 discovered_colors;
|
Chris@16
|
143 typedef typename detail::
|
Chris@16
|
144 bfs_run_queue<Graph, mpl::vector<Vertex>,
|
Chris@16
|
145 VisitorOps, discovered_state,
|
Chris@16
|
146 discovered_colors>::type type;
|
Chris@16
|
147 };
|
Chris@16
|
148
|
Chris@16
|
149 template<typename Graph, typename VisitorOps, typename VisitorState,
|
Chris@16
|
150 typename FirstVertex = typename mpl::front<typename mpl_graph::vertices<Graph>::type>::type,
|
Chris@16
|
151 typename ColorMap = create_search_color_map::type>
|
Chris@16
|
152 struct breadth_first_search_all : // visit "first" first, then visit any still white
|
Chris@16
|
153 mpl::fold<typename mpl_graph::vertices<Graph>::type,
|
Chris@16
|
154 typename breadth_first_search<Graph, VisitorOps, VisitorState, FirstVertex, ColorMap>::type,
|
Chris@16
|
155 mpl::if_<boost::is_same<search_color_map_ops::template get_color<mpl::_2, mpl::second<mpl::_1> >,
|
Chris@16
|
156 search_colors::White>,
|
Chris@16
|
157 breadth_first_search<Graph, VisitorOps, mpl::first<mpl::_1>,
|
Chris@16
|
158 mpl::_2, mpl::second<mpl::_1> >,
|
Chris@16
|
159 mpl::_1> >
|
Chris@16
|
160 {};
|
Chris@16
|
161
|
Chris@16
|
162 } // namespace mpl_graph
|
Chris@16
|
163 } // namespace msm
|
Chris@16
|
164 } // namespace boost
|
Chris@16
|
165
|
Chris@16
|
166
|
Chris@16
|
167 #endif // BOOST_MSM_MPL_GRAPH_BREADTH_FIRST_SEARCH_HPP_INCLUDED
|