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