transformation.hpp 15 KB

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