transformation.hpp 15 KB

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