Chris@16
|
1 // Copyright 2008 Christophe Henry
|
Chris@16
|
2 // henry UNDERSCORE christophe AT hotmail DOT com
|
Chris@16
|
3 // This is an extended version of the state machine available in the boost::mpl library
|
Chris@16
|
4 // Distributed under the same license as the original.
|
Chris@16
|
5 // Copyright for the original version:
|
Chris@16
|
6 // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
Chris@16
|
7 // under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
8 // file LICENSE_1_0.txt or copy at
|
Chris@16
|
9 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_MSM_FRONT_EUML_STT_GRAMMAR_H
|
Chris@16
|
12 #define BOOST_MSM_FRONT_EUML_STT_GRAMMAR_H
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/msm/front/euml/common.hpp>
|
Chris@16
|
15 #include <boost/mpl/vector.hpp>
|
Chris@16
|
16 #include <boost/mpl/eval_if.hpp>
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/msm/front/euml/operator.hpp>
|
Chris@16
|
19 #include <boost/msm/front/euml/guard_grammar.hpp>
|
Chris@16
|
20 #include <boost/msm/front/euml/state_grammar.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 namespace proto = boost::proto;
|
Chris@16
|
23
|
Chris@16
|
24 namespace boost { namespace msm { namespace front { namespace euml
|
Chris@16
|
25 {
|
Chris@16
|
26
|
Chris@16
|
27 template <class SOURCE,class EVENT,class TARGET,class ACTION=none,class GUARD=none>
|
Chris@16
|
28 struct TempRow
|
Chris@16
|
29 {
|
Chris@16
|
30 typedef SOURCE Source;
|
Chris@16
|
31 typedef EVENT Evt;
|
Chris@16
|
32 typedef TARGET Target;
|
Chris@16
|
33 typedef ACTION Action;
|
Chris@16
|
34 typedef GUARD Guard;
|
Chris@16
|
35 };
|
Chris@16
|
36
|
Chris@16
|
37 template <class TEMP_ROW>
|
Chris@16
|
38 struct convert_to_row
|
Chris@16
|
39 {
|
Chris@16
|
40 typedef Row<typename TEMP_ROW::Source,typename TEMP_ROW::Evt,typename TEMP_ROW::Target,
|
Chris@16
|
41 typename TEMP_ROW::Action,typename TEMP_ROW::Guard> type;
|
Chris@16
|
42 };
|
Chris@16
|
43 template <class TEMP_ROW>
|
Chris@16
|
44 struct convert_to_internal_row
|
Chris@16
|
45 {
|
Chris@16
|
46 typedef Internal<typename TEMP_ROW::Evt,
|
Chris@16
|
47 typename TEMP_ROW::Action,typename TEMP_ROW::Guard> type;
|
Chris@16
|
48 };
|
Chris@16
|
49 // explicit + fork + entry point + exit point grammar
|
Chris@16
|
50 struct BuildEntry
|
Chris@16
|
51 : proto::or_<
|
Chris@16
|
52 proto::when<
|
Chris@16
|
53 proto::function<proto::terminal<proto::_>,proto::terminal<state_tag>,proto::terminal<state_tag> >,
|
Chris@16
|
54 get_fct<proto::_child_c<0>,get_state_name<proto::_child_c<1>() >(),get_state_name<proto::_child_c<2>() >() >()
|
Chris@16
|
55 >
|
Chris@16
|
56 >
|
Chris@16
|
57 {};
|
Chris@16
|
58
|
Chris@16
|
59 // row grammar
|
Chris@16
|
60 struct BuildNextStates
|
Chris@16
|
61 : proto::or_<
|
Chris@16
|
62 proto::when<
|
Chris@16
|
63 proto::terminal<state_tag>,
|
Chris@16
|
64 get_state_name<proto::_>()
|
Chris@16
|
65 >,
|
Chris@16
|
66 proto::when<
|
Chris@16
|
67 BuildEntry,
|
Chris@16
|
68 BuildEntry
|
Chris@16
|
69 >,
|
Chris@16
|
70 proto::when<
|
Chris@16
|
71 proto::comma<BuildEntry,BuildEntry >,
|
Chris@16
|
72 ::boost::mpl::push_back<
|
Chris@16
|
73 make_vector_one_row<BuildEntry(proto::_left)>(),
|
Chris@16
|
74 BuildEntry(proto::_right)>()
|
Chris@16
|
75 >,
|
Chris@16
|
76 proto::when <
|
Chris@16
|
77 proto::comma<BuildNextStates,BuildEntry >,
|
Chris@16
|
78 ::boost::mpl::push_back<
|
Chris@16
|
79 BuildNextStates(proto::_left),
|
Chris@16
|
80 BuildEntry(proto::_right) >()
|
Chris@16
|
81 >
|
Chris@16
|
82 >
|
Chris@16
|
83 {};
|
Chris@16
|
84
|
Chris@16
|
85 template <class EventGuard,class ActionClass>
|
Chris@16
|
86 struct fusion_event_action_guard
|
Chris@16
|
87 {
|
Chris@16
|
88 typedef TempRow<none,typename EventGuard::Evt,none,typename ActionClass::Action,typename EventGuard::Guard> type;
|
Chris@16
|
89 };
|
Chris@16
|
90
|
Chris@16
|
91 template <class SourceGuard,class ActionClass>
|
Chris@16
|
92 struct fusion_source_action_guard
|
Chris@16
|
93 {
|
Chris@16
|
94 typedef TempRow<typename SourceGuard::Source,none,none,typename ActionClass::Action,typename SourceGuard::Guard> type;
|
Chris@16
|
95 };
|
Chris@16
|
96
|
Chris@16
|
97 template <class SourceClass,class EventClass>
|
Chris@16
|
98 struct fusion_source_event_action_guard
|
Chris@16
|
99 {
|
Chris@16
|
100 typedef TempRow<typename SourceClass::Source,typename EventClass::Evt,
|
Chris@16
|
101 none,typename EventClass::Action,typename EventClass::Guard> type;
|
Chris@16
|
102 };
|
Chris@16
|
103 template <class Left,class Right>
|
Chris@16
|
104 struct fusion_left_right
|
Chris@16
|
105 {
|
Chris@16
|
106 typedef TempRow<typename Right::Source,typename Right::Evt,typename Left::Target
|
Chris@16
|
107 ,typename Right::Action,typename Right::Guard> type;
|
Chris@16
|
108 };
|
Chris@16
|
109
|
Chris@16
|
110 struct BuildEventPlusGuard
|
Chris@16
|
111 : proto::or_<
|
Chris@16
|
112 proto::when<
|
Chris@16
|
113 proto::subscript<proto::terminal<event_tag>, GuardGrammar >,
|
Chris@16
|
114 TempRow<none,proto::_left,none,none, GuardGrammar(proto::_right)>(proto::_right)
|
Chris@16
|
115 >
|
Chris@16
|
116 >
|
Chris@16
|
117 {};
|
Chris@16
|
118
|
Chris@16
|
119 struct BuildSourceState
|
Chris@16
|
120 : proto::or_<
|
Chris@16
|
121 proto::when<
|
Chris@16
|
122 proto::terminal<state_tag>,
|
Chris@16
|
123 get_state_name<proto::_>()
|
Chris@16
|
124 >,
|
Chris@16
|
125 proto::when<
|
Chris@16
|
126 BuildEntry,
|
Chris@16
|
127 BuildEntry
|
Chris@16
|
128 >
|
Chris@16
|
129 >
|
Chris@16
|
130 {};
|
Chris@16
|
131
|
Chris@16
|
132 struct BuildSourcePlusGuard
|
Chris@16
|
133 : proto::when<
|
Chris@16
|
134 proto::subscript<BuildSourceState,GuardGrammar >,
|
Chris@16
|
135 TempRow<BuildSourceState(proto::_left),none,none,none,GuardGrammar(proto::_right)>(proto::_right)
|
Chris@16
|
136 >
|
Chris@16
|
137 {};
|
Chris@16
|
138
|
Chris@16
|
139 struct BuildEvent
|
Chris@16
|
140 : proto::or_<
|
Chris@16
|
141 // just event without guard/action
|
Chris@16
|
142 proto::when<
|
Chris@16
|
143 proto::terminal<event_tag>,
|
Chris@16
|
144 TempRow<none,proto::_,none>() >
|
Chris@16
|
145 // event / action
|
Chris@16
|
146 , proto::when<
|
Chris@16
|
147 proto::divides<proto::terminal<event_tag>,ActionGrammar >,
|
Chris@16
|
148 TempRow<none,proto::_left,none,ActionGrammar(proto::_right) >(proto::_right) >
|
Chris@16
|
149 // event [ guard ]
|
Chris@16
|
150 , proto::when<
|
Chris@16
|
151 proto::subscript<proto::terminal<event_tag>,GuardGrammar >,
|
Chris@16
|
152 TempRow<none,proto::_left,none,none,GuardGrammar(proto::_right)>(proto::_right) >
|
Chris@16
|
153 // event [ guard ] / action
|
Chris@16
|
154 , proto::when<
|
Chris@16
|
155 proto::divides<BuildEventPlusGuard, ActionGrammar>,
|
Chris@16
|
156 fusion_event_action_guard<BuildEventPlusGuard(proto::_left),
|
Chris@16
|
157 TempRow<none,none,none,ActionGrammar(proto::_right)>(proto::_right)
|
Chris@16
|
158 >()
|
Chris@16
|
159 >
|
Chris@16
|
160 >
|
Chris@16
|
161 {};
|
Chris@16
|
162 struct BuildSource
|
Chris@16
|
163 : proto::or_<
|
Chris@16
|
164 // after == if just state without event or guard/action
|
Chris@16
|
165 proto::when<
|
Chris@16
|
166 BuildSourceState,
|
Chris@16
|
167 TempRow<BuildSourceState(proto::_),none,none>() >
|
Chris@16
|
168 // == source / action
|
Chris@16
|
169 , proto::when<
|
Chris@16
|
170 proto::divides<BuildSourceState,ActionGrammar >,
|
Chris@16
|
171 TempRow<BuildSourceState(proto::_left),none,none,ActionGrammar(proto::_right) >(proto::_right) >
|
Chris@16
|
172 // == source [ guard ]
|
Chris@16
|
173 , proto::when<
|
Chris@16
|
174 proto::subscript<BuildSourceState,GuardGrammar >,
|
Chris@16
|
175 TempRow<BuildSourceState(proto::_left),none,none,none,GuardGrammar(proto::_right)>(proto::_right) >
|
Chris@16
|
176 // == source [ guard ] / action
|
Chris@16
|
177 , proto::when<
|
Chris@16
|
178 proto::divides<BuildSourcePlusGuard,
|
Chris@16
|
179 ActionGrammar >,
|
Chris@16
|
180 fusion_source_action_guard<BuildSourcePlusGuard(proto::_left),
|
Chris@16
|
181 TempRow<none,none,none,ActionGrammar(proto::_right)>(proto::_right)
|
Chris@16
|
182 >()
|
Chris@16
|
183 >
|
Chris@16
|
184 >
|
Chris@16
|
185 {};
|
Chris@16
|
186
|
Chris@16
|
187 struct BuildRight
|
Chris@16
|
188 : proto::or_<
|
Chris@16
|
189 proto::when<
|
Chris@16
|
190 proto::plus<BuildSource,BuildEvent >,
|
Chris@16
|
191 fusion_source_event_action_guard<BuildSource(proto::_left),BuildEvent(proto::_right)>()
|
Chris@16
|
192 >,
|
Chris@16
|
193 proto::when<
|
Chris@16
|
194 BuildSource,
|
Chris@16
|
195 BuildSource
|
Chris@16
|
196 >
|
Chris@16
|
197 >
|
Chris@16
|
198 {};
|
Chris@16
|
199
|
Chris@16
|
200 struct BuildRow
|
Chris@16
|
201 : proto::or_<
|
Chris@16
|
202 // grammar 1
|
Chris@16
|
203 proto::when<
|
Chris@16
|
204 proto::equal_to<BuildNextStates,BuildRight >,
|
Chris@16
|
205 convert_to_row<
|
Chris@16
|
206 fusion_left_right<TempRow<none,none,BuildNextStates(proto::_left)>,BuildRight(proto::_right)> >()
|
Chris@16
|
207 >,
|
Chris@16
|
208 // internal events
|
Chris@16
|
209 proto::when<
|
Chris@16
|
210 BuildRight,
|
Chris@16
|
211 convert_to_row<
|
Chris@16
|
212 fusion_left_right<TempRow<none,none,none>,BuildRight(proto::_)> >()
|
Chris@16
|
213 >,
|
Chris@16
|
214 // grammar 2
|
Chris@16
|
215 proto::when<
|
Chris@16
|
216 proto::equal_to<BuildRight,BuildNextStates>,
|
Chris@16
|
217 convert_to_row<
|
Chris@16
|
218 fusion_left_right<TempRow<none,none,BuildNextStates(proto::_right)>,BuildRight(proto::_left)> >()
|
Chris@16
|
219 >
|
Chris@16
|
220 >
|
Chris@16
|
221 {};
|
Chris@16
|
222
|
Chris@16
|
223 // stt grammar
|
Chris@16
|
224 struct BuildStt
|
Chris@16
|
225 : proto::or_<
|
Chris@16
|
226 proto::when<
|
Chris@16
|
227 proto::comma<BuildStt,BuildStt>,
|
Chris@16
|
228 boost::mpl::push_back<BuildStt(proto::_left),BuildRow(proto::_right)>()
|
Chris@16
|
229 >,
|
Chris@16
|
230 proto::when <
|
Chris@16
|
231 BuildRow,
|
Chris@16
|
232 make_vector_one_row<BuildRow(proto::_)>()
|
Chris@16
|
233 >
|
Chris@16
|
234 >
|
Chris@16
|
235 {};
|
Chris@16
|
236
|
Chris@16
|
237 template <class Expr>
|
Chris@16
|
238 typename ::boost::mpl::eval_if<
|
Chris@16
|
239 typename proto::matches<Expr,BuildStt>::type,
|
Chris@16
|
240 boost::result_of<BuildStt(Expr)>,
|
Chris@16
|
241 make_invalid_type>::type
|
Chris@101
|
242 build_stt(Expr const&)
|
Chris@16
|
243 {
|
Chris@16
|
244 return typename boost::result_of<BuildStt(Expr)>::type();
|
Chris@16
|
245 }
|
Chris@16
|
246
|
Chris@16
|
247 // internal stt grammar
|
Chris@16
|
248 struct BuildInternalRow
|
Chris@16
|
249 : proto::when<
|
Chris@16
|
250 BuildEvent,
|
Chris@16
|
251 convert_to_internal_row<
|
Chris@16
|
252 fusion_left_right<TempRow<none,none,none>,BuildEvent(proto::_)> >()
|
Chris@16
|
253 >
|
Chris@16
|
254 {};
|
Chris@16
|
255 struct BuildInternalStt
|
Chris@16
|
256 : proto::or_<
|
Chris@16
|
257 proto::when<
|
Chris@16
|
258 proto::comma<BuildInternalStt,BuildInternalStt>,
|
Chris@16
|
259 boost::mpl::push_back<BuildInternalStt(proto::_left),BuildInternalRow(proto::_right)>()
|
Chris@16
|
260 >,
|
Chris@16
|
261 proto::when <
|
Chris@16
|
262 BuildInternalRow,
|
Chris@16
|
263 make_vector_one_row<BuildInternalRow(proto::_)>()
|
Chris@16
|
264 >
|
Chris@16
|
265 >
|
Chris@16
|
266 {};
|
Chris@16
|
267
|
Chris@16
|
268 template <class Expr>
|
Chris@16
|
269 typename ::boost::mpl::eval_if<
|
Chris@16
|
270 typename proto::matches<Expr,BuildInternalStt>::type,
|
Chris@16
|
271 boost::result_of<BuildInternalStt(Expr)>,
|
Chris@16
|
272 make_invalid_type>::type
|
Chris@101
|
273 build_internal_stt(Expr const&)
|
Chris@16
|
274 {
|
Chris@16
|
275 return typename boost::result_of<BuildInternalStt(Expr)>::type();
|
Chris@16
|
276 }
|
Chris@16
|
277
|
Chris@16
|
278
|
Chris@16
|
279 }}}}
|
Chris@16
|
280 #endif //BOOST_MSM_FRONT_EUML_STT_GRAMMAR_H
|