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