functor_row.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. // Copyright 2008 Christophe Henry
  2. // henry UNDERSCORE christophe AT hotmail DOT com
  3. // This is an extended version of the state machine available in the boost::mpl library
  4. // Distributed under the same license as the original.
  5. // Copyright for the original version:
  6. // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
  7. // under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_MSM_FRONT_FUNCTOR_ROW_H
  11. #define BOOST_MSM_FRONT_FUNCTOR_ROW_H
  12. #include <boost/mpl/set.hpp>
  13. #include <boost/mpl/for_each.hpp>
  14. #include <boost/mpl/has_xxx.hpp>
  15. #include <boost/mpl/count_if.hpp>
  16. #include <boost/typeof/typeof.hpp>
  17. #include <boost/msm/back/common_types.hpp>
  18. #include <boost/msm/row_tags.hpp>
  19. #include <boost/msm/common.hpp>
  20. #include <boost/msm/front/completion_event.hpp>
  21. #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
  22. BOOST_MPL_HAS_XXX_TRAIT_DEF(deferring_action)
  23. BOOST_MPL_HAS_XXX_TRAIT_DEF(some_deferring_actions)
  24. namespace boost { namespace msm { namespace front
  25. {
  26. template <class Func,class Enable=void>
  27. struct get_functor_return_value
  28. {
  29. static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_TRUE;
  30. };
  31. template <class Func>
  32. struct get_functor_return_value<Func,
  33. typename ::boost::enable_if<
  34. typename has_deferring_action<Func>::type
  35. >::type
  36. >
  37. {
  38. static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_DEFERRED;
  39. };
  40. // for sequences
  41. template <class Func>
  42. struct get_functor_return_value<Func,
  43. typename ::boost::enable_if<
  44. typename has_some_deferring_actions<Func>::type
  45. >::type
  46. >
  47. {
  48. static const ::boost::msm::back::HandledEnum value =
  49. (Func::some_deferring_actions::value ? ::boost::msm::back::HANDLED_DEFERRED : ::boost::msm::back::HANDLED_TRUE );
  50. };
  51. template <class SOURCE,class EVENT,class TARGET,class ACTION=none,class GUARD=none>
  52. struct Row
  53. {
  54. typedef SOURCE Source;
  55. typedef EVENT Evt;
  56. typedef TARGET Target;
  57. typedef ACTION Action;
  58. typedef GUARD Guard;
  59. // action plus guard
  60. typedef row_tag row_type_tag;
  61. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  62. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  63. {
  64. // create functor, call it
  65. Action()(evt,fsm,src,tgt);
  66. return get_functor_return_value<Action>::value;
  67. }
  68. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  69. static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt,AllStates&)
  70. {
  71. // create functor, call it
  72. return Guard()(evt,fsm,src,tgt);
  73. }
  74. };
  75. template<class SOURCE,class EVENT,class TARGET>
  76. struct Row<SOURCE,EVENT,TARGET,none,none>
  77. {
  78. typedef SOURCE Source;
  79. typedef EVENT Evt;
  80. typedef TARGET Target;
  81. typedef none Action;
  82. typedef none Guard;
  83. // no action, no guard
  84. typedef _row_tag row_type_tag;
  85. };
  86. template<class SOURCE,class EVENT,class TARGET,class ACTION>
  87. struct Row<SOURCE,EVENT,TARGET,ACTION,none>
  88. {
  89. typedef SOURCE Source;
  90. typedef EVENT Evt;
  91. typedef TARGET Target;
  92. typedef ACTION Action;
  93. typedef none Guard;
  94. // no guard
  95. typedef a_row_tag row_type_tag;
  96. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  97. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  98. {
  99. // create functor, call it
  100. Action()(evt,fsm,src,tgt);
  101. return get_functor_return_value<Action>::value;
  102. }
  103. };
  104. template<class SOURCE,class EVENT,class TARGET,class GUARD>
  105. struct Row<SOURCE,EVENT,TARGET,none,GUARD>
  106. {
  107. typedef SOURCE Source;
  108. typedef EVENT Evt;
  109. typedef TARGET Target;
  110. typedef none Action;
  111. typedef GUARD Guard;
  112. // no action
  113. typedef g_row_tag row_type_tag;
  114. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  115. static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  116. {
  117. // create functor, call it
  118. return Guard()(evt,fsm,src,tgt);
  119. }
  120. };
  121. // internal transitions
  122. template<class SOURCE,class EVENT,class ACTION>
  123. struct Row<SOURCE,EVENT,none,ACTION,none>
  124. {
  125. typedef SOURCE Source;
  126. typedef EVENT Evt;
  127. typedef Source Target;
  128. typedef ACTION Action;
  129. typedef none Guard;
  130. // no guard
  131. typedef a_irow_tag row_type_tag;
  132. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  133. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  134. {
  135. // create functor, call it
  136. Action()(evt,fsm,src,tgt);
  137. return get_functor_return_value<Action>::value;
  138. }
  139. };
  140. template<class SOURCE,class EVENT,class GUARD>
  141. struct Row<SOURCE,EVENT,none,none,GUARD>
  142. {
  143. typedef SOURCE Source;
  144. typedef EVENT Evt;
  145. typedef Source Target;
  146. typedef none Action;
  147. typedef GUARD Guard;
  148. // no action
  149. typedef g_irow_tag row_type_tag;
  150. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  151. static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  152. {
  153. // create functor, call it
  154. return Guard()(evt,fsm,src,tgt);
  155. }
  156. };
  157. template<class SOURCE,class EVENT,class ACTION,class GUARD>
  158. struct Row<SOURCE,EVENT,none,ACTION,GUARD>
  159. {
  160. typedef SOURCE Source;
  161. typedef EVENT Evt;
  162. typedef Source Target;
  163. typedef ACTION Action;
  164. typedef GUARD Guard;
  165. // action + guard
  166. typedef irow_tag row_type_tag;
  167. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  168. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  169. {
  170. // create functor, call it
  171. Action()(evt,fsm,src,tgt);
  172. return get_functor_return_value<Action>::value;
  173. }
  174. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  175. static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  176. {
  177. // create functor, call it
  178. return Guard()(evt,fsm,src,tgt);
  179. }
  180. };
  181. template<class SOURCE,class EVENT>
  182. struct Row<SOURCE,EVENT,none,none,none>
  183. {
  184. typedef SOURCE Source;
  185. typedef EVENT Evt;
  186. typedef Source Target;
  187. typedef none Action;
  188. typedef none Guard;
  189. // no action, no guard
  190. typedef _irow_tag row_type_tag;
  191. };
  192. template<class TGT>
  193. struct get_row_target
  194. {
  195. typedef typename TGT::Target type;
  196. };
  197. template <class EVENT,class ACTION=none,class GUARD=none>
  198. struct Internal
  199. {
  200. typedef EVENT Evt;
  201. typedef ACTION Action;
  202. typedef GUARD Guard;
  203. // action plus guard
  204. typedef sm_i_row_tag row_type_tag;
  205. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  206. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  207. {
  208. // create functor, call it
  209. Action()(evt,fsm,src,tgt);
  210. return get_functor_return_value<Action>::value;
  211. }
  212. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  213. static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  214. {
  215. // create functor, call it
  216. return Guard()(evt,fsm,src,tgt);
  217. }
  218. };
  219. template<class EVENT,class ACTION>
  220. struct Internal<EVENT,ACTION,none>
  221. {
  222. typedef EVENT Evt;
  223. typedef ACTION Action;
  224. typedef none Guard;
  225. // no guard
  226. typedef sm_a_i_row_tag row_type_tag;
  227. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  228. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  229. {
  230. // create functor, call it
  231. Action()(evt,fsm,src,tgt);
  232. return get_functor_return_value<Action>::value;
  233. }
  234. };
  235. template<class EVENT,class GUARD>
  236. struct Internal<EVENT,none,GUARD>
  237. {
  238. typedef EVENT Evt;
  239. typedef none Action;
  240. typedef GUARD Guard;
  241. // no action
  242. typedef sm_g_i_row_tag row_type_tag;
  243. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  244. static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
  245. {
  246. // create functor, call it
  247. return Guard()(evt,fsm,src,tgt);
  248. }
  249. };
  250. template<class EVENT>
  251. struct Internal<EVENT,none,none>
  252. {
  253. typedef EVENT Evt;
  254. typedef none Action;
  255. typedef none Guard;
  256. // no action, no guard
  257. typedef sm__i_row_tag row_type_tag;
  258. };
  259. struct event_tag{};
  260. struct action_tag{};
  261. struct state_action_tag{};
  262. struct flag_tag{};
  263. struct config_tag{};
  264. struct not_euml_tag{};
  265. template <class Sequence>
  266. struct ActionSequence_
  267. {
  268. typedef Sequence sequence;
  269. // if one functor of the sequence defers events, the complete sequence does
  270. typedef ::boost::mpl::bool_<
  271. ::boost::mpl::count_if<sequence,
  272. has_deferring_action< ::boost::mpl::placeholders::_1 >
  273. >::value != 0> some_deferring_actions;
  274. template <class Event,class FSM,class STATE >
  275. struct state_action_result
  276. {
  277. typedef void type;
  278. };
  279. template <class EVT,class FSM,class STATE>
  280. struct Call
  281. {
  282. Call(EVT const& evt,FSM& fsm,STATE& state):
  283. evt_(evt),fsm_(fsm),state_(state){}
  284. template <class FCT>
  285. void operator()(::boost::msm::wrap<FCT> const& )
  286. {
  287. FCT()(evt_,fsm_,state_);
  288. }
  289. private:
  290. EVT const& evt_;
  291. FSM& fsm_;
  292. STATE& state_;
  293. };
  294. template <class EVT,class FSM,class SourceState,class TargetState>
  295. struct transition_action_result
  296. {
  297. typedef void type;
  298. };
  299. template <class EVT,class FSM,class SourceState,class TargetState>
  300. struct Call2
  301. {
  302. Call2(EVT const& evt,FSM& fsm,SourceState& src,TargetState& tgt):
  303. evt_(evt),fsm_(fsm),src_(src),tgt_(tgt){}
  304. template <class FCT>
  305. void operator()(::boost::msm::wrap<FCT> const& )
  306. {
  307. FCT()(evt_,fsm_,src_,tgt_);
  308. }
  309. private:
  310. EVT const & evt_;
  311. FSM& fsm_;
  312. SourceState& src_;
  313. TargetState& tgt_;
  314. };
  315. typedef ::boost::mpl::set<state_action_tag,action_tag> tag_type;
  316. template <class EVT,class FSM,class STATE>
  317. void operator()(EVT const& evt,FSM& fsm,STATE& state)
  318. {
  319. mpl::for_each<Sequence,boost::msm::wrap< ::boost::mpl::placeholders::_1> >
  320. (Call<EVT,FSM,STATE>(evt,fsm,state));
  321. }
  322. template <class EVT,class FSM,class SourceState,class TargetState>
  323. void operator()(EVT const& evt,FSM& fsm,SourceState& src,TargetState& tgt)
  324. {
  325. mpl::for_each<Sequence,boost::msm::wrap< ::boost::mpl::placeholders::_1> >
  326. (Call2<EVT,FSM,SourceState,TargetState>(evt,fsm,src,tgt));
  327. }
  328. };
  329. // functor pre-defined for basic functionality
  330. struct Defer
  331. {
  332. // mark as deferring to avoid stack overflows in certain conditions
  333. typedef int deferring_action;
  334. template <class EVT,class FSM,class SourceState,class TargetState>
  335. void operator()(EVT const& evt,FSM& fsm,SourceState& ,TargetState& ) const
  336. {
  337. fsm.defer_event(evt);
  338. }
  339. };
  340. }}}
  341. #endif //BOOST_MSM_FRONT_FUNCTOR_ROW_H