File indexing completed on 2025-09-17 08:38:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_MSM_BACK_METAFUNCTIONS_H
0012 #define BOOST_MSM_BACK_METAFUNCTIONS_H
0013
0014 #include <algorithm>
0015
0016 #include <boost/mpl/set.hpp>
0017 #include <boost/mpl/at.hpp>
0018 #include <boost/mpl/pair.hpp>
0019 #include <boost/mpl/map.hpp>
0020 #include <boost/mpl/int.hpp>
0021 #include <boost/mpl/has_xxx.hpp>
0022 #include <boost/mpl/find.hpp>
0023 #include <boost/mpl/count_if.hpp>
0024 #include <boost/mpl/fold.hpp>
0025 #include <boost/mpl/if.hpp>
0026 #include <boost/mpl/has_key.hpp>
0027 #include <boost/mpl/insert.hpp>
0028 #include <boost/mpl/next_prior.hpp>
0029 #include <boost/mpl/map.hpp>
0030 #include <boost/mpl/push_back.hpp>
0031 #include <boost/mpl/vector.hpp>
0032 #include <boost/mpl/is_sequence.hpp>
0033 #include <boost/mpl/size.hpp>
0034 #include <boost/mpl/transform.hpp>
0035 #include <boost/mpl/begin_end.hpp>
0036 #include <boost/mpl/bool.hpp>
0037 #include <boost/mpl/empty.hpp>
0038 #include <boost/mpl/identity.hpp>
0039 #include <boost/mpl/eval_if.hpp>
0040 #include <boost/mpl/insert_range.hpp>
0041 #include <boost/mpl/front.hpp>
0042 #include <boost/mpl/logical.hpp>
0043 #include <boost/mpl/plus.hpp>
0044 #include <boost/mpl/copy_if.hpp>
0045 #include <boost/mpl/back_inserter.hpp>
0046 #include <boost/mpl/transform.hpp>
0047
0048 #include <boost/fusion/include/as_vector.hpp>
0049 #include <boost/fusion/include/insert_range.hpp>
0050
0051 #include <boost/type_traits/is_same.hpp>
0052 #include <boost/utility/enable_if.hpp>
0053
0054 #include <boost/msm/row_tags.hpp>
0055
0056
0057 #include <boost/msm/mpl_graph/incidence_list_graph.hpp>
0058 #include <boost/msm/mpl_graph/depth_first_search.hpp>
0059
0060 BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_creation)
0061 BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_entry)
0062 BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_exit)
0063 BOOST_MPL_HAS_XXX_TRAIT_DEF(concrete_exit_state)
0064 BOOST_MPL_HAS_XXX_TRAIT_DEF(composite_tag)
0065 BOOST_MPL_HAS_XXX_TRAIT_DEF(not_real_row_tag)
0066 BOOST_MPL_HAS_XXX_TRAIT_DEF(event_blocking_flag)
0067 BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_entry_state)
0068 BOOST_MPL_HAS_XXX_TRAIT_DEF(completion_event)
0069 BOOST_MPL_HAS_XXX_TRAIT_DEF(no_exception_thrown)
0070 BOOST_MPL_HAS_XXX_TRAIT_DEF(no_message_queue)
0071 BOOST_MPL_HAS_XXX_TRAIT_DEF(activate_deferred_events)
0072 BOOST_MPL_HAS_XXX_TRAIT_DEF(wrapped_entry)
0073 BOOST_MPL_HAS_XXX_TRAIT_DEF(active_state_switch_policy)
0074
0075 namespace boost { namespace msm { namespace back
0076 {
0077 template <typename Sequence, typename Range>
0078 struct set_insert_range
0079 {
0080 typedef typename ::boost::mpl::fold<
0081 Range,Sequence,
0082 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >
0083 >::type type;
0084 };
0085
0086
0087 template <class Transition>
0088 struct transition_source_type
0089 {
0090 typedef typename Transition::current_state_type type;
0091 };
0092
0093
0094 template <class Transition>
0095 struct transition_target_type
0096 {
0097 typedef typename Transition::next_state_type type;
0098 };
0099
0100
0101
0102 template <class Id,class Transition>
0103 struct make_pair_source_state_id
0104 {
0105 typedef typename ::boost::mpl::pair<typename Transition::current_state_type,Id> type;
0106 };
0107 template <class Id,class Transition>
0108 struct make_pair_target_state_id
0109 {
0110 typedef typename ::boost::mpl::pair<typename Transition::next_state_type,Id> type;
0111 };
0112
0113
0114
0115
0116 template <class stt>
0117 struct generate_state_ids
0118 {
0119 typedef typename
0120 ::boost::mpl::fold<
0121 stt,::boost::mpl::pair< ::boost::mpl::map< >, ::boost::mpl::int_<0> >,
0122 ::boost::mpl::pair<
0123 ::boost::mpl::if_<
0124 ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
0125 transition_source_type< ::boost::mpl::placeholders::_2> >,
0126 ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
0127 ::boost::mpl::insert< ::boost::mpl::first<mpl::placeholders::_1>,
0128 make_pair_source_state_id< ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
0129 ::boost::mpl::placeholders::_2> >
0130 >,
0131 ::boost::mpl::if_<
0132 ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
0133 transition_source_type< ::boost::mpl::placeholders::_2> >,
0134 ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
0135 ::boost::mpl::next< ::boost::mpl::second<mpl::placeholders::_1 > >
0136 >
0137 >
0138 >::type source_state_ids;
0139 typedef typename ::boost::mpl::first<source_state_ids>::type source_state_map;
0140 typedef typename ::boost::mpl::second<source_state_ids>::type highest_state_id;
0141
0142
0143 typedef typename
0144 ::boost::mpl::fold<
0145 stt,::boost::mpl::pair<source_state_map,highest_state_id >,
0146 ::boost::mpl::pair<
0147 ::boost::mpl::if_<
0148 ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
0149 transition_target_type< ::boost::mpl::placeholders::_2> >,
0150 ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
0151 ::boost::mpl::insert< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
0152 make_pair_target_state_id< ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
0153 ::boost::mpl::placeholders::_2> >
0154 >,
0155 ::boost::mpl::if_<
0156 ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
0157 transition_target_type< ::boost::mpl::placeholders::_2> >,
0158 ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
0159 ::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
0160 >
0161 >
0162 >::type all_state_ids;
0163 typedef typename ::boost::mpl::first<all_state_ids>::type type;
0164 };
0165
0166 template <class Fsm>
0167 struct get_active_state_switch_policy_helper
0168 {
0169 typedef typename Fsm::active_state_switch_policy type;
0170 };
0171 template <class Iter>
0172 struct get_active_state_switch_policy_helper2
0173 {
0174 typedef typename boost::mpl::deref<Iter>::type Fsm;
0175 typedef typename Fsm::active_state_switch_policy type;
0176 };
0177
0178 template <class Fsm>
0179 struct get_active_state_switch_policy
0180 {
0181 typedef typename ::boost::mpl::find_if<
0182 typename Fsm::configuration,
0183 has_active_state_switch_policy< ::boost::mpl::placeholders::_1 > >::type iter;
0184
0185 typedef typename ::boost::mpl::eval_if<
0186 typename ::boost::is_same<
0187 iter,
0188 typename ::boost::mpl::end<typename Fsm::configuration>::type
0189 >::type,
0190 get_active_state_switch_policy_helper<Fsm>,
0191 get_active_state_switch_policy_helper2< iter >
0192 >::type type;
0193 };
0194
0195
0196 template <class stt,class State>
0197 struct get_state_id
0198 {
0199 typedef typename ::boost::mpl::at<typename generate_state_ids<stt>::type,State>::type type;
0200 enum {value = type::value};
0201 };
0202
0203
0204 template <class States>
0205 struct get_initial_states
0206 {
0207 typedef typename ::boost::mpl::if_<
0208 ::boost::mpl::is_sequence<States>,
0209 States,
0210 typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,States>::type >::type type;
0211 };
0212
0213 template <class region>
0214 struct get_number_of_regions
0215 {
0216 typedef typename mpl::if_<
0217 ::boost::mpl::is_sequence<region>,
0218 ::boost::mpl::size<region>,
0219 ::boost::mpl::int_<1> >::type type;
0220 };
0221
0222
0223
0224 template <class region>
0225 struct get_regions_as_sequence
0226 {
0227 typedef typename ::boost::mpl::if_<
0228 ::boost::mpl::is_sequence<region>,
0229 region,
0230 typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,region>::type >::type type;
0231 };
0232
0233 template <class ToCreateSeq>
0234 struct get_explicit_creation_as_sequence
0235 {
0236 typedef typename ::boost::mpl::if_<
0237 ::boost::mpl::is_sequence<ToCreateSeq>,
0238 ToCreateSeq,
0239 typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,ToCreateSeq>::type >::type type;
0240 };
0241
0242
0243 template <class stt,class Transition1,class Transition2>
0244 struct have_same_source
0245 {
0246 enum {current_state1 = get_state_id<stt,typename Transition1::current_state_type >::type::value};
0247 enum {current_state2 = get_state_id<stt,typename Transition2::current_state_type >::type::value};
0248 enum {value = ((int)current_state1 == (int)current_state2) };
0249 };
0250
0251
0252
0253 template <class Transition>
0254 struct transition_event
0255 {
0256 typedef typename Transition::transition_event type;
0257 };
0258
0259
0260 template <class State>
0261 struct is_composite_state
0262 {
0263 enum {value = has_composite_tag<State>::type::value};
0264 typedef typename has_composite_tag<State>::type type;
0265 };
0266
0267
0268 template <class stt>
0269 struct keep_source_names
0270 {
0271
0272 typedef typename
0273 ::boost::mpl::transform<
0274 stt,transition_source_type< ::boost::mpl::placeholders::_1> >::type type;
0275 };
0276
0277
0278 template <class stt>
0279 struct keep_target_names
0280 {
0281
0282 typedef typename
0283 ::boost::mpl::transform<
0284 stt,transition_target_type< ::boost::mpl::placeholders::_1> >::type type;
0285 };
0286
0287 template <class stt>
0288 struct generate_state_set
0289 {
0290
0291 typedef typename keep_source_names<stt>::type sources;
0292 typedef typename keep_target_names<stt>::type targets;
0293 typedef typename
0294 ::boost::mpl::fold<
0295 sources, ::boost::mpl::set<>,
0296 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
0297 >::type source_set;
0298 typedef typename
0299 ::boost::mpl::fold<
0300 targets,source_set,
0301 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
0302 >::type type;
0303 };
0304
0305
0306 template <class stt>
0307 struct generate_event_set
0308 {
0309 typedef typename
0310 ::boost::mpl::fold<
0311 stt, ::boost::mpl::set<>,
0312 ::boost::mpl::if_<
0313 ::boost::mpl::has_key< ::boost::mpl::placeholders::_1,
0314 transition_event< ::boost::mpl::placeholders::_2> >,
0315 ::boost::mpl::placeholders::_1,
0316 ::boost::mpl::insert< ::boost::mpl::placeholders::_1,
0317 transition_event< ::boost::mpl::placeholders::_2> > >
0318 >::type type;
0319 };
0320
0321
0322 template <class State, class Event>
0323 struct has_state_delayed_event
0324 {
0325 typedef typename ::boost::mpl::find<typename State::deferred_events,Event>::type found;
0326 typedef typename ::boost::mpl::if_<
0327 ::boost::is_same<found,typename ::boost::mpl::end<typename State::deferred_events>::type >,
0328 ::boost::mpl::bool_<false>,
0329 ::boost::mpl::bool_<true> >::type type;
0330 };
0331
0332 template <class State>
0333 struct has_state_delayed_events
0334 {
0335 typedef typename ::boost::mpl::if_<
0336 ::boost::mpl::empty<typename State::deferred_events>,
0337 ::boost::mpl::bool_<false>,
0338 ::boost::mpl::bool_<true> >::type type;
0339 };
0340
0341
0342 template< typename T1 >
0343 struct not_a_row
0344 {
0345 typedef int not_real_row_tag;
0346 struct dummy_event
0347 {
0348 };
0349 typedef T1 current_state_type;
0350 typedef T1 next_state_type;
0351 typedef dummy_event transition_event;
0352 };
0353
0354
0355 template <class State>
0356 struct is_pseudo_entry
0357 {
0358 typedef typename ::boost::mpl::if_< typename has_pseudo_entry<State>::type,
0359 ::boost::mpl::bool_<true>,::boost::mpl::bool_<false>
0360 >::type type;
0361 };
0362
0363 template <class State>
0364 struct is_pseudo_exit
0365 {
0366 typedef typename ::boost::mpl::if_< typename has_pseudo_exit<State>::type,
0367 ::boost::mpl::bool_<true>, ::boost::mpl::bool_<false>
0368 >::type type;
0369 };
0370
0371 template <class State>
0372 struct is_direct_entry
0373 {
0374 typedef typename ::boost::mpl::if_< typename has_explicit_entry_state<State>::type,
0375 ::boost::mpl::bool_<true>, ::boost::mpl::bool_<false>
0376 >::type type;
0377 };
0378
0379
0380 template <class StateType,class CompositeType>
0381 struct convert_fake_state
0382 {
0383
0384 typedef typename ::boost::mpl::if_<
0385 typename is_direct_entry<StateType>::type,
0386 typename CompositeType::template direct<StateType>,
0387 typename ::boost::mpl::identity<StateType>::type
0388 >::type type;
0389 };
0390
0391 template <class StateType>
0392 struct get_explicit_creation
0393 {
0394 typedef typename StateType::explicit_creation type;
0395 };
0396
0397 template <class StateType>
0398 struct get_wrapped_entry
0399 {
0400 typedef typename StateType::wrapped_entry type;
0401 };
0402
0403
0404
0405 template <class StateType>
0406 struct get_wrapped_state
0407 {
0408 typedef typename ::boost::mpl::eval_if<
0409 typename has_wrapped_entry<StateType>::type,
0410 get_wrapped_entry<StateType>,
0411 ::boost::mpl::identity<StateType> >::type type;
0412 };
0413
0414 template <class Derived>
0415 struct create_stt
0416 {
0417
0418 typedef typename Derived::real_transition_table Stt;
0419
0420 typedef typename generate_state_set<Stt>::type states;
0421
0422 typedef typename get_regions_as_sequence<typename Derived::initial_state>::type init_states;
0423
0424 typedef typename
0425 ::boost::mpl::fold<
0426 init_states,Stt,
0427 ::boost::mpl::if_<
0428 ::boost::mpl::has_key<states, ::boost::mpl::placeholders::_2>,
0429 ::boost::mpl::placeholders::_1,
0430 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end< ::boost::mpl::placeholders::_1>,
0431 not_a_row< get_wrapped_state< ::boost::mpl::placeholders::_2> > >
0432 >
0433 >::type with_init;
0434
0435 typedef typename get_explicit_creation_as_sequence<
0436 typename ::boost::mpl::eval_if<
0437 typename has_explicit_creation<Derived>::type,
0438 get_explicit_creation<Derived>,
0439 ::boost::mpl::vector0<> >::type
0440 >::type fake_explicit_created;
0441
0442 typedef typename
0443 ::boost::mpl::transform<
0444 fake_explicit_created,convert_fake_state< ::boost::mpl::placeholders::_1,Derived> >::type explicit_created;
0445
0446 typedef typename
0447 ::boost::mpl::fold<
0448 explicit_created,with_init,
0449 ::boost::mpl::if_<
0450 ::boost::mpl::has_key<states, ::boost::mpl::placeholders::_2>,
0451 ::boost::mpl::placeholders::_1,
0452 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end<mpl::placeholders::_1>,
0453 not_a_row< get_wrapped_state< ::boost::mpl::placeholders::_2> > >
0454 >
0455 >::type type;
0456 };
0457
0458
0459 template <class Composite>
0460 struct get_transition_table
0461 {
0462 typedef typename create_stt<Composite>::type type;
0463 };
0464
0465
0466
0467 template <class StateType,class IsComposite>
0468 struct recursive_get_internal_transition_table
0469 {
0470
0471 typedef typename StateType::internal_transition_table composite_table;
0472
0473 typedef typename generate_state_set<typename StateType::stt>::type composite_states;
0474 typedef typename ::boost::mpl::fold<
0475 composite_states, composite_table,
0476 ::boost::mpl::insert_range< ::boost::mpl::placeholders::_1, ::boost::mpl::end< ::boost::mpl::placeholders::_1>,
0477 recursive_get_internal_transition_table< ::boost::mpl::placeholders::_2, is_composite_state< ::boost::mpl::placeholders::_2> >
0478 >
0479 >::type type;
0480 };
0481
0482 template <class StateType>
0483 struct recursive_get_internal_transition_table<StateType, ::boost::mpl::false_ >
0484 {
0485 typedef typename StateType::internal_transition_table type;
0486 };
0487
0488
0489 template <class Composite>
0490 struct recursive_get_transition_table
0491 {
0492
0493 typedef typename ::boost::mpl::eval_if<typename is_composite_state<Composite>::type,
0494 get_transition_table<Composite>,
0495 ::boost::mpl::vector0<>
0496 >::type org_table;
0497
0498 typedef typename generate_state_set<org_table>::type states;
0499
0500
0501 typedef typename ::boost::mpl::fold<
0502 states,org_table,
0503 ::boost::mpl::insert_range< ::boost::mpl::placeholders::_1, ::boost::mpl::end<mpl::placeholders::_1>,
0504 recursive_get_transition_table< ::boost::mpl::placeholders::_2 > >
0505 >::type type;
0506
0507 };
0508
0509
0510 template <class Derived>
0511 struct has_fsm_deferred_events
0512 {
0513 typedef typename create_stt<Derived>::type Stt;
0514 typedef typename generate_state_set<Stt>::type state_list;
0515
0516 typedef typename ::boost::mpl::or_<
0517 typename has_activate_deferred_events<Derived>::type,
0518 ::boost::mpl::bool_< ::boost::mpl::count_if<
0519 typename Derived::configuration,
0520 has_activate_deferred_events< ::boost::mpl::placeholders::_1 > >::value != 0>
0521 >::type found_in_fsm;
0522
0523 typedef typename ::boost::mpl::or_<
0524 found_in_fsm,
0525 ::boost::mpl::bool_< ::boost::mpl::count_if<
0526 state_list,has_state_delayed_events<
0527 ::boost::mpl::placeholders::_1 > >::value != 0>
0528 >::type type;
0529 };
0530
0531
0532 template <class Event>
0533 struct is_completion_event
0534 {
0535 typedef typename ::boost::mpl::if_<
0536 has_completion_event<Event>,
0537 ::boost::mpl::bool_<true>,
0538 ::boost::mpl::bool_<false> >::type type;
0539 };
0540
0541 template <class Derived>
0542 struct has_fsm_eventless_transition
0543 {
0544 typedef typename create_stt<Derived>::type Stt;
0545 typedef typename generate_event_set<Stt>::type event_list;
0546
0547 typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
0548 event_list,is_completion_event< ::boost::mpl::placeholders::_1 > >::value != 0> type;
0549 };
0550 template <class Derived>
0551 struct find_completion_events
0552 {
0553 typedef typename create_stt<Derived>::type Stt;
0554 typedef typename generate_event_set<Stt>::type event_list;
0555
0556 typedef typename ::boost::mpl::fold<
0557 event_list, ::boost::mpl::set<>,
0558 ::boost::mpl::if_<
0559 is_completion_event< ::boost::mpl::placeholders::_2>,
0560 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >,
0561 ::boost::mpl::placeholders::_1 >
0562 >::type type;
0563 };
0564
0565 template <class Transition>
0566 struct make_vector
0567 {
0568 typedef ::boost::mpl::vector<Transition> type;
0569 };
0570 template< typename Entry >
0571 struct get_first_element_pair_second
0572 {
0573 typedef typename ::boost::mpl::front<typename Entry::second>::type type;
0574 };
0575
0576
0577
0578
0579 template <class State,class ContainingSM>
0580 struct get_owner
0581 {
0582 typedef typename ::boost::mpl::if_<
0583 typename ::boost::mpl::not_<typename ::boost::is_same<typename State::owner,
0584 ContainingSM >::type>::type,
0585 typename State::owner,
0586 State >::type type;
0587 };
0588
0589 template <class Sequence,class ContainingSM>
0590 struct get_fork_owner
0591 {
0592 typedef typename ::boost::mpl::front<Sequence>::type seq_front;
0593 typedef typename ::boost::mpl::if_<
0594 typename ::boost::mpl::not_<
0595 typename ::boost::is_same<typename seq_front::owner,ContainingSM>::type>::type,
0596 typename seq_front::owner,
0597 seq_front >::type type;
0598 };
0599
0600 template <class StateType,class ContainingSM>
0601 struct make_exit
0602 {
0603 typedef typename ::boost::mpl::if_<
0604 typename is_pseudo_exit<StateType>::type ,
0605 typename ContainingSM::template exit_pt<StateType>,
0606 typename ::boost::mpl::identity<StateType>::type
0607 >::type type;
0608 };
0609
0610 template <class StateType,class ContainingSM>
0611 struct make_entry
0612 {
0613 typedef typename ::boost::mpl::if_<
0614 typename is_pseudo_entry<StateType>::type ,
0615 typename ContainingSM::template entry_pt<StateType>,
0616 typename ::boost::mpl::if_<
0617 typename is_direct_entry<StateType>::type,
0618 typename ContainingSM::template direct<StateType>,
0619 typename ::boost::mpl::identity<StateType>::type
0620 >::type
0621 >::type type;
0622 };
0623
0624 template <class StateType>
0625 struct has_exit_pseudo_states_helper
0626 {
0627 typedef typename StateType::stt Stt;
0628 typedef typename generate_state_set<Stt>::type state_list;
0629
0630 typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
0631 state_list,is_pseudo_exit< ::boost::mpl::placeholders::_1> >::value != 0> type;
0632 };
0633 template <class StateType>
0634 struct has_exit_pseudo_states
0635 {
0636 typedef typename ::boost::mpl::eval_if<typename is_composite_state<StateType>::type,
0637 has_exit_pseudo_states_helper<StateType>,
0638 ::boost::mpl::bool_<false> >::type type;
0639 };
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651 template <class StateType>
0652 struct get_flag_list
0653 {
0654 typedef typename ::boost::fusion::result_of::as_vector<
0655 typename ::boost::fusion::result_of::insert_range<
0656 typename StateType::flag_list,
0657 typename ::boost::fusion::result_of::end< typename StateType::flag_list >::type,
0658 typename StateType::internal_flag_list
0659 >::type
0660 >::type type;
0661 };
0662
0663 template <class StateType>
0664 struct is_state_blocking
0665 {
0666 typedef typename ::boost::mpl::fold<
0667 typename get_flag_list<StateType>::type, ::boost::mpl::set<>,
0668 ::boost::mpl::if_<
0669 has_event_blocking_flag< ::boost::mpl::placeholders::_2>,
0670 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >,
0671 ::boost::mpl::placeholders::_1 >
0672 >::type blocking_flags;
0673
0674 typedef typename ::boost::mpl::if_<
0675 ::boost::mpl::empty<blocking_flags>,
0676 ::boost::mpl::bool_<false>,
0677 ::boost::mpl::bool_<true> >::type type;
0678 };
0679
0680 template <class StateType>
0681 struct has_fsm_blocking_states
0682 {
0683 typedef typename create_stt<StateType>::type Stt;
0684 typedef typename generate_state_set<Stt>::type state_list;
0685
0686 typedef typename ::boost::mpl::fold<
0687 state_list, ::boost::mpl::set<>,
0688 ::boost::mpl::if_<
0689 is_state_blocking< ::boost::mpl::placeholders::_2>,
0690 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >,
0691 ::boost::mpl::placeholders::_1 >
0692 >::type blocking_states;
0693
0694 typedef typename ::boost::mpl::if_<
0695 ::boost::mpl::empty<blocking_states>,
0696 ::boost::mpl::bool_<false>,
0697 ::boost::mpl::bool_<true> >::type type;
0698 };
0699
0700 template <class StateType>
0701 struct is_no_exception_thrown
0702 {
0703 typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
0704 typename StateType::configuration,
0705 has_no_exception_thrown< ::boost::mpl::placeholders::_1 > >::value != 0> found;
0706
0707 typedef typename ::boost::mpl::or_<
0708 typename has_no_exception_thrown<StateType>::type,
0709 found
0710 >::type type;
0711 };
0712
0713 template <class StateType>
0714 struct is_no_message_queue
0715 {
0716 typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
0717 typename StateType::configuration,
0718 has_no_message_queue< ::boost::mpl::placeholders::_1 > >::value != 0> found;
0719
0720 typedef typename ::boost::mpl::or_<
0721 typename has_no_message_queue<StateType>::type,
0722 found
0723 >::type type;
0724 };
0725
0726 template <class StateType>
0727 struct is_active_state_switch_policy
0728 {
0729 typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
0730 typename StateType::configuration,
0731 has_active_state_switch_policy< ::boost::mpl::placeholders::_1 > >::value != 0> found;
0732
0733 typedef typename ::boost::mpl::or_<
0734 typename has_active_state_switch_policy<StateType>::type,
0735 found
0736 >::type type;
0737 };
0738
0739 template <class StateType>
0740 struct get_initial_event
0741 {
0742 typedef typename StateType::initial_event type;
0743 };
0744
0745 template <class StateType>
0746 struct get_final_event
0747 {
0748 typedef typename StateType::final_event type;
0749 };
0750
0751 template <class TransitionTable, class InitState>
0752 struct build_one_orthogonal_region
0753 {
0754 template<typename Row>
0755 struct row_to_incidence :
0756 ::boost::mpl::vector<
0757 ::boost::mpl::pair<
0758 typename Row::next_state_type,
0759 typename Row::transition_event>,
0760 typename Row::current_state_type,
0761 typename Row::next_state_type
0762 > {};
0763
0764 template <class Seq, class Elt>
0765 struct transition_incidence_list_helper
0766 {
0767 typedef typename ::boost::mpl::push_back< Seq, row_to_incidence< Elt > >::type type;
0768 };
0769
0770 typedef typename ::boost::mpl::fold<
0771 TransitionTable,
0772 ::boost::mpl::vector<>,
0773 transition_incidence_list_helper< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
0774 >::type transition_incidence_list;
0775
0776 typedef ::boost::msm::mpl_graph::incidence_list_graph<transition_incidence_list>
0777 transition_graph;
0778
0779 struct preordering_dfs_visitor :
0780 ::boost::msm::mpl_graph::dfs_default_visitor_operations
0781 {
0782 template<typename Node, typename Graph, typename State>
0783 struct discover_vertex :
0784 ::boost::mpl::insert<State, Node>
0785 {};
0786 };
0787
0788 typedef typename mpl::first<
0789 typename ::boost::msm::mpl_graph::depth_first_search<
0790 transition_graph,
0791 preordering_dfs_visitor,
0792 ::boost::mpl::set<>,
0793 InitState
0794 >::type
0795 >::type type;
0796 };
0797
0798 template <class Fsm>
0799 struct find_entry_states
0800 {
0801 typedef typename ::boost::mpl::copy<
0802 typename Fsm::substate_list,
0803 ::boost::mpl::inserter<
0804 ::boost::mpl::set0<>,
0805 ::boost::mpl::if_<
0806 has_explicit_entry_state< ::boost::mpl::placeholders::_2 >,
0807 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>,
0808 ::boost::mpl::placeholders::_1
0809 >
0810 >
0811 >::type type;
0812 };
0813
0814 template <class Set1, class Set2>
0815 struct is_common_element
0816 {
0817 typedef typename ::boost::mpl::fold<
0818 Set1, ::boost::mpl::false_,
0819 ::boost::mpl::if_<
0820 ::boost::mpl::has_key<
0821 Set2,
0822 ::boost::mpl::placeholders::_2
0823 >,
0824 ::boost::mpl::true_,
0825 ::boost::mpl::placeholders::_1
0826 >
0827 >::type type;
0828 };
0829
0830 template <class EntryRegion, class AllRegions>
0831 struct add_entry_region
0832 {
0833 typedef typename ::boost::mpl::transform<
0834 AllRegions,
0835 ::boost::mpl::if_<
0836 is_common_element<EntryRegion, ::boost::mpl::placeholders::_1>,
0837 set_insert_range< ::boost::mpl::placeholders::_1, EntryRegion>,
0838 ::boost::mpl::placeholders::_1
0839 >
0840 >::type type;
0841 };
0842
0843
0844
0845 template <class Fsm, class InitStates>
0846 struct build_orthogonal_regions
0847 {
0848 typedef typename
0849 ::boost::mpl::fold<
0850 InitStates, ::boost::mpl::vector0<>,
0851 ::boost::mpl::push_back<
0852 ::boost::mpl::placeholders::_1,
0853 build_one_orthogonal_region< typename Fsm::stt, ::boost::mpl::placeholders::_2 > >
0854 >::type without_entries;
0855
0856 typedef typename
0857 ::boost::mpl::fold<
0858 typename find_entry_states<Fsm>::type, ::boost::mpl::vector0<>,
0859 ::boost::mpl::push_back<
0860 ::boost::mpl::placeholders::_1,
0861 build_one_orthogonal_region< typename Fsm::stt, ::boost::mpl::placeholders::_2 > >
0862 >::type only_entries;
0863
0864 typedef typename ::boost::mpl::fold<
0865 only_entries , without_entries,
0866 add_entry_region< ::boost::mpl::placeholders::_2, ::boost::mpl::placeholders::_1>
0867 >::type type;
0868 };
0869
0870 template <class GraphAsSeqOfSets, class StateType>
0871 struct find_region_index
0872 {
0873 typedef typename
0874 ::boost::mpl::fold<
0875 GraphAsSeqOfSets, ::boost::mpl::pair< ::boost::mpl::int_< -1 > , ::boost::mpl::int_<0> >,
0876 ::boost::mpl::if_<
0877 ::boost::mpl::has_key< ::boost::mpl::placeholders::_2, StateType >,
0878 ::boost::mpl::pair<
0879 ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
0880 ::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
0881 >,
0882 ::boost::mpl::pair<
0883 ::boost::mpl::first< ::boost::mpl::placeholders::_1 >,
0884 ::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
0885 >
0886 >
0887 >::type result_pair;
0888 typedef typename ::boost::mpl::first<result_pair>::type type;
0889 enum {value = type::value};
0890 };
0891
0892 template <class Fsm>
0893 struct check_regions_orthogonality
0894 {
0895 typedef typename build_orthogonal_regions< Fsm,typename Fsm::initial_states>::type regions;
0896
0897 typedef typename ::boost::mpl::fold<
0898 regions, ::boost::mpl::int_<0>,
0899 ::boost::mpl::plus< ::boost::mpl::placeholders::_1 , ::boost::mpl::size< ::boost::mpl::placeholders::_2> >
0900 >::type number_of_states_in_regions;
0901
0902 typedef typename ::boost::mpl::fold<
0903 regions,mpl::set0<>,
0904 set_insert_range<
0905 ::boost::mpl::placeholders::_1,
0906 ::boost::mpl::placeholders::_2 >
0907 >::type one_big_states_set;
0908
0909 enum {states_in_regions_raw = number_of_states_in_regions::value};
0910 enum {cumulated_states_in_regions_raw = ::boost::mpl::size<one_big_states_set>::value};
0911 };
0912
0913 template <class Fsm>
0914 struct check_no_unreachable_state
0915 {
0916 typedef typename check_regions_orthogonality<Fsm>::one_big_states_set states_in_regions;
0917
0918 typedef typename set_insert_range<
0919 states_in_regions,
0920 typename ::boost::mpl::eval_if<
0921 typename has_explicit_creation<Fsm>::type,
0922 get_explicit_creation<Fsm>,
0923 ::boost::mpl::vector0<>
0924 >::type
0925 >::type with_explicit_creation;
0926
0927 enum {states_in_fsm = ::boost::mpl::size< typename Fsm::substate_list >::value};
0928 enum {cumulated_states_in_regions = ::boost::mpl::size< with_explicit_creation >::value};
0929 };
0930
0931
0932 template <class StateType,class OwnerFct,class FSM>
0933 inline
0934 typename ::boost::enable_if<typename ::boost::mpl::and_<typename is_composite_state<FSM>::type,
0935 typename is_pseudo_exit<StateType>::type>,bool >::type
0936 is_exit_state_active(FSM& fsm)
0937 {
0938 typedef typename OwnerFct::type Composite;
0939
0940 typedef typename Composite::stt stt;
0941 int state_id = get_state_id<stt,StateType>::type::value;
0942 Composite& comp = fsm.template get_state<Composite&>();
0943 return (std::find(comp.current_state(),comp.current_state()+Composite::nr_regions::value,state_id)
0944 !=comp.current_state()+Composite::nr_regions::value);
0945 }
0946 template <class StateType,class OwnerFct,class FSM>
0947 inline
0948 typename ::boost::disable_if<typename ::boost::mpl::and_<typename is_composite_state<FSM>::type,
0949 typename is_pseudo_exit<StateType>::type>,bool >::type
0950 is_exit_state_active(FSM&)
0951 {
0952 return false;
0953 }
0954
0955
0956 template <class Event>
0957 struct transform_to_end_interrupt
0958 {
0959 typedef boost::msm::EndInterruptFlag<Event> type;
0960 };
0961
0962 template <class Events>
0963 struct apply_end_interrupt_flag
0964 {
0965 typedef typename
0966 ::boost::mpl::transform<
0967 Events,transform_to_end_interrupt< ::boost::mpl::placeholders::_1> >::type type;
0968 };
0969
0970 template <class Event>
0971 struct get_interrupt_events
0972 {
0973 typedef typename ::boost::mpl::eval_if<
0974 ::boost::mpl::is_sequence<Event>,
0975 boost::msm::back::apply_end_interrupt_flag<Event>,
0976 boost::mpl::vector1<boost::msm::EndInterruptFlag<Event> > >::type type;
0977 };
0978
0979 template <class Events>
0980 struct build_interrupt_state_flag_list
0981 {
0982 typedef ::boost::mpl::vector<boost::msm::InterruptedFlag> first_part;
0983 typedef typename ::boost::mpl::insert_range<
0984 first_part,
0985 typename ::boost::mpl::end< first_part >::type,
0986 Events
0987 >::type type;
0988 };
0989
0990 } } }
0991
0992 #endif
0993