transformation.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  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_EUML_TRANSFORMATION_H
  11. #define BOOST_MSM_FRONT_EUML_TRANSFORMATION_H
  12. #include <algorithm>
  13. #include <boost/msm/front/euml/common.hpp>
  14. namespace boost { namespace msm { namespace front { namespace euml
  15. {
  16. #ifdef __STL_CONFIG_H
  17. BOOST_MSM_EUML_FUNCTION(FillN_ , std::fill_n , fill_n_ , RESULT_TYPE_PARAM1 , RESULT_TYPE2_PARAM1 )
  18. BOOST_MSM_EUML_FUNCTION(Rotate_ , std::rotate , rotate_ , RESULT_TYPE_PARAM1 , RESULT_TYPE2_PARAM1 )
  19. BOOST_MSM_EUML_FUNCTION(GenerateN_ , std::generate_n , generate_n_ , RESULT_TYPE_PARAM1 , RESULT_TYPE2_PARAM1 )
  20. #else
  21. BOOST_MSM_EUML_FUNCTION(FillN_ , std::fill_n , fill_n_ , void , void )
  22. BOOST_MSM_EUML_FUNCTION(Rotate_ , std::rotate , rotate_ , void , void )
  23. BOOST_MSM_EUML_FUNCTION(GenerateN_ , std::generate_n , generate_n_ , void , void )
  24. #endif
  25. BOOST_MSM_EUML_FUNCTION(Copy_ , std::copy , copy_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  26. BOOST_MSM_EUML_FUNCTION(CopyBackward_ , std::copy_backward , copy_backward_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  27. BOOST_MSM_EUML_FUNCTION(Reverse_ , std::reverse , reverse_ , void , void )
  28. BOOST_MSM_EUML_FUNCTION(ReverseCopy_ , std::reverse_copy , reverse_copy_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  29. BOOST_MSM_EUML_FUNCTION(Remove_ , std::remove , remove_ , RESULT_TYPE_PARAM1 , RESULT_TYPE2_PARAM1 )
  30. BOOST_MSM_EUML_FUNCTION(RemoveIf_ , std::remove_if , remove_if_ , RESULT_TYPE_PARAM1 , RESULT_TYPE2_PARAM1 )
  31. BOOST_MSM_EUML_FUNCTION(RemoveCopy_ , std::remove_copy , remove_copy_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  32. BOOST_MSM_EUML_FUNCTION(RemoveCopyIf_ , std::remove_copy_if , remove_copy_if_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  33. BOOST_MSM_EUML_FUNCTION(Fill_ , std::fill , fill_ , void , void )
  34. BOOST_MSM_EUML_FUNCTION(Generate_ , std::generate , generate_ , void , void )
  35. BOOST_MSM_EUML_FUNCTION(Unique_ , std::unique , unique_ , RESULT_TYPE_PARAM1 , RESULT_TYPE2_PARAM1 )
  36. BOOST_MSM_EUML_FUNCTION(UniqueCopy_ , std::unique_copy , unique_copy_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  37. BOOST_MSM_EUML_FUNCTION(RandomShuffle_ , std::random_shuffle , random_shuffle_ , void , void )
  38. BOOST_MSM_EUML_FUNCTION(RotateCopy_ , std::rotate_copy , rotate_copy_ , RESULT_TYPE_PARAM4 , RESULT_TYPE2_PARAM4 )
  39. BOOST_MSM_EUML_FUNCTION(Partition_ , std::partition , partition_ , RESULT_TYPE_PARAM1 , RESULT_TYPE2_PARAM1 )
  40. BOOST_MSM_EUML_FUNCTION(StablePartition_ , std::stable_partition , stable_partition_ , RESULT_TYPE_PARAM1 , RESULT_TYPE2_PARAM1 )
  41. BOOST_MSM_EUML_FUNCTION(Sort_ , std::sort , sort_ , void , void )
  42. BOOST_MSM_EUML_FUNCTION(StableSort_ , std::stable_sort , stable_sort_ , void , void )
  43. BOOST_MSM_EUML_FUNCTION(PartialSort_ , std::partial_sort , partial_sort_ , void , void )
  44. BOOST_MSM_EUML_FUNCTION(PartialSortCopy_ , std::partial_sort_copy , partial_sort_copy_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  45. BOOST_MSM_EUML_FUNCTION(NthElement_ , std::nth_element , nth_element_ , void , void )
  46. BOOST_MSM_EUML_FUNCTION(Merge_ , std::merge , merge_ , RESULT_TYPE_PARAM5 , RESULT_TYPE2_PARAM5 )
  47. BOOST_MSM_EUML_FUNCTION(InplaceMerge_ , std::inplace_merge , inplace_merge_ , void , void )
  48. BOOST_MSM_EUML_FUNCTION(SetUnion_ , std::set_union , set_union_ , RESULT_TYPE_PARAM5 , RESULT_TYPE2_PARAM5 )
  49. BOOST_MSM_EUML_FUNCTION(PushHeap_ , std::push_heap , push_heap_ , void , void )
  50. BOOST_MSM_EUML_FUNCTION(PopHeap_ , std::pop_heap , pop_heap_ , void , void )
  51. BOOST_MSM_EUML_FUNCTION(MakeHeap_ , std::make_heap , make_heap_ , void , void )
  52. BOOST_MSM_EUML_FUNCTION(SortHeap_ , std::sort_heap , sort_heap_ , void , void )
  53. BOOST_MSM_EUML_FUNCTION(NextPermutation_ , std::next_permutation , next_permutation_ , bool , bool )
  54. BOOST_MSM_EUML_FUNCTION(PrevPermutation_ , std::prev_permutation , prev_permutation_ , bool , bool )
  55. BOOST_MSM_EUML_FUNCTION(InnerProduct_ , std::inner_product , inner_product_ , RESULT_TYPE_PARAM4 , RESULT_TYPE2_PARAM4 )
  56. BOOST_MSM_EUML_FUNCTION(PartialSum_ , std::partial_sum , partial_sum_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  57. BOOST_MSM_EUML_FUNCTION(AdjacentDifference_ , std::adjacent_difference , adjacent_difference_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  58. BOOST_MSM_EUML_FUNCTION(Replace_ , std::replace , replace_ , void , void )
  59. BOOST_MSM_EUML_FUNCTION(ReplaceIf_ , std::replace_if , replace_if_ , void , void )
  60. BOOST_MSM_EUML_FUNCTION(ReplaceCopy_ , std::replace_copy , replace_copy_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  61. BOOST_MSM_EUML_FUNCTION(ReplaceCopyIf_ , std::replace_copy_if , replace_copy_if_ , RESULT_TYPE_PARAM3 , RESULT_TYPE2_PARAM3 )
  62. template <class T>
  63. struct BackInserter_ : euml_action<BackInserter_<T> >
  64. {
  65. template <class Event,class FSM,class STATE >
  66. struct state_action_result
  67. {
  68. typedef std::back_insert_iterator<
  69. typename ::boost::remove_reference<
  70. typename get_result_type2<T,Event,FSM,STATE>::type>::type> type;
  71. };
  72. template <class EVT,class FSM,class SourceState,class TargetState>
  73. struct transition_action_result
  74. {
  75. typedef std::back_insert_iterator<
  76. typename ::boost::remove_reference<
  77. typename get_result_type<T,EVT,FSM,SourceState,TargetState>::type>::type> type;
  78. };
  79. typedef ::boost::mpl::set<state_action_tag,action_tag> tag_type;
  80. template <class EVT,class FSM,class SourceState,class TargetState>
  81. typename ::boost::enable_if<
  82. typename ::boost::mpl::has_key<
  83. typename T::tag_type,action_tag>::type,
  84. typename transition_action_result<EVT,FSM,SourceState,TargetState>::type >::type
  85. operator()(EVT const& evt, FSM& fsm,SourceState& src,TargetState& tgt)const
  86. {
  87. return std::back_inserter(T()(evt,fsm,src,tgt));
  88. }
  89. template <class Event,class FSM,class STATE>
  90. typename ::boost::enable_if<
  91. typename ::boost::mpl::has_key<
  92. typename T::tag_type,state_action_tag>::type,
  93. typename state_action_result<Event,FSM,STATE>::type >::type
  94. operator()(Event const& evt,FSM& fsm,STATE& state )const
  95. {
  96. return std::back_inserter(T()(evt,fsm,state));
  97. }
  98. };
  99. struct back_inserter_tag {};
  100. struct BackInserter_Helper: proto::extends< proto::terminal<back_inserter_tag>::type, BackInserter_Helper, boost::msm::sm_domain>
  101. {
  102. BackInserter_Helper(){}
  103. template <class Arg1,class Arg2,class Arg3,class Arg4,class Arg5
  104. #ifdef BOOST_MSVC
  105. ,class Arg6
  106. #endif
  107. >
  108. struct In
  109. {
  110. typedef BackInserter_<Arg1> type;
  111. };
  112. };
  113. BackInserter_Helper const back_inserter_;
  114. template <class T>
  115. struct FrontInserter_ : euml_action<FrontInserter_<T> >
  116. {
  117. template <class Event,class FSM,class STATE >
  118. struct state_action_result
  119. {
  120. typedef std::front_insert_iterator<
  121. typename ::boost::remove_reference<
  122. typename get_result_type2<T,Event,FSM,STATE>::type>::type> type;
  123. };
  124. template <class EVT,class FSM,class SourceState,class TargetState>
  125. struct transition_action_result
  126. {
  127. typedef std::front_insert_iterator<
  128. typename ::boost::remove_reference<
  129. typename get_result_type<T,EVT,FSM,SourceState,TargetState>::type>::type> type;
  130. };
  131. typedef ::boost::mpl::set<state_action_tag,action_tag> tag_type;
  132. template <class EVT,class FSM,class SourceState,class TargetState>
  133. typename ::boost::enable_if<
  134. typename ::boost::mpl::has_key<
  135. typename T::tag_type,action_tag>::type,
  136. typename transition_action_result<EVT,FSM,SourceState,TargetState>::type >::type
  137. operator()(EVT const& evt, FSM& fsm,SourceState& src,TargetState& tgt)const
  138. {
  139. return std::front_inserter(T()(evt,fsm,src,tgt));
  140. }
  141. template <class Event,class FSM,class STATE>
  142. typename ::boost::enable_if<
  143. typename ::boost::mpl::has_key<
  144. typename T::tag_type,state_action_tag>::type,
  145. typename state_action_result<Event,FSM,STATE>::type >::type
  146. operator()(Event const& evt,FSM& fsm,STATE& state )const
  147. {
  148. return std::front_inserter(T()(evt,fsm,state));
  149. }
  150. };
  151. struct front_inserter_tag {};
  152. struct FrontInserter_Helper: proto::extends< proto::terminal<front_inserter_tag>::type, FrontInserter_Helper, boost::msm::sm_domain>
  153. {
  154. FrontInserter_Helper(){}
  155. template <class Arg1,class Arg2,class Arg3,class Arg4,class Arg5
  156. #ifdef BOOST_MSVC
  157. ,class Arg6
  158. #endif
  159. >
  160. struct In
  161. {
  162. typedef FrontInserter_<Arg1> type;
  163. };
  164. };
  165. FrontInserter_Helper const front_inserter_;
  166. template <class T,class Pos>
  167. struct Inserter_ : euml_action<Inserter_<T,Pos> >
  168. {
  169. template <class Event,class FSM,class STATE >
  170. struct state_action_result
  171. {
  172. typedef std::insert_iterator<
  173. typename ::boost::remove_reference<
  174. typename get_result_type2<T,Event,FSM,STATE>::type>::type> type;
  175. };
  176. template <class EVT,class FSM,class SourceState,class TargetState>
  177. struct transition_action_result
  178. {
  179. typedef std::insert_iterator<
  180. typename ::boost::remove_reference<
  181. typename get_result_type<T,EVT,FSM,SourceState,TargetState>::type>::type> type;
  182. };
  183. typedef ::boost::mpl::set<state_action_tag,action_tag> tag_type;
  184. template <class EVT,class FSM,class SourceState,class TargetState>
  185. typename ::boost::enable_if<
  186. typename ::boost::mpl::has_key<
  187. typename T::tag_type,action_tag>::type,
  188. typename transition_action_result<EVT,FSM,SourceState,TargetState>::type >::type
  189. operator()(EVT const& evt, FSM& fsm,SourceState& src,TargetState& tgt)const
  190. {
  191. return std::inserter(T()(evt,fsm,src,tgt),Pos()(evt,fsm,src,tgt));
  192. }
  193. template <class Event,class FSM,class STATE>
  194. typename ::boost::enable_if<
  195. typename ::boost::mpl::has_key<
  196. typename T::tag_type,state_action_tag>::type,
  197. typename state_action_result<Event,FSM,STATE>::type >::type
  198. operator()(Event const& evt,FSM& fsm,STATE& state )const
  199. {
  200. return std::inserter(T()(evt,fsm,state),Pos()(evt,fsm,state));
  201. }
  202. };
  203. struct inserter_tag {};
  204. struct Inserter_Helper: proto::extends< proto::terminal<inserter_tag>::type, Inserter_Helper, boost::msm::sm_domain>
  205. {
  206. Inserter_Helper(){}
  207. template <class Arg1,class Arg2,class Arg3,class Arg4,class Arg5
  208. #ifdef BOOST_MSVC
  209. ,class Arg6
  210. #endif
  211. >
  212. struct In
  213. {
  214. typedef Inserter_<Arg1,Arg2> type;
  215. };
  216. };
  217. Inserter_Helper const inserter_;
  218. template <class Param1, class Param2, class Param3, class Param4, class Param5, class Enable=void >
  219. struct Transform_ : euml_action<Transform_<Param1,Param2,Param3,Param4,Param5,Enable> >
  220. {
  221. };
  222. template <class Param1, class Param2, class Param3, class Param4, class Param5>
  223. struct Transform_<Param1,Param2,Param3,Param4,Param5,
  224. typename ::boost::enable_if<typename ::boost::is_same<Param5,void>::type >::type>
  225. : euml_action<Transform_<Param1,Param2,Param3,Param4,Param5> >
  226. {
  227. template <class Event,class FSM,class STATE >
  228. struct state_action_result
  229. {
  230. typedef typename get_result_type2<Param3,Event,FSM,STATE>::type type;
  231. };
  232. template <class EVT,class FSM,class SourceState,class TargetState>
  233. struct transition_action_result
  234. {
  235. typedef typename get_result_type<Param3,EVT,FSM,SourceState,TargetState>::type type;
  236. };
  237. typedef ::boost::mpl::set<state_action_tag,action_tag> tag_type;
  238. template <class EVT,class FSM,class SourceState,class TargetState>
  239. typename ::boost::enable_if<
  240. typename ::boost::mpl::has_key<
  241. typename Param1::tag_type,action_tag>::type,
  242. typename transition_action_result<EVT,FSM,SourceState,TargetState>::type >::type
  243. operator()(EVT const& evt, FSM& fsm,SourceState& src,TargetState& tgt)const
  244. {
  245. return std::transform(Param1()(evt,fsm,src,tgt),Param2()(evt,fsm,src,tgt),Param3()(evt,fsm,src,tgt),
  246. Param4()(evt,fsm,src,tgt));
  247. }
  248. template <class Event,class FSM,class STATE>
  249. typename ::boost::enable_if<
  250. typename ::boost::mpl::has_key<
  251. typename Param1::tag_type,state_action_tag>::type,
  252. typename state_action_result<Event,FSM,STATE>::type >::type
  253. operator()(Event const& evt,FSM& fsm,STATE& state )const
  254. {
  255. return std::transform(Param1()(evt,fsm,state),Param2()(evt,fsm,state),Param3()(evt,fsm,state),
  256. Param4()(evt,fsm,state));
  257. }
  258. };
  259. template <class Param1, class Param2, class Param3, class Param4, class Param5>
  260. struct Transform_<Param1,Param2,Param3,Param4,Param5,
  261. typename ::boost::disable_if<typename ::boost::is_same<Param5,void>::type >::type>
  262. : euml_action<Transform_<Param1,Param2,Param3,Param4,Param5> >
  263. {
  264. template <class Event,class FSM,class STATE >
  265. struct state_action_result
  266. {
  267. typedef typename get_result_type2<Param4,Event,FSM,STATE>::type type;
  268. };
  269. template <class EVT,class FSM,class SourceState,class TargetState>
  270. struct transition_action_result
  271. {
  272. typedef typename get_result_type<Param4,EVT,FSM,SourceState,TargetState>::type type;
  273. };
  274. typedef ::boost::mpl::set<state_action_tag,action_tag> tag_type;
  275. template <class EVT,class FSM,class SourceState,class TargetState>
  276. typename ::boost::enable_if<
  277. typename ::boost::mpl::has_key<
  278. typename Param1::tag_type,action_tag>::type,
  279. typename transition_action_result<EVT,FSM,SourceState,TargetState>::type >::type
  280. operator()(EVT const& evt, FSM& fsm,SourceState& src,TargetState& tgt)const
  281. {
  282. return std::transform (Param1()(evt,fsm,src,tgt),Param2()(evt,fsm,src,tgt),Param3()(evt,fsm,src,tgt),
  283. Param4()(evt,fsm,src,tgt),Param5()(evt,fsm,src,tgt));
  284. }
  285. template <class Event,class FSM,class STATE>
  286. typename ::boost::enable_if<
  287. typename ::boost::mpl::has_key<
  288. typename Param1::tag_type,state_action_tag>::type,
  289. typename state_action_result<Event,FSM,STATE>::type >::type
  290. operator()(Event const& evt,FSM& fsm,STATE& state )const
  291. {
  292. return std::transform (Param1()(evt,fsm,state),Param2()(evt,fsm,state),Param3()(evt,fsm,state),
  293. Param4()(evt,fsm,state),Param5()(evt,fsm,state));
  294. }
  295. };
  296. struct transform_tag {};
  297. struct Transform_Helper: proto::extends< proto::terminal<transform_tag>::type, Transform_Helper, boost::msm::sm_domain>
  298. {
  299. Transform_Helper(){}
  300. template <class Arg1,class Arg2,class Arg3,class Arg4,class Arg5
  301. #ifdef BOOST_MSVC
  302. ,class Arg6
  303. #endif
  304. >
  305. struct In
  306. {
  307. typedef Transform_<Arg1,Arg2,Arg3,Arg4,Arg5> type;
  308. };
  309. };
  310. Transform_Helper const transform_;
  311. }}}}
  312. #endif //BOOST_MSM_FRONT_EUML_TRANSFORMATION_H