annotate DEPENDENCIES/generic/include/boost/msm/back/metafunctions.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright 2008 Christophe Henry
Chris@16 2 // henry UNDERSCORE christophe AT hotmail DOT com
Chris@16 3 // This is an extended version of the state machine available in the boost::mpl library
Chris@16 4 // Distributed under the same license as the original.
Chris@16 5 // Copyright for the original version:
Chris@16 6 // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
Chris@16 7 // under the Boost Software License, Version 1.0. (See accompanying
Chris@16 8 // file LICENSE_1_0.txt or copy at
Chris@16 9 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10
Chris@16 11 #ifndef BOOST_MSM_BACK_METAFUNCTIONS_H
Chris@16 12 #define BOOST_MSM_BACK_METAFUNCTIONS_H
Chris@16 13
Chris@16 14 #include <boost/mpl/set.hpp>
Chris@16 15 #include <boost/mpl/at.hpp>
Chris@16 16 #include <boost/mpl/pair.hpp>
Chris@16 17 #include <boost/mpl/map.hpp>
Chris@16 18 #include <boost/mpl/int.hpp>
Chris@16 19 #include <boost/mpl/has_xxx.hpp>
Chris@16 20 #include <boost/mpl/find.hpp>
Chris@16 21 #include <boost/mpl/count_if.hpp>
Chris@16 22 #include <boost/mpl/fold.hpp>
Chris@16 23 #include <boost/mpl/if.hpp>
Chris@16 24 #include <boost/mpl/has_key.hpp>
Chris@16 25 #include <boost/mpl/insert.hpp>
Chris@16 26 #include <boost/mpl/next_prior.hpp>
Chris@16 27 #include <boost/mpl/map.hpp>
Chris@16 28 #include <boost/mpl/push_back.hpp>
Chris@16 29 #include <boost/mpl/vector.hpp>
Chris@16 30 #include <boost/mpl/is_sequence.hpp>
Chris@16 31 #include <boost/mpl/size.hpp>
Chris@16 32 #include <boost/mpl/transform.hpp>
Chris@16 33 #include <boost/mpl/begin_end.hpp>
Chris@16 34 #include <boost/mpl/bool.hpp>
Chris@16 35 #include <boost/mpl/empty.hpp>
Chris@16 36 #include <boost/mpl/identity.hpp>
Chris@16 37 #include <boost/mpl/eval_if.hpp>
Chris@16 38 #include <boost/mpl/insert_range.hpp>
Chris@16 39 #include <boost/mpl/front.hpp>
Chris@16 40 #include <boost/mpl/logical.hpp>
Chris@16 41 #include <boost/mpl/plus.hpp>
Chris@16 42 #include <boost/mpl/copy_if.hpp>
Chris@16 43 #include <boost/mpl/back_inserter.hpp>
Chris@16 44 #include <boost/mpl/transform.hpp>
Chris@16 45
Chris@16 46 #include <boost/type_traits/is_same.hpp>
Chris@16 47 #include <boost/utility/enable_if.hpp>
Chris@16 48
Chris@16 49 #include <boost/msm/row_tags.hpp>
Chris@16 50
Chris@16 51 // mpl_graph graph implementation and depth first search
Chris@16 52 #include <boost/msm/mpl_graph/incidence_list_graph.hpp>
Chris@16 53 #include <boost/msm/mpl_graph/depth_first_search.hpp>
Chris@16 54
Chris@16 55 BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_creation)
Chris@16 56 BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_entry)
Chris@16 57 BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_exit)
Chris@16 58 BOOST_MPL_HAS_XXX_TRAIT_DEF(concrete_exit_state)
Chris@16 59 BOOST_MPL_HAS_XXX_TRAIT_DEF(composite_tag)
Chris@16 60 BOOST_MPL_HAS_XXX_TRAIT_DEF(not_real_row_tag)
Chris@16 61 BOOST_MPL_HAS_XXX_TRAIT_DEF(event_blocking_flag)
Chris@16 62 BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_entry_state)
Chris@16 63 BOOST_MPL_HAS_XXX_TRAIT_DEF(completion_event)
Chris@16 64 BOOST_MPL_HAS_XXX_TRAIT_DEF(no_exception_thrown)
Chris@16 65 BOOST_MPL_HAS_XXX_TRAIT_DEF(no_message_queue)
Chris@16 66 BOOST_MPL_HAS_XXX_TRAIT_DEF(activate_deferred_events)
Chris@16 67 BOOST_MPL_HAS_XXX_TRAIT_DEF(wrapped_entry)
Chris@16 68 BOOST_MPL_HAS_XXX_TRAIT_DEF(active_state_switch_policy)
Chris@16 69
Chris@16 70 namespace boost { namespace msm { namespace back
Chris@16 71 {
Chris@16 72 template <typename Sequence, typename Range>
Chris@16 73 struct set_insert_range
Chris@16 74 {
Chris@16 75 typedef typename ::boost::mpl::fold<
Chris@16 76 Range,Sequence,
Chris@16 77 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >
Chris@16 78 >::type type;
Chris@16 79 };
Chris@16 80
Chris@16 81 // returns the current state type of a transition
Chris@16 82 template <class Transition>
Chris@16 83 struct transition_source_type
Chris@16 84 {
Chris@16 85 typedef typename Transition::current_state_type type;
Chris@16 86 };
Chris@16 87
Chris@16 88 // returns the target state type of a transition
Chris@16 89 template <class Transition>
Chris@16 90 struct transition_target_type
Chris@16 91 {
Chris@16 92 typedef typename Transition::next_state_type type;
Chris@16 93 };
Chris@16 94
Chris@16 95 // helper functions for generate_state_ids
Chris@16 96 // create a pair of a state and a passed id for source and target states
Chris@16 97 template <class Id,class Transition>
Chris@16 98 struct make_pair_source_state_id
Chris@16 99 {
Chris@16 100 typedef typename ::boost::mpl::pair<typename Transition::current_state_type,Id> type;
Chris@16 101 };
Chris@16 102 template <class Id,class Transition>
Chris@16 103 struct make_pair_target_state_id
Chris@16 104 {
Chris@16 105 typedef typename ::boost::mpl::pair<typename Transition::next_state_type,Id> type;
Chris@16 106 };
Chris@16 107
Chris@16 108 // iterates through a transition table and automatically generates ids starting at 0
Chris@16 109 // first the source states, transition up to down
Chris@16 110 // then the target states, up to down
Chris@16 111 template <class stt>
Chris@16 112 struct generate_state_ids
Chris@16 113 {
Chris@16 114 typedef typename
Chris@16 115 ::boost::mpl::fold<
Chris@16 116 stt,::boost::mpl::pair< ::boost::mpl::map< >, ::boost::mpl::int_<0> >,
Chris@16 117 ::boost::mpl::pair<
Chris@16 118 ::boost::mpl::if_<
Chris@16 119 ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
Chris@16 120 transition_source_type< ::boost::mpl::placeholders::_2> >,
Chris@16 121 ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
Chris@16 122 ::boost::mpl::insert< ::boost::mpl::first<mpl::placeholders::_1>,
Chris@16 123 make_pair_source_state_id< ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
Chris@16 124 ::boost::mpl::placeholders::_2> >
Chris@16 125 >,
Chris@16 126 ::boost::mpl::if_<
Chris@16 127 ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
Chris@16 128 transition_source_type< ::boost::mpl::placeholders::_2> >,
Chris@16 129 ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
Chris@16 130 ::boost::mpl::next< ::boost::mpl::second<mpl::placeholders::_1 > >
Chris@16 131 >
Chris@16 132 > //pair
Chris@16 133 >::type source_state_ids;
Chris@16 134 typedef typename ::boost::mpl::first<source_state_ids>::type source_state_map;
Chris@16 135 typedef typename ::boost::mpl::second<source_state_ids>::type highest_state_id;
Chris@16 136
Chris@16 137
Chris@16 138 typedef typename
Chris@16 139 ::boost::mpl::fold<
Chris@16 140 stt,::boost::mpl::pair<source_state_map,highest_state_id >,
Chris@16 141 ::boost::mpl::pair<
Chris@16 142 ::boost::mpl::if_<
Chris@16 143 ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
Chris@16 144 transition_target_type< ::boost::mpl::placeholders::_2> >,
Chris@16 145 ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
Chris@16 146 ::boost::mpl::insert< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
Chris@16 147 make_pair_target_state_id< ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
Chris@16 148 ::boost::mpl::placeholders::_2> >
Chris@16 149 >,
Chris@16 150 ::boost::mpl::if_<
Chris@16 151 ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
Chris@16 152 transition_target_type< ::boost::mpl::placeholders::_2> >,
Chris@16 153 ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
Chris@16 154 ::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
Chris@16 155 >
Chris@16 156 > //pair
Chris@16 157 >::type all_state_ids;
Chris@16 158 typedef typename ::boost::mpl::first<all_state_ids>::type type;
Chris@16 159 };
Chris@16 160
Chris@16 161 template <class Fsm>
Chris@16 162 struct get_active_state_switch_policy_helper
Chris@16 163 {
Chris@16 164 typedef typename Fsm::active_state_switch_policy type;
Chris@16 165 };
Chris@16 166 template <class Iter>
Chris@16 167 struct get_active_state_switch_policy_helper2
Chris@16 168 {
Chris@16 169 typedef typename boost::mpl::deref<Iter>::type Fsm;
Chris@16 170 typedef typename Fsm::active_state_switch_policy type;
Chris@16 171 };
Chris@16 172 // returns the active state switching policy
Chris@16 173 template <class Fsm>
Chris@16 174 struct get_active_state_switch_policy
Chris@16 175 {
Chris@16 176 typedef typename ::boost::mpl::find_if<
Chris@16 177 typename Fsm::configuration,
Chris@16 178 has_active_state_switch_policy< ::boost::mpl::placeholders::_1 > >::type iter;
Chris@16 179
Chris@16 180 typedef typename ::boost::mpl::eval_if<
Chris@16 181 typename ::boost::is_same<
Chris@16 182 iter,
Chris@16 183 typename ::boost::mpl::end<typename Fsm::configuration>::type
Chris@16 184 >::type,
Chris@16 185 get_active_state_switch_policy_helper<Fsm>,
Chris@16 186 get_active_state_switch_policy_helper2< iter >
Chris@16 187 >::type type;
Chris@16 188 };
Chris@16 189
Chris@16 190 // returns the id of a given state
Chris@16 191 template <class stt,class State>
Chris@16 192 struct get_state_id
Chris@16 193 {
Chris@16 194 typedef typename ::boost::mpl::at<typename generate_state_ids<stt>::type,State>::type type;
Chris@16 195 enum {value = type::value};
Chris@16 196 };
Chris@16 197
Chris@16 198 // returns a mpl::vector containing the init states of a state machine
Chris@16 199 template <class States>
Chris@16 200 struct get_initial_states
Chris@16 201 {
Chris@16 202 typedef typename ::boost::mpl::if_<
Chris@16 203 ::boost::mpl::is_sequence<States>,
Chris@16 204 States,
Chris@16 205 typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,States>::type >::type type;
Chris@16 206 };
Chris@16 207 // returns a mpl::int_ containing the size of a region. If the argument is not a sequence, returns 1
Chris@16 208 template <class region>
Chris@16 209 struct get_number_of_regions
Chris@16 210 {
Chris@16 211 typedef typename mpl::if_<
Chris@16 212 ::boost::mpl::is_sequence<region>,
Chris@16 213 ::boost::mpl::size<region>,
Chris@16 214 ::boost::mpl::int_<1> >::type type;
Chris@16 215 };
Chris@16 216
Chris@16 217 // builds a mpl::vector of initial states
Chris@16 218 //TODO remove duplicate from get_initial_states
Chris@16 219 template <class region>
Chris@16 220 struct get_regions_as_sequence
Chris@16 221 {
Chris@16 222 typedef typename ::boost::mpl::if_<
Chris@16 223 ::boost::mpl::is_sequence<region>,
Chris@16 224 region,
Chris@16 225 typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,region>::type >::type type;
Chris@16 226 };
Chris@16 227
Chris@16 228 template <class ToCreateSeq>
Chris@16 229 struct get_explicit_creation_as_sequence
Chris@16 230 {
Chris@16 231 typedef typename ::boost::mpl::if_<
Chris@16 232 ::boost::mpl::is_sequence<ToCreateSeq>,
Chris@16 233 ToCreateSeq,
Chris@16 234 typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,ToCreateSeq>::type >::type type;
Chris@16 235 };
Chris@16 236
Chris@16 237 // returns true if 2 transitions have the same source (used to remove duplicates in search of composite states)
Chris@16 238 template <class stt,class Transition1,class Transition2>
Chris@16 239 struct have_same_source
Chris@16 240 {
Chris@16 241 enum {current_state1 = get_state_id<stt,typename Transition1::current_state_type >::type::value};
Chris@16 242 enum {current_state2 = get_state_id<stt,typename Transition2::current_state_type >::type::value};
Chris@16 243 enum {value = ((int)current_state1 == (int)current_state2) };
Chris@16 244 };
Chris@16 245
Chris@16 246
Chris@16 247 // A metafunction that returns the Event associated with a transition.
Chris@16 248 template <class Transition>
Chris@16 249 struct transition_event
Chris@16 250 {
Chris@16 251 typedef typename Transition::transition_event type;
Chris@16 252 };
Chris@16 253
Chris@16 254 // returns true for composite states
Chris@16 255 template <class State>
Chris@16 256 struct is_composite_state
Chris@16 257 {
Chris@16 258 enum {value = has_composite_tag<State>::type::value};
Chris@16 259 typedef typename has_composite_tag<State>::type type;
Chris@16 260 };
Chris@16 261
Chris@16 262 // transform a transition table in a container of source states
Chris@16 263 template <class stt>
Chris@16 264 struct keep_source_names
Chris@16 265 {
Chris@16 266 // instead of the rows we want only the names of the states (from source)
Chris@16 267 typedef typename
Chris@16 268 ::boost::mpl::transform<
Chris@16 269 stt,transition_source_type< ::boost::mpl::placeholders::_1> >::type type;
Chris@16 270 };
Chris@16 271
Chris@16 272 // transform a transition table in a container of target states
Chris@16 273 template <class stt>
Chris@16 274 struct keep_target_names
Chris@16 275 {
Chris@16 276 // instead of the rows we want only the names of the states (from source)
Chris@16 277 typedef typename
Chris@16 278 ::boost::mpl::transform<
Chris@16 279 stt,transition_target_type< ::boost::mpl::placeholders::_1> >::type type;
Chris@16 280 };
Chris@16 281
Chris@16 282 template <class stt>
Chris@16 283 struct generate_state_set
Chris@16 284 {
Chris@16 285 // keep in the original transition table only the source/target state types
Chris@16 286 typedef typename keep_source_names<stt>::type sources;
Chris@16 287 typedef typename keep_target_names<stt>::type targets;
Chris@16 288 typedef typename
Chris@16 289 ::boost::mpl::fold<
Chris@16 290 sources, ::boost::mpl::set<>,
Chris@16 291 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
Chris@16 292 >::type source_set;
Chris@16 293 typedef typename
Chris@16 294 ::boost::mpl::fold<
Chris@16 295 targets,source_set,
Chris@16 296 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
Chris@16 297 >::type type;
Chris@16 298 };
Chris@16 299
Chris@16 300 // iterates through the transition table and generate a mpl::set<> containing all the events
Chris@16 301 template <class stt>
Chris@16 302 struct generate_event_set
Chris@16 303 {
Chris@16 304 typedef typename
Chris@16 305 ::boost::mpl::fold<
Chris@16 306 stt, ::boost::mpl::set<>,
Chris@16 307 ::boost::mpl::if_<
Chris@16 308 ::boost::mpl::has_key< ::boost::mpl::placeholders::_1,
Chris@16 309 transition_event< ::boost::mpl::placeholders::_2> >,
Chris@16 310 ::boost::mpl::placeholders::_1,
Chris@16 311 ::boost::mpl::insert< ::boost::mpl::placeholders::_1,
Chris@16 312 transition_event< ::boost::mpl::placeholders::_2> > >
Chris@16 313 >::type type;
Chris@16 314 };
Chris@16 315
Chris@16 316 // returns a mpl::bool_<true> if State has Event as deferred event
Chris@16 317 template <class State, class Event>
Chris@16 318 struct has_state_delayed_event
Chris@16 319 {
Chris@16 320 typedef typename ::boost::mpl::find<typename State::deferred_events,Event>::type found;
Chris@16 321 typedef typename ::boost::mpl::if_<
Chris@16 322 ::boost::is_same<found,typename ::boost::mpl::end<typename State::deferred_events>::type >,
Chris@16 323 ::boost::mpl::bool_<false>,
Chris@16 324 ::boost::mpl::bool_<true> >::type type;
Chris@16 325 };
Chris@16 326 // returns a mpl::bool_<true> if State has any deferred event
Chris@16 327 template <class State>
Chris@16 328 struct has_state_delayed_events
Chris@16 329 {
Chris@16 330 typedef typename ::boost::mpl::if_<
Chris@16 331 ::boost::mpl::empty<typename State::deferred_events>,
Chris@16 332 ::boost::mpl::bool_<false>,
Chris@16 333 ::boost::mpl::bool_<true> >::type type;
Chris@16 334 };
Chris@16 335
Chris@16 336 // Template used to create dummy entries for initial states not found in the stt.
Chris@16 337 template< typename T1 >
Chris@16 338 struct not_a_row
Chris@16 339 {
Chris@16 340 typedef int not_real_row_tag;
Chris@16 341 struct dummy_event
Chris@16 342 {
Chris@16 343 };
Chris@16 344 typedef T1 current_state_type;
Chris@16 345 typedef T1 next_state_type;
Chris@16 346 typedef dummy_event transition_event;
Chris@16 347 };
Chris@16 348
Chris@16 349 // metafunctions used to find out if a state is entry, exit or something else
Chris@16 350 template <class State>
Chris@16 351 struct is_pseudo_entry
Chris@16 352 {
Chris@16 353 typedef typename ::boost::mpl::if_< typename has_pseudo_entry<State>::type,
Chris@16 354 ::boost::mpl::bool_<true>,::boost::mpl::bool_<false>
Chris@16 355 >::type type;
Chris@16 356 };
Chris@16 357 // says if a state is an exit pseudo state
Chris@16 358 template <class State>
Chris@16 359 struct is_pseudo_exit
Chris@16 360 {
Chris@16 361 typedef typename ::boost::mpl::if_< typename has_pseudo_exit<State>::type,
Chris@16 362 ::boost::mpl::bool_<true>, ::boost::mpl::bool_<false>
Chris@16 363 >::type type;
Chris@16 364 };
Chris@16 365 // says if a state is an entry pseudo state or an explicit entry
Chris@16 366 template <class State>
Chris@16 367 struct is_direct_entry
Chris@16 368 {
Chris@16 369 typedef typename ::boost::mpl::if_< typename has_explicit_entry_state<State>::type,
Chris@16 370 ::boost::mpl::bool_<true>, ::boost::mpl::bool_<false>
Chris@16 371 >::type type;
Chris@16 372 };
Chris@16 373
Chris@16 374 //converts a "fake" (simulated in a state_machine_ description )state into one which will really get created
Chris@16 375 template <class StateType,class CompositeType>
Chris@16 376 struct convert_fake_state
Chris@16 377 {
Chris@16 378 // converts a state (explicit entry) into the state we really are going to create (explicit<>)
Chris@16 379 typedef typename ::boost::mpl::if_<
Chris@16 380 typename is_direct_entry<StateType>::type,
Chris@16 381 typename CompositeType::template direct<StateType>,
Chris@16 382 typename ::boost::mpl::identity<StateType>::type
Chris@16 383 >::type type;
Chris@16 384 };
Chris@16 385
Chris@16 386 template <class StateType>
Chris@16 387 struct get_explicit_creation
Chris@16 388 {
Chris@16 389 typedef typename StateType::explicit_creation type;
Chris@16 390 };
Chris@16 391
Chris@16 392 template <class StateType>
Chris@16 393 struct get_wrapped_entry
Chris@16 394 {
Chris@16 395 typedef typename StateType::wrapped_entry type;
Chris@16 396 };
Chris@16 397 // used for states created with explicit_creation
Chris@16 398 // if the state is an explicit entry, we reach for the wrapped state
Chris@16 399 // otherwise, this returns the state itself
Chris@16 400 template <class StateType>
Chris@16 401 struct get_wrapped_state
Chris@16 402 {
Chris@16 403 typedef typename ::boost::mpl::eval_if<
Chris@16 404 typename has_wrapped_entry<StateType>::type,
Chris@16 405 get_wrapped_entry<StateType>,
Chris@16 406 ::boost::mpl::identity<StateType> >::type type;
Chris@16 407 };
Chris@16 408
Chris@16 409 template <class Derived>
Chris@16 410 struct create_stt
Chris@16 411 {
Chris@16 412 //typedef typename Derived::transition_table stt;
Chris@16 413 typedef typename Derived::real_transition_table Stt;
Chris@16 414 // get the state set
Chris@16 415 typedef typename generate_state_set<Stt>::type states;
Chris@16 416 // transform the initial region(s) in a sequence
Chris@16 417 typedef typename get_regions_as_sequence<typename Derived::initial_state>::type init_states;
Chris@16 418 // iterate through the initial states and add them in the stt if not already there
Chris@16 419 typedef typename
Chris@16 420 ::boost::mpl::fold<
Chris@16 421 init_states,Stt,
Chris@16 422 ::boost::mpl::if_<
Chris@16 423 ::boost::mpl::has_key<states, ::boost::mpl::placeholders::_2>,
Chris@16 424 ::boost::mpl::placeholders::_1,
Chris@16 425 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end< ::boost::mpl::placeholders::_1>,
Chris@16 426 not_a_row< get_wrapped_state< ::boost::mpl::placeholders::_2> > >
Chris@16 427 >
Chris@16 428 >::type with_init;
Chris@16 429 // do the same for states marked as explicitly created
Chris@16 430 typedef typename get_explicit_creation_as_sequence<
Chris@16 431 typename ::boost::mpl::eval_if<
Chris@16 432 typename has_explicit_creation<Derived>::type,
Chris@16 433 get_explicit_creation<Derived>,
Chris@16 434 ::boost::mpl::vector0<> >::type
Chris@16 435 >::type fake_explicit_created;
Chris@16 436
Chris@16 437 typedef typename
Chris@16 438 ::boost::mpl::transform<
Chris@16 439 fake_explicit_created,convert_fake_state< ::boost::mpl::placeholders::_1,Derived> >::type explicit_created;
Chris@16 440
Chris@16 441 typedef typename
Chris@16 442 ::boost::mpl::fold<
Chris@16 443 explicit_created,with_init,
Chris@16 444 ::boost::mpl::if_<
Chris@16 445 ::boost::mpl::has_key<states, ::boost::mpl::placeholders::_2>,
Chris@16 446 ::boost::mpl::placeholders::_1,
Chris@16 447 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end<mpl::placeholders::_1>,
Chris@16 448 not_a_row< get_wrapped_state< ::boost::mpl::placeholders::_2> > >
Chris@16 449 >
Chris@16 450 >::type type;
Chris@16 451 };
Chris@16 452
Chris@16 453 // returns the transition table of a Composite state
Chris@16 454 template <class Composite>
Chris@16 455 struct get_transition_table
Chris@16 456 {
Chris@16 457 typedef typename create_stt<Composite>::type type;
Chris@16 458 };
Chris@16 459
Chris@16 460 // recursively builds an internal table including those of substates, sub-substates etc.
Chris@16 461 // variant for submachines
Chris@16 462 template <class StateType,class IsComposite>
Chris@16 463 struct recursive_get_internal_transition_table
Chris@16 464 {
Chris@16 465 // get the composite's internal table
Chris@16 466 typedef typename StateType::internal_transition_table composite_table;
Chris@16 467 // and for every substate (state of submachine), recursively get the internal transition table
Chris@16 468 typedef typename generate_state_set<typename StateType::stt>::type composite_states;
Chris@16 469 typedef typename ::boost::mpl::fold<
Chris@16 470 composite_states, composite_table,
Chris@16 471 ::boost::mpl::insert_range< ::boost::mpl::placeholders::_1, ::boost::mpl::end< ::boost::mpl::placeholders::_1>,
Chris@16 472 recursive_get_internal_transition_table< ::boost::mpl::placeholders::_2, is_composite_state< ::boost::mpl::placeholders::_2> >
Chris@16 473 >
Chris@16 474 >::type type;
Chris@16 475 };
Chris@16 476 // stop iterating on leafs (simple states)
Chris@16 477 template <class StateType>
Chris@16 478 struct recursive_get_internal_transition_table<StateType, ::boost::mpl::false_ >
Chris@16 479 {
Chris@16 480 typedef typename StateType::internal_transition_table type;
Chris@16 481 };
Chris@16 482 // recursively get a transition table for a given composite state.
Chris@16 483 // returns the transition table for this state + the tables of all composite sub states recursively
Chris@16 484 template <class Composite>
Chris@16 485 struct recursive_get_transition_table
Chris@16 486 {
Chris@16 487 // get the transition table of the state if it's a state machine
Chris@16 488 typedef typename ::boost::mpl::eval_if<typename is_composite_state<Composite>::type,
Chris@16 489 get_transition_table<Composite>,
Chris@16 490 ::boost::mpl::vector0<>
Chris@16 491 >::type org_table;
Chris@16 492
Chris@16 493 typedef typename generate_state_set<org_table>::type states;
Chris@16 494
Chris@16 495 // and for every substate, recursively get the transition table if it's a state machine
Chris@16 496 typedef typename ::boost::mpl::fold<
Chris@16 497 states,org_table,
Chris@16 498 ::boost::mpl::insert_range< ::boost::mpl::placeholders::_1, ::boost::mpl::end<mpl::placeholders::_1>,
Chris@16 499 recursive_get_transition_table< ::boost::mpl::placeholders::_2 > >
Chris@16 500 >::type type;
Chris@16 501
Chris@16 502 };
Chris@16 503
Chris@16 504 // metafunction used to say if a SM has pseudo exit states
Chris@16 505 template <class Derived>
Chris@16 506 struct has_fsm_deferred_events
Chris@16 507 {
Chris@16 508 typedef typename create_stt<Derived>::type Stt;
Chris@16 509 typedef typename generate_state_set<Stt>::type state_list;
Chris@16 510
Chris@16 511 typedef typename ::boost::mpl::or_<
Chris@16 512 typename has_activate_deferred_events<Derived>::type,
Chris@16 513 ::boost::mpl::bool_< ::boost::mpl::count_if<
Chris@16 514 typename Derived::configuration,
Chris@16 515 has_activate_deferred_events< ::boost::mpl::placeholders::_1 > >::value != 0>
Chris@16 516 >::type found_in_fsm;
Chris@16 517
Chris@16 518 typedef typename ::boost::mpl::or_<
Chris@16 519 found_in_fsm,
Chris@16 520 ::boost::mpl::bool_< ::boost::mpl::count_if<
Chris@16 521 state_list,has_state_delayed_events<
Chris@16 522 ::boost::mpl::placeholders::_1 > >::value != 0>
Chris@16 523 >::type type;
Chris@16 524 };
Chris@16 525
Chris@16 526 // returns a mpl::bool_<true> if State has any delayed event
Chris@16 527 template <class Event>
Chris@16 528 struct is_completion_event
Chris@16 529 {
Chris@16 530 typedef typename ::boost::mpl::if_<
Chris@16 531 has_completion_event<Event>,
Chris@16 532 ::boost::mpl::bool_<true>,
Chris@16 533 ::boost::mpl::bool_<false> >::type type;
Chris@16 534 };
Chris@16 535 // metafunction used to say if a SM has eventless transitions
Chris@16 536 template <class Derived>
Chris@16 537 struct has_fsm_eventless_transition
Chris@16 538 {
Chris@16 539 typedef typename create_stt<Derived>::type Stt;
Chris@16 540 typedef typename generate_event_set<Stt>::type event_list;
Chris@16 541
Chris@16 542 typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
Chris@16 543 event_list,is_completion_event< ::boost::mpl::placeholders::_1 > >::value != 0> type;
Chris@16 544 };
Chris@16 545 template <class Derived>
Chris@16 546 struct find_completion_events
Chris@16 547 {
Chris@16 548 typedef typename create_stt<Derived>::type Stt;
Chris@16 549 typedef typename generate_event_set<Stt>::type event_list;
Chris@16 550
Chris@16 551 typedef typename ::boost::mpl::fold<
Chris@16 552 event_list, ::boost::mpl::set<>,
Chris@16 553 ::boost::mpl::if_<
Chris@16 554 is_completion_event< ::boost::mpl::placeholders::_2>,
Chris@16 555 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >,
Chris@16 556 ::boost::mpl::placeholders::_1 >
Chris@16 557 >::type type;
Chris@16 558 };
Chris@16 559
Chris@16 560 template <class Transition>
Chris@16 561 struct make_vector
Chris@16 562 {
Chris@16 563 typedef ::boost::mpl::vector<Transition> type;
Chris@16 564 };
Chris@16 565 template< typename Entry >
Chris@16 566 struct get_first_element_pair_second
Chris@16 567 {
Chris@16 568 typedef typename ::boost::mpl::front<typename Entry::second>::type type;
Chris@16 569 };
Chris@16 570
Chris@16 571 //returns the owner of an explicit_entry state
Chris@16 572 //which is the containing SM if the transition originates from outside the containing SM
Chris@16 573 //or else the explicit_entry state itself
Chris@16 574 template <class State,class ContainingSM>
Chris@16 575 struct get_owner
Chris@16 576 {
Chris@16 577 typedef typename ::boost::mpl::if_<
Chris@16 578 typename ::boost::mpl::not_<typename ::boost::is_same<typename State::owner,
Chris@16 579 ContainingSM >::type>::type,
Chris@16 580 typename State::owner,
Chris@16 581 State >::type type;
Chris@16 582 };
Chris@16 583
Chris@16 584 template <class Sequence,class ContainingSM>
Chris@16 585 struct get_fork_owner
Chris@16 586 {
Chris@16 587 typedef typename ::boost::mpl::front<Sequence>::type seq_front;
Chris@16 588 typedef typename ::boost::mpl::if_<
Chris@16 589 typename ::boost::mpl::not_<
Chris@16 590 typename ::boost::is_same<typename seq_front::owner,ContainingSM>::type>::type,
Chris@16 591 typename seq_front::owner,
Chris@16 592 seq_front >::type type;
Chris@16 593 };
Chris@16 594
Chris@16 595 template <class StateType,class ContainingSM>
Chris@16 596 struct make_exit
Chris@16 597 {
Chris@16 598 typedef typename ::boost::mpl::if_<
Chris@16 599 typename is_pseudo_exit<StateType>::type ,
Chris@16 600 typename ContainingSM::template exit_pt<StateType>,
Chris@16 601 typename ::boost::mpl::identity<StateType>::type
Chris@16 602 >::type type;
Chris@16 603 };
Chris@16 604
Chris@16 605 template <class StateType,class ContainingSM>
Chris@16 606 struct make_entry
Chris@16 607 {
Chris@16 608 typedef typename ::boost::mpl::if_<
Chris@16 609 typename is_pseudo_entry<StateType>::type ,
Chris@16 610 typename ContainingSM::template entry_pt<StateType>,
Chris@16 611 typename ::boost::mpl::if_<
Chris@16 612 typename is_direct_entry<StateType>::type,
Chris@16 613 typename ContainingSM::template direct<StateType>,
Chris@16 614 typename ::boost::mpl::identity<StateType>::type
Chris@16 615 >::type
Chris@16 616 >::type type;
Chris@16 617 };
Chris@16 618 // metafunction used to say if a SM has pseudo exit states
Chris@16 619 template <class StateType>
Chris@16 620 struct has_exit_pseudo_states_helper
Chris@16 621 {
Chris@16 622 typedef typename StateType::stt Stt;
Chris@16 623 typedef typename generate_state_set<Stt>::type state_list;
Chris@16 624
Chris@16 625 typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
Chris@16 626 state_list,is_pseudo_exit< ::boost::mpl::placeholders::_1> >::value != 0> type;
Chris@16 627 };
Chris@16 628 template <class StateType>
Chris@16 629 struct has_exit_pseudo_states
Chris@16 630 {
Chris@16 631 typedef typename ::boost::mpl::eval_if<typename is_composite_state<StateType>::type,
Chris@16 632 has_exit_pseudo_states_helper<StateType>,
Chris@16 633 ::boost::mpl::bool_<false> >::type type;
Chris@16 634 };
Chris@16 635
Chris@16 636 // builds flags (add internal_flag_list and flag_list). internal_flag_list is used for terminate/interrupt states
Chris@16 637 template <class StateType>
Chris@16 638 struct get_flag_list
Chris@16 639 {
Chris@16 640 typedef typename ::boost::mpl::insert_range<
Chris@16 641 typename StateType::flag_list,
Chris@16 642 typename ::boost::mpl::end< typename StateType::flag_list >::type,
Chris@16 643 typename StateType::internal_flag_list
Chris@16 644 >::type type;
Chris@16 645 };
Chris@16 646
Chris@16 647 template <class StateType>
Chris@16 648 struct is_state_blocking
Chris@16 649 {
Chris@16 650 typedef typename ::boost::mpl::fold<
Chris@16 651 typename get_flag_list<StateType>::type, ::boost::mpl::set<>,
Chris@16 652 ::boost::mpl::if_<
Chris@16 653 has_event_blocking_flag< ::boost::mpl::placeholders::_2>,
Chris@16 654 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >,
Chris@16 655 ::boost::mpl::placeholders::_1 >
Chris@16 656 >::type blocking_flags;
Chris@16 657
Chris@16 658 typedef typename ::boost::mpl::if_<
Chris@16 659 ::boost::mpl::empty<blocking_flags>,
Chris@16 660 ::boost::mpl::bool_<false>,
Chris@16 661 ::boost::mpl::bool_<true> >::type type;
Chris@16 662 };
Chris@16 663 // returns a mpl::bool_<true> if fsm has an event blocking flag in one of its substates
Chris@16 664 template <class StateType>
Chris@16 665 struct has_fsm_blocking_states
Chris@16 666 {
Chris@16 667 typedef typename create_stt<StateType>::type Stt;
Chris@16 668 typedef typename generate_state_set<Stt>::type state_list;
Chris@16 669
Chris@16 670 typedef typename ::boost::mpl::fold<
Chris@16 671 state_list, ::boost::mpl::set<>,
Chris@16 672 ::boost::mpl::if_<
Chris@16 673 is_state_blocking< ::boost::mpl::placeholders::_2>,
Chris@16 674 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >,
Chris@16 675 ::boost::mpl::placeholders::_1 >
Chris@16 676 >::type blocking_states;
Chris@16 677
Chris@16 678 typedef typename ::boost::mpl::if_<
Chris@16 679 ::boost::mpl::empty<blocking_states>,
Chris@16 680 ::boost::mpl::bool_<false>,
Chris@16 681 ::boost::mpl::bool_<true> >::type type;
Chris@16 682 };
Chris@16 683
Chris@16 684 template <class StateType>
Chris@16 685 struct is_no_exception_thrown
Chris@16 686 {
Chris@16 687 typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
Chris@16 688 typename StateType::configuration,
Chris@16 689 has_no_exception_thrown< ::boost::mpl::placeholders::_1 > >::value != 0> found;
Chris@16 690
Chris@16 691 typedef typename ::boost::mpl::or_<
Chris@16 692 typename has_no_exception_thrown<StateType>::type,
Chris@16 693 found
Chris@16 694 >::type type;
Chris@16 695 };
Chris@16 696
Chris@16 697 template <class StateType>
Chris@16 698 struct is_no_message_queue
Chris@16 699 {
Chris@16 700 typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
Chris@16 701 typename StateType::configuration,
Chris@16 702 has_no_message_queue< ::boost::mpl::placeholders::_1 > >::value != 0> found;
Chris@16 703
Chris@16 704 typedef typename ::boost::mpl::or_<
Chris@16 705 typename has_no_message_queue<StateType>::type,
Chris@16 706 found
Chris@16 707 >::type type;
Chris@16 708 };
Chris@16 709
Chris@16 710 template <class StateType>
Chris@16 711 struct is_active_state_switch_policy
Chris@16 712 {
Chris@16 713 typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
Chris@16 714 typename StateType::configuration,
Chris@16 715 has_active_state_switch_policy< ::boost::mpl::placeholders::_1 > >::value != 0> found;
Chris@16 716
Chris@16 717 typedef typename ::boost::mpl::or_<
Chris@16 718 typename has_active_state_switch_policy<StateType>::type,
Chris@16 719 found
Chris@16 720 >::type type;
Chris@16 721 };
Chris@16 722
Chris@16 723 template <class StateType>
Chris@16 724 struct get_initial_event
Chris@16 725 {
Chris@16 726 typedef typename StateType::initial_event type;
Chris@16 727 };
Chris@16 728
Chris@16 729 template <class StateType>
Chris@16 730 struct get_final_event
Chris@16 731 {
Chris@16 732 typedef typename StateType::final_event type;
Chris@16 733 };
Chris@16 734
Chris@16 735 template <class TransitionTable, class InitState>
Chris@16 736 struct build_one_orthogonal_region
Chris@16 737 {
Chris@16 738 template<typename Row>
Chris@16 739 struct row_to_incidence :
Chris@16 740 ::boost::mpl::vector<
Chris@16 741 ::boost::mpl::pair<
Chris@16 742 typename Row::next_state_type,
Chris@16 743 typename Row::transition_event>,
Chris@16 744 typename Row::current_state_type,
Chris@16 745 typename Row::next_state_type
Chris@16 746 > {};
Chris@16 747
Chris@16 748 template <class Seq, class Elt>
Chris@16 749 struct transition_incidence_list_helper
Chris@16 750 {
Chris@16 751 typedef typename ::boost::mpl::push_back< Seq, row_to_incidence< Elt > >::type type;
Chris@16 752 };
Chris@16 753
Chris@16 754 typedef typename ::boost::mpl::fold<
Chris@16 755 TransitionTable,
Chris@16 756 ::boost::mpl::vector<>,
Chris@16 757 transition_incidence_list_helper< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
Chris@16 758 >::type transition_incidence_list;
Chris@16 759
Chris@16 760 typedef ::boost::msm::mpl_graph::incidence_list_graph<transition_incidence_list>
Chris@16 761 transition_graph;
Chris@16 762
Chris@16 763 struct preordering_dfs_visitor :
Chris@16 764 ::boost::msm::mpl_graph::dfs_default_visitor_operations
Chris@16 765 {
Chris@16 766 template<typename Node, typename Graph, typename State>
Chris@16 767 struct discover_vertex :
Chris@16 768 ::boost::mpl::insert<State, Node>
Chris@16 769 {};
Chris@16 770 };
Chris@16 771
Chris@16 772 typedef typename mpl::first<
Chris@16 773 typename ::boost::msm::mpl_graph::depth_first_search<
Chris@16 774 transition_graph,
Chris@16 775 preordering_dfs_visitor,
Chris@16 776 ::boost::mpl::set<>,
Chris@16 777 InitState
Chris@16 778 >::type
Chris@16 779 >::type type;
Chris@16 780 };
Chris@16 781
Chris@16 782 template <class Fsm>
Chris@16 783 struct find_entry_states
Chris@16 784 {
Chris@16 785 typedef typename ::boost::mpl::copy<
Chris@16 786 typename Fsm::substate_list,
Chris@16 787 ::boost::mpl::inserter<
Chris@16 788 ::boost::mpl::set0<>,
Chris@16 789 ::boost::mpl::if_<
Chris@16 790 has_explicit_entry_state< ::boost::mpl::placeholders::_2 >,
Chris@16 791 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>,
Chris@16 792 ::boost::mpl::placeholders::_1
Chris@16 793 >
Chris@16 794 >
Chris@16 795 >::type type;
Chris@16 796 };
Chris@16 797
Chris@16 798 template <class Set1, class Set2>
Chris@16 799 struct is_common_element
Chris@16 800 {
Chris@16 801 typedef typename ::boost::mpl::fold<
Chris@16 802 Set1, ::boost::mpl::false_,
Chris@16 803 ::boost::mpl::if_<
Chris@16 804 ::boost::mpl::has_key<
Chris@16 805 Set2,
Chris@16 806 ::boost::mpl::placeholders::_2
Chris@16 807 >,
Chris@16 808 ::boost::mpl::true_,
Chris@16 809 ::boost::mpl::placeholders::_1
Chris@16 810 >
Chris@16 811 >::type type;
Chris@16 812 };
Chris@16 813
Chris@16 814 template <class EntryRegion, class AllRegions>
Chris@16 815 struct add_entry_region
Chris@16 816 {
Chris@16 817 typedef typename ::boost::mpl::transform<
Chris@16 818 AllRegions,
Chris@16 819 ::boost::mpl::if_<
Chris@16 820 is_common_element<EntryRegion, ::boost::mpl::placeholders::_1>,
Chris@16 821 set_insert_range< ::boost::mpl::placeholders::_1, EntryRegion>,
Chris@16 822 ::boost::mpl::placeholders::_1
Chris@16 823 >
Chris@16 824 >::type type;
Chris@16 825 };
Chris@16 826
Chris@16 827 // build a vector of regions states (as a set)
Chris@16 828 // one set of states for every region
Chris@16 829 template <class Fsm, class InitStates>
Chris@16 830 struct build_orthogonal_regions
Chris@16 831 {
Chris@16 832 typedef typename
Chris@16 833 ::boost::mpl::fold<
Chris@16 834 InitStates, ::boost::mpl::vector0<>,
Chris@16 835 ::boost::mpl::push_back<
Chris@16 836 ::boost::mpl::placeholders::_1,
Chris@16 837 build_one_orthogonal_region< typename Fsm::stt, ::boost::mpl::placeholders::_2 > >
Chris@16 838 >::type without_entries;
Chris@16 839
Chris@16 840 typedef typename
Chris@16 841 ::boost::mpl::fold<
Chris@16 842 typename find_entry_states<Fsm>::type, ::boost::mpl::vector0<>,
Chris@16 843 ::boost::mpl::push_back<
Chris@16 844 ::boost::mpl::placeholders::_1,
Chris@16 845 build_one_orthogonal_region< typename Fsm::stt, ::boost::mpl::placeholders::_2 > >
Chris@16 846 >::type only_entries;
Chris@16 847
Chris@16 848 typedef typename ::boost::mpl::fold<
Chris@16 849 only_entries , without_entries,
Chris@16 850 add_entry_region< ::boost::mpl::placeholders::_2, ::boost::mpl::placeholders::_1>
Chris@16 851 >::type type;
Chris@16 852 };
Chris@16 853
Chris@16 854 template <class GraphAsSeqOfSets, class StateType>
Chris@16 855 struct find_region_index
Chris@16 856 {
Chris@16 857 typedef typename
Chris@16 858 ::boost::mpl::fold<
Chris@16 859 GraphAsSeqOfSets, ::boost::mpl::pair< ::boost::mpl::int_< -1 > /*res*/, ::boost::mpl::int_<0> /*counter*/ >,
Chris@16 860 ::boost::mpl::if_<
Chris@16 861 ::boost::mpl::has_key< ::boost::mpl::placeholders::_2, StateType >,
Chris@16 862 ::boost::mpl::pair<
Chris@16 863 ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
Chris@16 864 ::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
Chris@16 865 >,
Chris@16 866 ::boost::mpl::pair<
Chris@16 867 ::boost::mpl::first< ::boost::mpl::placeholders::_1 >,
Chris@16 868 ::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
Chris@16 869 >
Chris@16 870 >
Chris@16 871 >::type result_pair;
Chris@16 872 typedef typename ::boost::mpl::first<result_pair>::type type;
Chris@16 873 enum {value = type::value};
Chris@16 874 };
Chris@16 875
Chris@16 876 template <class Fsm>
Chris@16 877 struct check_regions_orthogonality
Chris@16 878 {
Chris@16 879 typedef typename build_orthogonal_regions< Fsm,typename Fsm::initial_states>::type regions;
Chris@16 880
Chris@16 881 typedef typename ::boost::mpl::fold<
Chris@16 882 regions, ::boost::mpl::int_<0>,
Chris@16 883 ::boost::mpl::plus< ::boost::mpl::placeholders::_1 , ::boost::mpl::size< ::boost::mpl::placeholders::_2> >
Chris@16 884 >::type number_of_states_in_regions;
Chris@16 885
Chris@16 886 typedef typename ::boost::mpl::fold<
Chris@16 887 regions,mpl::set0<>,
Chris@16 888 set_insert_range<
Chris@16 889 ::boost::mpl::placeholders::_1,
Chris@16 890 ::boost::mpl::placeholders::_2 >
Chris@16 891 >::type one_big_states_set;
Chris@16 892
Chris@16 893 enum {states_in_regions_raw = number_of_states_in_regions::value};
Chris@16 894 enum {cumulated_states_in_regions_raw = ::boost::mpl::size<one_big_states_set>::value};
Chris@16 895 };
Chris@16 896
Chris@16 897 template <class Fsm>
Chris@16 898 struct check_no_unreachable_state
Chris@16 899 {
Chris@16 900 typedef typename check_regions_orthogonality<Fsm>::one_big_states_set states_in_regions;
Chris@16 901
Chris@16 902 typedef typename set_insert_range<
Chris@16 903 states_in_regions,
Chris@16 904 typename ::boost::mpl::eval_if<
Chris@16 905 typename has_explicit_creation<Fsm>::type,
Chris@16 906 get_explicit_creation<Fsm>,
Chris@16 907 ::boost::mpl::vector0<>
Chris@16 908 >::type
Chris@16 909 >::type with_explicit_creation;
Chris@16 910
Chris@16 911 enum {states_in_fsm = ::boost::mpl::size< typename Fsm::substate_list >::value};
Chris@16 912 enum {cumulated_states_in_regions = ::boost::mpl::size< with_explicit_creation >::value};
Chris@16 913 };
Chris@16 914
Chris@16 915 // helper to find out if a SM has an active exit state and is therefore waiting for exiting
Chris@16 916 template <class StateType,class OwnerFct,class FSM>
Chris@16 917 inline
Chris@16 918 typename ::boost::enable_if<typename ::boost::mpl::and_<typename is_composite_state<FSM>::type,
Chris@16 919 typename is_pseudo_exit<StateType>::type>,bool >::type
Chris@16 920 is_exit_state_active(FSM& fsm)
Chris@16 921 {
Chris@16 922 typedef typename OwnerFct::type Composite;
Chris@16 923 //typedef typename create_stt<Composite>::type stt;
Chris@16 924 typedef typename Composite::stt stt;
Chris@16 925 int state_id = get_state_id<stt,StateType>::type::value;
Chris@16 926 Composite& comp = fsm.template get_state<Composite&>();
Chris@16 927 return (std::find(comp.current_state(),comp.current_state()+Composite::nr_regions::value,state_id)
Chris@16 928 !=comp.current_state()+Composite::nr_regions::value);
Chris@16 929 }
Chris@16 930 template <class StateType,class OwnerFct,class FSM>
Chris@16 931 inline
Chris@16 932 typename ::boost::disable_if<typename ::boost::mpl::and_<typename is_composite_state<FSM>::type,
Chris@16 933 typename is_pseudo_exit<StateType>::type>,bool >::type
Chris@16 934 is_exit_state_active(FSM&)
Chris@16 935 {
Chris@16 936 return false;
Chris@16 937 }
Chris@16 938
Chris@16 939 // transformation metafunction to end interrupt flags
Chris@16 940 template <class Event>
Chris@16 941 struct transform_to_end_interrupt
Chris@16 942 {
Chris@16 943 typedef boost::msm::EndInterruptFlag<Event> type;
Chris@16 944 };
Chris@16 945 // transform a sequence of events into another one of EndInterruptFlag<Event>
Chris@16 946 template <class Events>
Chris@16 947 struct apply_end_interrupt_flag
Chris@16 948 {
Chris@16 949 typedef typename
Chris@16 950 ::boost::mpl::transform<
Chris@16 951 Events,transform_to_end_interrupt< ::boost::mpl::placeholders::_1> >::type type;
Chris@16 952 };
Chris@16 953 // returns a mpl vector containing all end interrupt events if sequence, otherwise the same event
Chris@16 954 template <class Event>
Chris@16 955 struct get_interrupt_events
Chris@16 956 {
Chris@16 957 typedef typename ::boost::mpl::eval_if<
Chris@16 958 ::boost::mpl::is_sequence<Event>,
Chris@16 959 boost::msm::back::apply_end_interrupt_flag<Event>,
Chris@16 960 boost::mpl::vector1<boost::msm::EndInterruptFlag<Event> > >::type type;
Chris@16 961 };
Chris@16 962
Chris@16 963 template <class Events>
Chris@16 964 struct build_interrupt_state_flag_list
Chris@16 965 {
Chris@16 966 typedef ::boost::mpl::vector<boost::msm::InterruptedFlag> first_part;
Chris@16 967 typedef typename ::boost::mpl::insert_range<
Chris@16 968 first_part,
Chris@16 969 typename ::boost::mpl::end< first_part >::type,
Chris@16 970 Events
Chris@16 971 >::type type;
Chris@16 972 };
Chris@16 973
Chris@16 974 } } }//boost::msm::back
Chris@16 975
Chris@16 976 #endif // BOOST_MSM_BACK_METAFUNCTIONS_H
Chris@16 977