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