Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 08:21:36

0001 // Copyright 2008 Christophe Henry
0002 // henry UNDERSCORE christophe AT hotmail DOT com
0003 // This is an extended version of the state machine available in the boost::mpl library
0004 // Distributed under the same license as the original.
0005 // Copyright for the original version:
0006 // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
0007 // under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at
0009 // http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 #ifndef BOOST_MSM_BACK_STATEMACHINE_H
0012 #define BOOST_MSM_BACK_STATEMACHINE_H
0013 
0014 #include <exception>
0015 #include <vector>
0016 #include <functional>
0017 #include <numeric>
0018 #include <utility>
0019 #include <algorithm>
0020 
0021 #include <boost/core/no_exceptions_support.hpp>
0022 
0023 #include <boost/core/ignore_unused.hpp>
0024 #include <boost/mpl/contains.hpp>
0025 #include <boost/mpl/deref.hpp>
0026 #include <boost/mpl/assert.hpp>
0027 
0028 #include <boost/fusion/container/vector/convert.hpp>
0029 #include <boost/fusion/include/as_vector.hpp>
0030 #include <boost/fusion/include/as_set.hpp>
0031 #include <boost/fusion/container/set.hpp>
0032 #include <boost/fusion/include/set.hpp>
0033 #include <boost/fusion/include/set_fwd.hpp>
0034 #include <boost/fusion/include/mpl.hpp>
0035 #include <boost/fusion/sequence/intrinsic/at_key.hpp>
0036 #include <boost/fusion/include/at_key.hpp>
0037 #include <boost/fusion/algorithm/iteration/for_each.hpp>
0038 #include <boost/fusion/include/for_each.hpp>
0039 
0040 #include <boost/assert.hpp>
0041 #include <boost/ref.hpp>
0042 #include <boost/type_traits.hpp>
0043 #include <boost/utility/enable_if.hpp>
0044 #include <boost/type_traits/is_convertible.hpp>
0045 
0046 #include <boost/bind/bind.hpp>
0047 #include <boost/function.hpp>
0048 #ifndef BOOST_NO_RTTI
0049 #include <boost/any.hpp>
0050 #endif
0051 
0052 #include <boost/serialization/base_object.hpp>
0053 
0054 #include <boost/parameter.hpp>
0055 
0056 #include <boost/msm/active_state_switching_policies.hpp>
0057 #include <boost/msm/row_tags.hpp>
0058 #include <boost/msm/msm_grammar.hpp>
0059 #include <boost/msm/back/fold_to_list.hpp>
0060 #include <boost/msm/back/metafunctions.hpp>
0061 #include <boost/msm/back/history_policies.hpp>
0062 #include <boost/msm/back/common_types.hpp>
0063 #include <boost/msm/back/args.hpp>
0064 #include <boost/msm/back/default_compile_policy.hpp>
0065 #include <boost/msm/back/dispatch_table.hpp>
0066 #include <boost/msm/back/no_fsm_check.hpp>
0067 #include <boost/msm/back/queue_container_deque.hpp>
0068 
0069 BOOST_MPL_HAS_XXX_TRAIT_DEF(accept_sig)
0070 BOOST_MPL_HAS_XXX_TRAIT_DEF(no_automatic_create)
0071 BOOST_MPL_HAS_XXX_TRAIT_DEF(non_forwarding_flag)
0072 BOOST_MPL_HAS_XXX_TRAIT_DEF(direct_entry)
0073 BOOST_MPL_HAS_XXX_TRAIT_DEF(initial_event)
0074 BOOST_MPL_HAS_XXX_TRAIT_DEF(final_event)
0075 BOOST_MPL_HAS_XXX_TRAIT_DEF(do_serialize)
0076 BOOST_MPL_HAS_XXX_TRAIT_DEF(history_policy)
0077 BOOST_MPL_HAS_XXX_TRAIT_DEF(fsm_check)
0078 BOOST_MPL_HAS_XXX_TRAIT_DEF(compile_policy)
0079 BOOST_MPL_HAS_XXX_TRAIT_DEF(queue_container_policy)
0080 BOOST_MPL_HAS_XXX_TRAIT_DEF(using_declared_table)
0081 BOOST_MPL_HAS_XXX_TRAIT_DEF(event_queue_before_deferred_queue)
0082 
0083 #ifndef BOOST_MSM_CONSTRUCTOR_ARG_SIZE
0084 #define BOOST_MSM_CONSTRUCTOR_ARG_SIZE 5 // default max number of arguments for constructors
0085 #endif
0086 
0087 namespace boost { namespace msm { namespace back
0088 {
0089 // event used internally for wrapping a direct entry
0090 template <class StateType,class Event>
0091 struct direct_entry_event
0092 {
0093     typedef int direct_entry;
0094     typedef StateType active_state;
0095     typedef Event contained_event;
0096 
0097     direct_entry_event(Event const& evt):m_event(evt){}
0098     Event const& m_event;
0099 };
0100 
0101 BOOST_PARAMETER_TEMPLATE_KEYWORD(front_end)
0102 BOOST_PARAMETER_TEMPLATE_KEYWORD(history_policy)
0103 BOOST_PARAMETER_TEMPLATE_KEYWORD(compile_policy)
0104 BOOST_PARAMETER_TEMPLATE_KEYWORD(fsm_check_policy)
0105 BOOST_PARAMETER_TEMPLATE_KEYWORD(queue_container_policy)
0106 
0107 typedef ::boost::parameter::parameters<
0108     ::boost::parameter::required< ::boost::msm::back::tag::front_end >
0109   , ::boost::parameter::optional<
0110         ::boost::parameter::deduced< ::boost::msm::back::tag::history_policy>, has_history_policy< ::boost::mpl::_ >
0111     >
0112   , ::boost::parameter::optional<
0113         ::boost::parameter::deduced< ::boost::msm::back::tag::compile_policy>, has_compile_policy< ::boost::mpl::_ >
0114     >
0115   , ::boost::parameter::optional<
0116         ::boost::parameter::deduced< ::boost::msm::back::tag::fsm_check_policy>, has_fsm_check< ::boost::mpl::_ >
0117     >
0118   , ::boost::parameter::optional<
0119         ::boost::parameter::deduced< ::boost::msm::back::tag::queue_container_policy>,
0120         has_queue_container_policy< ::boost::mpl::_ >
0121     >
0122 > state_machine_signature;
0123 
0124 // just here to disable use of proto when not needed
0125 template <class T, class F,class Enable=void>
0126 struct make_euml_terminal;
0127 template <class T,class F>
0128 struct make_euml_terminal<T,F,typename ::boost::disable_if<has_using_declared_table<F> >::type>
0129 {};
0130 template <class T,class F>
0131 struct make_euml_terminal<T,F,typename ::boost::enable_if<has_using_declared_table<F> >::type>
0132     : public proto::extends<typename proto::terminal< boost::msm::state_tag>::type, T, boost::msm::state_domain>
0133 {};
0134 
0135 // library-containing class for state machines.  Pass the actual FSM class as
0136 // the Concrete parameter.
0137 // A0=Derived,A1=NoHistory,A2=CompilePolicy,A3=FsmCheckPolicy >
0138 template <
0139       class A0
0140     , class A1 = parameter::void_
0141     , class A2 = parameter::void_
0142     , class A3 = parameter::void_
0143     , class A4 = parameter::void_
0144 >
0145 class state_machine : //public Derived
0146     public ::boost::parameter::binding<
0147             typename state_machine_signature::bind<A0,A1,A2,A3,A4>::type, ::boost::msm::back::tag::front_end
0148     >::type
0149     , public make_euml_terminal<state_machine<A0,A1,A2,A3,A4>,
0150                          typename ::boost::parameter::binding<
0151                                     typename state_machine_signature::bind<A0,A1,A2,A3,A4>::type, ::boost::msm::back::tag::front_end
0152                          >::type
0153       >
0154 {
0155 public:
0156     // Create ArgumentPack
0157     typedef typename
0158         state_machine_signature::bind<A0,A1,A2,A3,A4>::type
0159         state_machine_args;
0160 
0161     // Extract first logical parameter.
0162     typedef typename ::boost::parameter::binding<
0163         state_machine_args, ::boost::msm::back::tag::front_end>::type Derived;
0164 
0165     typedef typename ::boost::parameter::binding<
0166         state_machine_args, ::boost::msm::back::tag::history_policy, NoHistory >::type              HistoryPolicy;
0167 
0168     typedef typename ::boost::parameter::binding<
0169         state_machine_args, ::boost::msm::back::tag::compile_policy, favor_runtime_speed >::type    CompilePolicy;
0170 
0171     typedef typename ::boost::parameter::binding<
0172         state_machine_args, ::boost::msm::back::tag::fsm_check_policy, no_fsm_check >::type         FsmCheckPolicy;
0173 
0174     typedef typename ::boost::parameter::binding<
0175         state_machine_args, ::boost::msm::back::tag::queue_container_policy,
0176         queue_container_deque >::type                                                               QueueContainerPolicy;
0177 
0178 private:
0179 
0180     typedef boost::msm::back::state_machine<
0181         A0,A1,A2,A3,A4>                             library_sm;
0182 
0183     typedef ::boost::function<
0184         execute_return ()>                          transition_fct;
0185     typedef ::boost::function<
0186         execute_return () >                         deferred_fct;
0187     typedef typename QueueContainerPolicy::
0188         template In<
0189             std::pair<deferred_fct,char> >::type    deferred_events_queue_t;
0190     typedef typename QueueContainerPolicy::
0191         template In<transition_fct>::type           events_queue_t;
0192 
0193     typedef typename boost::mpl::eval_if<
0194         typename is_active_state_switch_policy<Derived>::type,
0195         get_active_state_switch_policy<Derived>,
0196         // default
0197         ::boost::mpl::identity<active_state_switch_after_entry>
0198     >::type active_state_switching;
0199 
0200     typedef bool (*flag_handler)(library_sm const&);
0201 
0202     // all state machines are friend with each other to allow embedding any of them in another fsm
0203     template <class ,class , class, class, class
0204     > friend class boost::msm::back::state_machine;
0205 
0206     // helper to add, if needed, visitors to all states
0207     // version without visitors
0208     template <class StateType,class Enable=void>
0209     struct visitor_fct_helper
0210     {
0211     public:
0212         visitor_fct_helper(){}
0213         void fill_visitors(int)
0214         {
0215         }
0216         template <class FCT>
0217         void insert(int,FCT)
0218         {
0219         }
0220         template <class VISITOR>
0221         void execute(int,VISITOR)
0222         {
0223         }
0224     };
0225     // version with visitors
0226     template <class StateType>
0227     struct visitor_fct_helper<StateType,typename ::boost::enable_if<has_accept_sig<StateType> >::type>
0228     {
0229     public:
0230         visitor_fct_helper():m_state_visitors(){}
0231         void fill_visitors(int number_of_states)
0232         {
0233             m_state_visitors.resize(number_of_states);
0234         }
0235         template <class FCT>
0236         void insert(int index,FCT fct)
0237         {
0238             m_state_visitors[index]=fct;
0239         }
0240         void execute(int index)
0241         {
0242             m_state_visitors[index]();
0243         }
0244 
0245 #define MSM_VISITOR_HELPER_EXECUTE_SUB(z, n, unused) ARG ## n vis ## n
0246 #define MSM_VISITOR_HELPER_EXECUTE(z, n, unused)                                    \
0247         template <BOOST_PP_ENUM_PARAMS(n, class ARG)>                               \
0248         void execute(int index BOOST_PP_COMMA_IF(n)                                 \
0249                      BOOST_PP_ENUM(n, MSM_VISITOR_HELPER_EXECUTE_SUB, ~ ) )         \
0250         {                                                                           \
0251             m_state_visitors[index](BOOST_PP_ENUM_PARAMS(n,vis));                   \
0252         }
0253         BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_HELPER_EXECUTE, ~)
0254 #undef MSM_VISITOR_HELPER_EXECUTE
0255 #undef MSM_VISITOR_HELPER_EXECUTE_SUB
0256     private:
0257         typedef typename StateType::accept_sig::type                  visitor_fct;
0258         typedef std::vector<visitor_fct>                              visitors;
0259 
0260         visitors                                                      m_state_visitors;
0261     };
0262 
0263     template <class StateType,class Enable=int>
0264     struct deferred_msg_queue_helper
0265     {
0266         void clear(){}
0267     };
0268     template <class StateType>
0269     struct deferred_msg_queue_helper<StateType,
0270         typename ::boost::enable_if<
0271             typename ::boost::msm::back::has_fsm_deferred_events<StateType>::type,int >::type>
0272     {
0273     public:
0274         deferred_msg_queue_helper():m_deferred_events_queue(),m_cur_seq(0){}
0275         void clear()
0276         {
0277             m_deferred_events_queue.clear();
0278         }
0279         deferred_events_queue_t         m_deferred_events_queue;
0280         char m_cur_seq;
0281     };
0282 
0283  public:
0284     // tags
0285     typedef int composite_tag;
0286 
0287     // in case someone needs to know
0288     typedef HistoryPolicy               history_policy;
0289 
0290     struct InitEvent { };
0291     struct ExitEvent { };
0292     // flag handling
0293     struct Flag_AND
0294     {
0295         typedef std::logical_and<bool> type;
0296     };
0297     struct Flag_OR
0298     {
0299      typedef std::logical_or<bool> type;
0300     };
0301     typedef typename Derived::BaseAllStates     BaseState;
0302     typedef Derived                             ConcreteSM;
0303 
0304     // if the front-end fsm provides an initial_event typedef, replace InitEvent by this one
0305     typedef typename ::boost::mpl::eval_if<
0306         typename has_initial_event<Derived>::type,
0307         get_initial_event<Derived>,
0308         ::boost::mpl::identity<InitEvent>
0309     >::type fsm_initial_event;
0310 
0311     // if the front-end fsm provides an exit_event typedef, replace ExitEvent by this one
0312     typedef typename ::boost::mpl::eval_if<
0313         typename has_final_event<Derived>::type,
0314         get_final_event<Derived>,
0315         ::boost::mpl::identity<ExitEvent>
0316     >::type fsm_final_event;
0317 
0318     template <class ExitPoint>
0319     struct exit_pt : public ExitPoint
0320     {
0321         // tags
0322         typedef ExitPoint           wrapped_exit;
0323         typedef int                 pseudo_exit;
0324         typedef library_sm          owner;
0325         typedef int                 no_automatic_create;
0326         typedef typename
0327             ExitPoint::event        Event;
0328         typedef ::boost::function<execute_return (Event const&)>
0329                                     forwarding_function;
0330 
0331         // forward event to the higher-level FSM
0332         template <class ForwardEvent>
0333         void forward_event(ForwardEvent const& incomingEvent)
0334         {
0335             // use helper to forward or not
0336             ForwardHelper< ::boost::is_convertible<ForwardEvent,Event>::value>::helper(incomingEvent,m_forward);
0337         }
0338         void set_forward_fct(::boost::function<execute_return (Event const&)> fct)
0339         {
0340             m_forward = fct;
0341         }
0342         exit_pt():m_forward(){}
0343         // by assignments, we keep our forwarding functor unchanged as our containing SM did not change
0344     template <class RHS>
0345         exit_pt(RHS&):m_forward(){}
0346         exit_pt<ExitPoint>& operator= (const exit_pt<ExitPoint>& )
0347         {
0348             return *this;
0349         }
0350     private:
0351          forwarding_function          m_forward;
0352 
0353          // using partial specialization instead of enable_if because of VC8 bug
0354         template <bool OwnEvent, int Dummy=0>
0355         struct ForwardHelper
0356         {
0357             template <class ForwardEvent>
0358             static void helper(ForwardEvent const& ,forwarding_function& )
0359             {
0360                 // Not our event, assert
0361                 BOOST_ASSERT(false);
0362             }
0363         };
0364         template <int Dummy>
0365         struct ForwardHelper<true,Dummy>
0366         {
0367             template <class ForwardEvent>
0368             static void helper(ForwardEvent const& incomingEvent,forwarding_function& forward_fct)
0369             {
0370                 // call if handler set, if not, this state is simply a terminate state
0371                 if (forward_fct)
0372                     forward_fct(incomingEvent);
0373             }
0374         };
0375 
0376     };
0377     template <class EntryPoint>
0378     struct entry_pt : public EntryPoint
0379     {
0380         // tags
0381         typedef EntryPoint          wrapped_entry;
0382         typedef int                 pseudo_entry;
0383         typedef library_sm          owner;
0384         typedef int                 no_automatic_create;
0385     };
0386     template <class EntryPoint>
0387     struct direct : public EntryPoint
0388     {
0389         // tags
0390         typedef EntryPoint          wrapped_entry;
0391         typedef int                 explicit_entry_state;
0392         typedef library_sm          owner;
0393         typedef int                 no_automatic_create;
0394     };
0395     typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
0396     // Template used to form rows in the transition table
0397     template<
0398         typename ROW
0399     >
0400     struct row_
0401     {
0402         //typedef typename ROW::Source T1;
0403         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0404         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0405         typedef typename ROW::Evt transition_event;
0406         // if the source is an exit pseudo state, then
0407         // current_state_type becomes the result of get_owner
0408         // meaning the containing SM from which the exit occurs
0409         typedef typename ::boost::mpl::eval_if<
0410                 typename has_pseudo_exit<T1>::type,
0411                 get_owner<T1,library_sm>,
0412                 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
0413 
0414         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
0415         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
0416         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
0417         typedef typename ::boost::mpl::eval_if<
0418             typename ::boost::mpl::is_sequence<T2>::type,
0419             get_fork_owner<T2,library_sm>,
0420             ::boost::mpl::eval_if<
0421                     typename has_no_automatic_create<T2>::type,
0422                     get_owner<T2,library_sm>,
0423                     ::boost::mpl::identity<T2> >
0424         >::type next_state_type;
0425 
0426         // if a guard condition is here, call it to check that the event is accepted
0427         static bool check_guard(library_sm& fsm,transition_event const& evt)
0428         {
0429             if ( ROW::guard_call(fsm,evt,
0430                                  ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0431                                  ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0432                                  fsm.m_substate_list ) )
0433                 return true;
0434             return false;
0435         }
0436         // Take the transition action and return the next state.
0437         static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event& evt)
0438         {
0439 
0440             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0441             BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
0442             boost::ignore_unused(state); // Avoid warnings if BOOST_ASSERT expands to nothing.
0443             BOOST_ASSERT(state == (current_state));
0444             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
0445             if (has_pseudo_exit<T1>::type::value &&
0446                 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
0447             {
0448                 return HANDLED_FALSE;
0449             }
0450             if (!check_guard(fsm,evt))
0451             {
0452                 // guard rejected the event, we stay in the current one
0453                 return HANDLED_GUARD_REJECT;
0454             }
0455             fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
0456 
0457             // the guard condition has already been checked
0458             execute_exit<current_state_type>
0459                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
0460             fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
0461 
0462             // then call the action method
0463             HandledEnum res = ROW::action_call(fsm,evt,
0464                              ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0465                              ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0466                              fsm.m_substate_list);
0467             fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
0468 
0469             // and finally the entry method of the new current state
0470             convert_event_and_execute_entry<next_state_type,T2>
0471                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
0472             fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
0473             return res;
0474         }
0475     };
0476 
0477     // row having only a guard condition
0478     template<
0479         typename ROW
0480     >
0481     struct g_row_
0482     {
0483         //typedef typename ROW::Source T1;
0484         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0485         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0486         typedef typename ROW::Evt transition_event;
0487         // if the source is an exit pseudo state, then
0488         // current_state_type becomes the result of get_owner
0489         // meaning the containing SM from which the exit occurs
0490         typedef typename ::boost::mpl::eval_if<
0491                 typename has_pseudo_exit<T1>::type,
0492                 get_owner<T1,library_sm>,
0493                 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
0494 
0495         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
0496         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
0497         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
0498         typedef typename ::boost::mpl::eval_if<
0499             typename ::boost::mpl::is_sequence<T2>::type,
0500             get_fork_owner<T2,library_sm>,
0501             ::boost::mpl::eval_if<
0502                     typename has_no_automatic_create<T2>::type,
0503                     get_owner<T2,library_sm>,
0504                     ::boost::mpl::identity<T2> >
0505         >::type next_state_type;
0506 
0507         // if a guard condition is defined, call it to check that the event is accepted
0508         static bool check_guard(library_sm& fsm,transition_event const& evt)
0509         {
0510             if ( ROW::guard_call(fsm,evt,
0511                                  ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0512                                  ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0513                                  fsm.m_substate_list ))
0514                 return true;
0515             return false;
0516         }
0517         // Take the transition action and return the next state.
0518         static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
0519         {
0520             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0521             BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
0522             boost::ignore_unused(state); // Avoid warnings if BOOST_ASSERT expands to nothing.
0523             BOOST_ASSERT(state == (current_state));
0524             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
0525             if (has_pseudo_exit<T1>::type::value &&
0526                 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
0527             {
0528                 return HANDLED_FALSE;
0529             }
0530             if (!check_guard(fsm,evt))
0531             {
0532                 // guard rejected the event, we stay in the current one
0533                 return HANDLED_GUARD_REJECT;
0534             }
0535             fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
0536 
0537             // the guard condition has already been checked
0538             execute_exit<current_state_type>
0539                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
0540             fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
0541             fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
0542 
0543             // and finally the entry method of the new current state
0544             convert_event_and_execute_entry<next_state_type,T2>
0545                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
0546             fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
0547             return HANDLED_TRUE;
0548         }
0549     };
0550 
0551     // row having only an action method
0552     template<
0553         typename ROW
0554     >
0555     struct a_row_
0556     {
0557         //typedef typename ROW::Source T1;
0558         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0559         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0560         typedef typename ROW::Evt transition_event;
0561         // if the source is an exit pseudo state, then
0562         // current_state_type becomes the result of get_owner
0563         // meaning the containing SM from which the exit occurs
0564         typedef typename ::boost::mpl::eval_if<
0565                 typename has_pseudo_exit<T1>::type,
0566                 get_owner<T1,library_sm>,
0567                 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
0568 
0569         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
0570         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
0571         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
0572         typedef typename ::boost::mpl::eval_if<
0573             typename ::boost::mpl::is_sequence<T2>::type,
0574             get_fork_owner<T2,library_sm>,
0575             ::boost::mpl::eval_if<
0576                     typename has_no_automatic_create<T2>::type,
0577                     get_owner<T2,library_sm>,
0578                     ::boost::mpl::identity<T2> >
0579         >::type next_state_type;
0580 
0581         // Take the transition action and return the next state.
0582         static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event& evt)
0583         {
0584             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0585             BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
0586             boost::ignore_unused(state); // Avoid warnings if BOOST_ASSERT expands to nothing.
0587             BOOST_ASSERT(state == (current_state));
0588 
0589             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
0590             if (has_pseudo_exit<T1>::type::value &&
0591                 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
0592             {
0593                 return HANDLED_FALSE;
0594             }
0595             fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
0596 
0597             // no need to check the guard condition
0598             // first call the exit method of the current state
0599             execute_exit<current_state_type>
0600                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
0601             fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
0602 
0603             // then call the action method
0604             HandledEnum res = ROW::action_call(fsm,evt,
0605                             ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0606                             ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0607                             fsm.m_substate_list);
0608             fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
0609 
0610             // and finally the entry method of the new current state
0611             convert_event_and_execute_entry<next_state_type,T2>
0612                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
0613             fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
0614             return res;
0615         }
0616     };
0617 
0618     // row having no guard condition or action, simply transitions
0619     template<
0620         typename ROW
0621     >
0622     struct _row_
0623     {
0624         //typedef typename ROW::Source T1;
0625         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0626         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0627         typedef typename ROW::Evt transition_event;
0628         // if the source is an exit pseudo state, then
0629         // current_state_type becomes the result of get_owner
0630         // meaning the containing SM from which the exit occurs
0631         typedef typename ::boost::mpl::eval_if<
0632                 typename has_pseudo_exit<T1>::type,
0633                 get_owner<T1,library_sm>,
0634                 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
0635 
0636         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
0637         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
0638         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
0639         typedef typename ::boost::mpl::eval_if<
0640             typename ::boost::mpl::is_sequence<T2>::type,
0641             get_fork_owner<T2,library_sm>,
0642             ::boost::mpl::eval_if<
0643                     typename has_no_automatic_create<T2>::type,
0644                     get_owner<T2,library_sm>,
0645                     ::boost::mpl::identity<T2> >
0646         >::type next_state_type;
0647 
0648         // Take the transition action and return the next state.
0649         static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
0650         {
0651             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0652             BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
0653             boost::ignore_unused(state); // Avoid warnings if BOOST_ASSERT expands to nothing.
0654             BOOST_ASSERT(state == (current_state));
0655 
0656             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
0657             if (has_pseudo_exit<T1>::type::value &&
0658                 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
0659             {
0660                 return HANDLED_FALSE;
0661             }
0662             fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
0663 
0664             // first call the exit method of the current state
0665             execute_exit<current_state_type>
0666                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
0667             fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
0668             fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
0669 
0670 
0671             // and finally the entry method of the new current state
0672             convert_event_and_execute_entry<next_state_type,T2>
0673                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
0674             fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
0675             return HANDLED_TRUE;
0676         }
0677     };
0678     // "i" rows are rows for internal transitions
0679     template<
0680         typename ROW
0681     >
0682     struct irow_
0683     {
0684         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0685         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0686         typedef typename ROW::Evt transition_event;
0687         typedef typename ROW::Source current_state_type;
0688         typedef T2 next_state_type;
0689 
0690         // if a guard condition is here, call it to check that the event is accepted
0691         static bool check_guard(library_sm& fsm,transition_event const& evt)
0692         {
0693             if ( ROW::guard_call(fsm,evt,
0694                                  ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0695                                  ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0696                                  fsm.m_substate_list))
0697                 return true;
0698             return false;
0699         }
0700         // Take the transition action and return the next state.
0701         static HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
0702         {
0703 
0704             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0705             boost::ignore_unused(state, current_state); // Avoid warnings if BOOST_ASSERT expands to nothing.
0706             BOOST_ASSERT(state == (current_state));
0707             if (!check_guard(fsm,evt))
0708             {
0709                 // guard rejected the event, we stay in the current one
0710                 return HANDLED_GUARD_REJECT;
0711             }
0712 
0713             // call the action method
0714             HandledEnum res = ROW::action_call(fsm,evt,
0715                              ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0716                              ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0717                              fsm.m_substate_list);
0718             return res;
0719         }
0720     };
0721 
0722     // row having only a guard condition
0723     template<
0724         typename ROW
0725     >
0726     struct g_irow_
0727     {
0728         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0729         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0730         typedef typename ROW::Evt transition_event;
0731         typedef typename ROW::Source current_state_type;
0732         typedef T2 next_state_type;
0733 
0734         // if a guard condition is defined, call it to check that the event is accepted
0735         static bool check_guard(library_sm& fsm,transition_event const& evt)
0736         {
0737             if ( ROW::guard_call(fsm,evt,
0738                                  ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0739                                  ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0740                                  fsm.m_substate_list) )
0741                 return true;
0742             return false;
0743         }
0744         // Take the transition action and return the next state.
0745         static HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
0746         {
0747             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0748             boost::ignore_unused(state, current_state); // Avoid warnings if BOOST_ASSERT expands to nothing.
0749             BOOST_ASSERT(state == (current_state));
0750             if (!check_guard(fsm,evt))
0751             {
0752                 // guard rejected the event, we stay in the current one
0753                 return HANDLED_GUARD_REJECT;
0754             }
0755             return HANDLED_TRUE;
0756         }
0757     };
0758 
0759     // row having only an action method
0760     template<
0761         typename ROW
0762     >
0763     struct a_irow_
0764     {
0765         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0766         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0767 
0768         typedef typename ROW::Evt transition_event;
0769         typedef typename ROW::Source current_state_type;
0770         typedef T2 next_state_type;
0771 
0772         // Take the transition action and return the next state.
0773         static HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
0774         {
0775             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0776             boost::ignore_unused(state, current_state); // Avoid warnings if BOOST_ASSERT expands to nothing.
0777             BOOST_ASSERT(state == (current_state));
0778 
0779             // call the action method
0780             HandledEnum res = ROW::action_call(fsm,evt,
0781                             ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0782                             ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0783                             fsm.m_substate_list);
0784 
0785             return res;
0786         }
0787     };
0788     // row simply ignoring the event
0789     template<
0790         typename ROW
0791     >
0792     struct _irow_
0793     {
0794         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0795         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0796         typedef typename ROW::Evt transition_event;
0797         typedef typename ROW::Source current_state_type;
0798         typedef T2 next_state_type;
0799 
0800         // Take the transition action and return the next state.
0801         static HandledEnum execute(library_sm& , int , int state, transition_event const& )
0802         {
0803             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0804             boost::ignore_unused(state, current_state); // Avoid warnings if BOOST_ASSERT expands to nothing.
0805             BOOST_ASSERT(state == (current_state));
0806             return HANDLED_TRUE;
0807         }
0808     };
0809     // transitions internal to this state machine (no substate involved)
0810     template<
0811         typename ROW,
0812         typename StateType
0813     >
0814     struct internal_
0815     {
0816         typedef StateType current_state_type;
0817         typedef StateType next_state_type;
0818         typedef typename ROW::Evt transition_event;
0819 
0820         // if a guard condition is here, call it to check that the event is accepted
0821         static bool check_guard(library_sm& fsm,transition_event const& evt)
0822         {
0823             if ( ROW::guard_call(fsm,evt,
0824                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0825                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0826                 fsm.m_substate_list) )
0827                 return true;
0828             return false;
0829         }
0830         // Take the transition action and return the next state.
0831         static HandledEnum execute(library_sm& fsm, int , int , transition_event const& evt)
0832         {
0833             if (!check_guard(fsm,evt))
0834             {
0835                 // guard rejected the event, we stay in the current one
0836                 return HANDLED_GUARD_REJECT;
0837             }
0838 
0839             // then call the action method
0840             HandledEnum res = ROW::action_call(fsm,evt,
0841                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0842                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0843                 fsm.m_substate_list);
0844             return res;
0845         }
0846     };
0847     template<
0848         typename ROW
0849     >
0850     struct internal_ <ROW,library_sm>
0851     {
0852         typedef library_sm current_state_type;
0853         typedef library_sm next_state_type;
0854         typedef typename ROW::Evt transition_event;
0855 
0856         // if a guard condition is here, call it to check that the event is accepted
0857         static bool check_guard(library_sm& fsm,transition_event const& evt)
0858         {
0859             if ( ROW::guard_call(fsm,evt,
0860                 fsm,
0861                 fsm,
0862                 fsm.m_substate_list) )
0863                 return true;
0864             return false;
0865         }
0866         // Take the transition action and return the next state.
0867         static HandledEnum execute(library_sm& fsm, int , int , transition_event const& evt)
0868         {
0869             if (!check_guard(fsm,evt))
0870             {
0871                 // guard rejected the event, we stay in the current one
0872                 return HANDLED_GUARD_REJECT;
0873             }
0874 
0875             // then call the action method
0876             HandledEnum res = ROW::action_call(fsm,evt,
0877                 fsm,
0878                 fsm,
0879                 fsm.m_substate_list);
0880             return res;
0881         }
0882     };
0883 
0884     template<
0885         typename ROW,
0886         typename StateType
0887     >
0888     struct a_internal_
0889     {
0890         typedef StateType current_state_type;
0891         typedef StateType next_state_type;
0892         typedef typename ROW::Evt transition_event;
0893 
0894         // Take the transition action and return the next state.
0895         static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
0896         {
0897             // then call the action method
0898             HandledEnum res = ROW::action_call(fsm,evt,
0899                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0900                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0901                 fsm.m_substate_list);
0902             return res;
0903         }
0904     };
0905     template<
0906         typename ROW
0907     >
0908     struct a_internal_ <ROW,library_sm>
0909     {
0910         typedef library_sm current_state_type;
0911         typedef library_sm next_state_type;
0912         typedef typename ROW::Evt transition_event;
0913 
0914         // Take the transition action and return the next state.
0915         static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
0916         {
0917             // then call the action method
0918             HandledEnum res = ROW::action_call(fsm,evt,
0919                 fsm,
0920                 fsm,
0921                 fsm.m_substate_list);
0922             return res;
0923         }
0924     };
0925     template<
0926         typename ROW,
0927         typename StateType
0928     >
0929     struct g_internal_
0930     {
0931         typedef StateType current_state_type;
0932         typedef StateType next_state_type;
0933         typedef typename ROW::Evt transition_event;
0934 
0935         // if a guard condition is here, call it to check that the event is accepted
0936         static bool check_guard(library_sm& fsm,transition_event const& evt)
0937         {
0938             if ( ROW::guard_call(fsm,evt,
0939                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0940                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0941                 fsm.m_substate_list) )
0942                 return true;
0943             return false;
0944         }
0945         // Take the transition action and return the next state.
0946         static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
0947         {
0948             if (!check_guard(fsm,evt))
0949             {
0950                 // guard rejected the event, we stay in the current one
0951                 return HANDLED_GUARD_REJECT;
0952             }
0953             return HANDLED_TRUE;
0954         }
0955     };
0956     template<
0957         typename ROW
0958     >
0959     struct g_internal_ <ROW,library_sm>
0960     {
0961         typedef library_sm current_state_type;
0962         typedef library_sm next_state_type;
0963         typedef typename ROW::Evt transition_event;
0964 
0965         // if a guard condition is here, call it to check that the event is accepted
0966         static bool check_guard(library_sm& fsm,transition_event const& evt)
0967         {
0968             if ( ROW::guard_call(fsm,evt,
0969                 fsm,
0970                 fsm,
0971                 fsm.m_substate_list) )
0972                 return true;
0973             return false;
0974         }
0975         // Take the transition action and return the next state.
0976         static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
0977         {
0978             if (!check_guard(fsm,evt))
0979             {
0980                 // guard rejected the event, we stay in the current one
0981                 return HANDLED_GUARD_REJECT;
0982             }
0983             return HANDLED_TRUE;
0984         }
0985     };
0986     template<
0987         typename ROW,
0988         typename StateType
0989     >
0990     struct _internal_
0991     {
0992         typedef StateType current_state_type;
0993         typedef StateType next_state_type;
0994         typedef typename ROW::Evt transition_event;
0995         static HandledEnum execute(library_sm& , int , int , transition_event const& )
0996         {
0997             return HANDLED_TRUE;
0998         }
0999     };
1000     template<
1001         typename ROW
1002     >
1003     struct _internal_ <ROW,library_sm>
1004     {
1005         typedef library_sm current_state_type;
1006         typedef library_sm next_state_type;
1007         typedef typename ROW::Evt transition_event;
1008         static HandledEnum execute(library_sm& , int , int , transition_event const& )
1009         {
1010             return HANDLED_TRUE;
1011         }
1012     };
1013     // Template used to form forwarding rows in the transition table for every row of a composite SM
1014     template<
1015         typename T1
1016         , class Evt
1017     >
1018     struct frow
1019     {
1020         typedef T1                  current_state_type;
1021         typedef T1                  next_state_type;
1022         typedef Evt                 transition_event;
1023         // tag to find out if a row is a forwarding row
1024         typedef int                 is_frow;
1025 
1026         // Take the transition action and return the next state.
1027         static HandledEnum execute(library_sm& fsm, int region_index, int , transition_event const& evt)
1028         {
1029             // false as second parameter because this event is forwarded from outer fsm
1030             execute_return res =
1031                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list)).process_event_internal(evt);
1032             fsm.m_states[region_index]=get_state_id<stt,T1>::type::value;
1033             return res;
1034         }
1035         // helper metafunctions used by dispatch table and give the frow a new event
1036         // (used to avoid double entries in a table because of base events)
1037         template <class NewEvent>
1038         struct replace_event
1039         {
1040             typedef frow<T1,NewEvent> type;
1041         };
1042     };
1043 
1044     template <class Tag, class Transition,class StateType>
1045     struct create_backend_stt
1046     {
1047     };
1048     template <class Transition,class StateType>
1049     struct create_backend_stt<g_row_tag,Transition,StateType>
1050     {
1051         typedef g_row_<Transition> type;
1052     };
1053     template <class Transition,class StateType>
1054     struct create_backend_stt<a_row_tag,Transition,StateType>
1055     {
1056         typedef a_row_<Transition> type;
1057     };
1058     template <class Transition,class StateType>
1059     struct create_backend_stt<_row_tag,Transition,StateType>
1060     {
1061         typedef _row_<Transition> type;
1062     };
1063     template <class Transition,class StateType>
1064     struct create_backend_stt<row_tag,Transition,StateType>
1065     {
1066         typedef row_<Transition> type;
1067     };
1068     // internal transitions
1069     template <class Transition,class StateType>
1070     struct create_backend_stt<g_irow_tag,Transition,StateType>
1071     {
1072         typedef g_irow_<Transition> type;
1073     };
1074     template <class Transition,class StateType>
1075     struct create_backend_stt<a_irow_tag,Transition,StateType>
1076     {
1077         typedef a_irow_<Transition> type;
1078     };
1079     template <class Transition,class StateType>
1080     struct create_backend_stt<irow_tag,Transition,StateType>
1081     {
1082         typedef irow_<Transition> type;
1083     };
1084     template <class Transition,class StateType>
1085     struct create_backend_stt<_irow_tag,Transition,StateType>
1086     {
1087         typedef _irow_<Transition> type;
1088     };
1089     template <class Transition,class StateType>
1090     struct create_backend_stt<sm_a_i_row_tag,Transition,StateType>
1091     {
1092         typedef a_internal_<Transition,StateType> type;
1093     };
1094     template <class Transition,class StateType>
1095     struct create_backend_stt<sm_g_i_row_tag,Transition,StateType>
1096     {
1097         typedef g_internal_<Transition,StateType> type;
1098     };
1099     template <class Transition,class StateType>
1100     struct create_backend_stt<sm_i_row_tag,Transition,StateType>
1101     {
1102         typedef internal_<Transition,StateType> type;
1103     };
1104     template <class Transition,class StateType>
1105     struct create_backend_stt<sm__i_row_tag,Transition,StateType>
1106     {
1107         typedef _internal_<Transition,StateType> type;
1108     };
1109     template <class Transition,class StateType=void>
1110     struct make_row_tag
1111     {
1112         typedef typename create_backend_stt<typename Transition::row_type_tag,Transition,StateType>::type type;
1113     };
1114 
1115     // add to the stt the initial states which could be missing (if not being involved in a transition)
1116     template <class BaseType, class stt_simulated = typename BaseType::transition_table>
1117     struct create_real_stt
1118     {
1119         //typedef typename BaseType::transition_table stt_simulated;
1120         typedef typename ::boost::mpl::fold<
1121             stt_simulated,mpl::vector0<>,
1122             ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1123                                      make_row_tag< ::boost::mpl::placeholders::_2 , BaseType > >
1124         >::type type;
1125     };
1126 
1127     template <class Table,class Intermediate,class StateType>
1128     struct add_forwarding_row_helper
1129     {
1130         typedef typename generate_event_set<Table>::type all_events;
1131         typedef typename ::boost::mpl::fold<
1132             all_events, Intermediate,
1133             ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1134             frow<StateType, ::boost::mpl::placeholders::_2> > >::type type;
1135     };
1136     // gets the transition table from a composite and make from it a forwarding row
1137     template <class StateType,class IsComposite>
1138     struct get_internal_transition_table
1139     {
1140         // first get the table of a composite
1141         typedef typename recursive_get_transition_table<StateType>::type original_table;
1142 
1143         // we now look for the events the composite has in its internal transitions
1144         // the internal ones are searched recursively in sub-sub... states
1145         // we go recursively because our states can also have internal tables or substates etc.
1146         typedef typename recursive_get_internal_transition_table<StateType, ::boost::mpl::true_>::type recursive_istt;
1147         typedef typename ::boost::mpl::fold<
1148                     recursive_istt,::boost::mpl::vector0<>,
1149                     ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1150                                              make_row_tag< ::boost::mpl::placeholders::_2 , StateType> >
1151                 >::type recursive_istt_with_tag;
1152 
1153         typedef typename ::boost::mpl::insert_range< original_table, typename ::boost::mpl::end<original_table>::type,
1154                                                      recursive_istt_with_tag>::type table_with_all_events;
1155 
1156         // and add for every event a forwarding row
1157         typedef typename ::boost::mpl::eval_if<
1158                 typename CompilePolicy::add_forwarding_rows,
1159                 add_forwarding_row_helper<table_with_all_events,::boost::mpl::vector0<>,StateType>,
1160                 ::boost::mpl::identity< ::boost::mpl::vector0<> >
1161         >::type type;
1162     };
1163     template <class StateType>
1164     struct get_internal_transition_table<StateType, ::boost::mpl::false_ >
1165     {
1166         typedef typename create_real_stt<StateType, typename StateType::internal_transition_table >::type type;
1167     };
1168     // typedefs used internally
1169     typedef typename create_real_stt<Derived>::type real_transition_table;
1170     typedef typename create_stt<library_sm>::type stt;
1171     typedef typename get_initial_states<typename Derived::initial_state>::type initial_states;
1172     typedef typename generate_state_set<stt>::type state_list;
1173     typedef typename HistoryPolicy::template apply<nr_regions::value>::type concrete_history;
1174 
1175     typedef typename ::boost::fusion::result_of::as_set<state_list>::type substate_list;
1176     typedef typename ::boost::msm::back::generate_event_set<
1177         typename create_real_stt<library_sm, typename library_sm::internal_transition_table >::type
1178     >::type processable_events_internal_table;
1179 
1180     // extends the transition table with rows from composite states
1181     template <class Composite>
1182     struct extend_table
1183     {
1184         // add the init states
1185         //typedef typename create_stt<Composite>::type stt;
1186         typedef typename Composite::stt Stt;
1187 
1188         // add the internal events defined in the internal_transition_table
1189         // Note: these are added first because they must have a lesser prio
1190         // than the deeper transitions in the sub regions
1191         // table made of a stt + internal transitions of composite
1192         typedef typename ::boost::mpl::fold<
1193             typename Composite::internal_transition_table,::boost::mpl::vector0<>,
1194             ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1195                                      make_row_tag< ::boost::mpl::placeholders::_2 , Composite> >
1196         >::type internal_stt;
1197 
1198         typedef typename ::boost::mpl::insert_range<
1199             Stt,
1200             typename ::boost::mpl::end<Stt>::type,
1201             internal_stt
1202             //typename get_internal_transition_table<Composite, ::boost::mpl::true_ >::type
1203         >::type stt_plus_internal;
1204 
1205         // for every state, add its transition table (if any)
1206         // transformed as frow
1207         typedef typename ::boost::mpl::fold<state_list,stt_plus_internal,
1208                 ::boost::mpl::insert_range<
1209                         ::boost::mpl::placeholders::_1,
1210                         ::boost::mpl::end< ::boost::mpl::placeholders::_1>,
1211                         get_internal_transition_table<
1212                                 ::boost::mpl::placeholders::_2,
1213                                 is_composite_state< ::boost::mpl::placeholders::_2> > >
1214         >::type type;
1215     };
1216     // extend the table with tables from composite states
1217     typedef typename extend_table<library_sm>::type complete_table;
1218      // build a sequence of regions
1219      typedef typename get_regions_as_sequence<typename Derived::initial_state>::type seq_initial_states;
1220     // Member functions
1221 
1222     // start the state machine (calls entry of the initial state)
1223     void start()
1224     {
1225          // reinitialize our list of currently active states with the ones defined in Derived::initial_state
1226          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1227                         (init_states(m_states));
1228         // call on_entry on this SM
1229         (static_cast<Derived*>(this))->on_entry(fsm_initial_event(),*this);
1230         ::boost::mpl::for_each<initial_states, boost::msm::wrap<mpl::placeholders::_1> >
1231             (call_init<fsm_initial_event>(fsm_initial_event(),this));
1232         // give a chance to handle an anonymous (eventless) transition
1233         handle_eventless_transitions_helper<library_sm> eventless_helper(this,true);
1234         eventless_helper.process_completion_event();
1235     }
1236 
1237     // start the state machine (calls entry of the initial state passing incomingEvent to on_entry's)
1238     template <class Event>
1239     void start(Event const& incomingEvent)
1240     {
1241         // reinitialize our list of currently active states with the ones defined in Derived::initial_state
1242         ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1243                         (init_states(m_states));
1244         // call on_entry on this SM
1245         (static_cast<Derived*>(this))->on_entry(incomingEvent,*this);
1246         ::boost::mpl::for_each<initial_states, boost::msm::wrap<mpl::placeholders::_1> >
1247             (call_init<Event>(incomingEvent,this));
1248         // give a chance to handle an anonymous (eventless) transition
1249         handle_eventless_transitions_helper<library_sm> eventless_helper(this,true);
1250         eventless_helper.process_completion_event();
1251     }
1252 
1253     // stop the state machine (calls exit of the current state)
1254     void stop()
1255     {
1256         do_exit(fsm_final_event(),*this);
1257     }
1258 
1259     // stop the state machine (calls exit of the current state passing finalEvent to on_exit's)
1260     template <class Event>
1261     void stop(Event const& finalEvent)
1262     {
1263         do_exit(finalEvent,*this);
1264     }
1265 
1266     // Main function used by clients of the derived FSM to make transitions.
1267     template<class Event>
1268     execute_return process_event(Event const& evt)
1269     {
1270         return process_event_internal(evt, EVENT_SOURCE_DIRECT);
1271     }
1272 
1273     template <class EventType>
1274     void enqueue_event_helper(EventType const& evt, ::boost::mpl::false_ const &)
1275     {
1276         execute_return (library_sm::*pf) (EventType const&, EventSource) =
1277             &library_sm::process_event_internal;
1278 
1279         m_events_queue.m_events_queue.push_back(
1280             ::boost::bind(
1281                 pf, this, evt,
1282                 static_cast<EventSource>(EVENT_SOURCE_MSG_QUEUE)));
1283     }
1284     template <class EventType>
1285     void enqueue_event_helper(EventType const& , ::boost::mpl::true_ const &)
1286     {
1287         // no queue
1288     }
1289 
1290     void execute_queued_events_helper(::boost::mpl::false_ const &)
1291     {
1292         while(!m_events_queue.m_events_queue.empty())
1293         {
1294             transition_fct to_call = m_events_queue.m_events_queue.front();
1295             m_events_queue.m_events_queue.pop_front();
1296             to_call();
1297         }
1298     }
1299     void execute_queued_events_helper(::boost::mpl::true_ const &)
1300     {
1301         // no queue required
1302     }
1303     void execute_single_queued_event_helper(::boost::mpl::false_ const &)
1304     {
1305         transition_fct to_call = m_events_queue.m_events_queue.front();
1306         m_events_queue.m_events_queue.pop_front();
1307         to_call();
1308     }
1309     void execute_single_queued_event_helper(::boost::mpl::true_ const &)
1310     {
1311         // no queue required
1312     }
1313     // enqueues an event in the message queue
1314     // call execute_queued_events to process all queued events.
1315     // Be careful if you do this during event processing, the event will be processed immediately
1316     // and not kept in the queue
1317     template <class EventType>
1318     void enqueue_event(EventType const& evt)
1319     {
1320         enqueue_event_helper<EventType>(evt, typename is_no_message_queue<library_sm>::type());
1321     }
1322 
1323     // empty the queue and process events
1324     void execute_queued_events()
1325     {
1326         execute_queued_events_helper(typename is_no_message_queue<library_sm>::type());
1327     }
1328     void execute_single_queued_event()
1329     {
1330         execute_single_queued_event_helper(typename is_no_message_queue<library_sm>::type());
1331     }
1332     typename events_queue_t::size_type get_message_queue_size() const
1333     {
1334         return m_events_queue.m_events_queue.size();
1335     }
1336 
1337     events_queue_t& get_message_queue()
1338     {
1339         return m_events_queue.m_events_queue;
1340     }
1341 
1342     const events_queue_t& get_message_queue() const
1343     {
1344         return m_events_queue.m_events_queue;
1345     }
1346 
1347     void clear_deferred_queue()
1348     {
1349         m_deferred_events_queue.clear();
1350     }
1351 
1352     deferred_events_queue_t& get_deferred_queue()
1353     {
1354         return m_deferred_events_queue.m_deferred_events_queue;
1355     }
1356 
1357     const deferred_events_queue_t& get_deferred_queue() const
1358     {
1359         return m_deferred_events_queue.m_deferred_events_queue;
1360     }
1361 
1362     // Getter that returns the current state of the FSM
1363     const int* current_state() const
1364     {
1365         return this->m_states;
1366     }
1367 
1368     template <class Archive>
1369     struct serialize_state
1370     {
1371         serialize_state(Archive& ar):ar_(ar){}
1372 
1373         template<typename T>
1374         typename ::boost::enable_if<
1375             typename ::boost::mpl::or_<
1376                 typename has_do_serialize<T>::type,
1377                 typename is_composite_state<T>::type
1378             >::type
1379             ,void
1380         >::type
1381         operator()(T& t) const
1382         {
1383             ar_ & t;
1384         }
1385         template<typename T>
1386         typename ::boost::disable_if<
1387             typename ::boost::mpl::or_<
1388                 typename has_do_serialize<T>::type,
1389                 typename is_composite_state<T>::type
1390             >::type
1391             ,void
1392         >::type
1393         operator()(T&) const
1394         {
1395             // no state to serialize
1396         }
1397         Archive& ar_;
1398     };
1399 
1400     template<class Archive>
1401     void serialize(Archive & ar, const unsigned int)
1402     {
1403         // invoke serialization of the base class
1404         (serialize_state<Archive>(ar))(boost::serialization::base_object<Derived>(*this));
1405         // now our attributes
1406         ar & m_states;
1407         // queues cannot be serialized => skip
1408         ar & m_history;
1409         ar & m_event_processing;
1410         ar & m_is_included;
1411         // visitors cannot be serialized => skip
1412         ::boost::fusion::for_each(m_substate_list, serialize_state<Archive>(ar));
1413     }
1414 
1415     // linearly search for the state with the given id
1416     struct get_state_id_helper
1417     {
1418         get_state_id_helper(int id,const BaseState** res,const library_sm* self_):
1419         result_state(res),searched_id(id),self(self_) {}
1420 
1421         template <class StateType>
1422         void operator()(boost::msm::wrap<StateType> const&)
1423         {
1424             // look for the state id until found
1425             BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,StateType>::value));
1426             if (!*result_state && (id == searched_id))
1427             {
1428                 *result_state = &::boost::fusion::at_key<StateType>(self->m_substate_list);
1429             }
1430         }
1431         const BaseState**  result_state;
1432         int                searched_id;
1433         const library_sm* self;
1434     };
1435     // return the state whose id is passed or 0 if not found
1436     // caution if you need this, you probably need polymorphic states
1437     // complexity: O(number of states)
1438     BaseState* get_state_by_id(int id)
1439     {
1440         const BaseState*  result_state=0;
1441         ::boost::mpl::for_each<state_list,
1442             ::boost::msm::wrap< ::boost::mpl::placeholders::_1> > (get_state_id_helper(id,&result_state,this));
1443         return const_cast<BaseState*>(result_state);
1444     }
1445     const BaseState* get_state_by_id(int id) const
1446     {
1447         const BaseState*  result_state=0;
1448         ::boost::mpl::for_each<state_list,
1449             ::boost::msm::wrap< ::boost::mpl::placeholders::_1> > (get_state_id_helper(id,&result_state,this));
1450         return result_state;
1451     }
1452     // true if the sm is used in another sm
1453     bool is_contained() const
1454     {
1455         return m_is_included;
1456     }
1457     // get the history policy class
1458     concrete_history& get_history()
1459     {
1460         return m_history;
1461     }
1462     concrete_history const& get_history() const
1463     {
1464         return m_history;
1465     }
1466     // get a state (const version)
1467     // as a pointer
1468     template <class State>
1469     typename ::boost::enable_if<typename ::boost::is_pointer<State>::type,State >::type
1470     get_state(::boost::msm::back::dummy<0> = 0) const
1471     {
1472         return const_cast<State >
1473             (&
1474                 (::boost::fusion::at_key<
1475                     typename ::boost::remove_const<typename ::boost::remove_pointer<State>::type>::type>(m_substate_list)));
1476     }
1477     // as a reference
1478     template <class State>
1479     typename ::boost::enable_if<typename ::boost::is_reference<State>::type,State >::type
1480     get_state(::boost::msm::back::dummy<1> = 0) const
1481     {
1482         return const_cast<State >
1483             ( ::boost::fusion::at_key<
1484                 typename ::boost::remove_const<typename ::boost::remove_reference<State>::type>::type>(m_substate_list) );
1485     }
1486     // get a state (non const version)
1487     // as a pointer
1488     template <class State>
1489     typename ::boost::enable_if<typename ::boost::is_pointer<State>::type,State >::type
1490     get_state(::boost::msm::back::dummy<0> = 0)
1491     {
1492         return &(static_cast<typename boost::add_reference<typename ::boost::remove_pointer<State>::type>::type >
1493         (::boost::fusion::at_key<typename ::boost::remove_pointer<State>::type>(m_substate_list)));
1494     }
1495     // as a reference
1496     template <class State>
1497     typename ::boost::enable_if<typename ::boost::is_reference<State>::type,State >::type
1498     get_state(::boost::msm::back::dummy<1> = 0)
1499     {
1500         return ::boost::fusion::at_key<typename ::boost::remove_reference<State>::type>(m_substate_list);
1501     }
1502     // checks if a flag is active using the BinaryOp as folding function
1503     template <class Flag,class BinaryOp>
1504     bool is_flag_active() const
1505     {
1506         flag_handler* flags_entries = get_entries_for_flag<Flag>();
1507         bool res = (*flags_entries[ m_states[0] ])(*this);
1508         for (int i = 1; i < nr_regions::value ; ++i)
1509         {
1510             res = typename BinaryOp::type() (res,(*flags_entries[ m_states[i] ])(*this));
1511         }
1512         return res;
1513     }
1514     // checks if a flag is active using no binary op if 1 region, or OR if > 1 regions
1515     template <class Flag>
1516     bool is_flag_active() const
1517     {
1518         return FlagHelper<Flag,(nr_regions::value>1)>::helper(*this,get_entries_for_flag<Flag>());
1519     }
1520     // visit the currently active states (if these are defined as visitable
1521     // by implementing accept)
1522     void visit_current_states()
1523     {
1524         for (int i=0; i<nr_regions::value;++i)
1525         {
1526             m_visitors.execute(m_states[i]);
1527         }
1528     }
1529 #define MSM_VISIT_STATE_SUB(z, n, unused) ARG ## n vis ## n
1530 #define MSM_VISIT_STATE_EXECUTE(z, n, unused)                                    \
1531         template <BOOST_PP_ENUM_PARAMS(n, class ARG)>                               \
1532         void visit_current_states(BOOST_PP_ENUM(n, MSM_VISIT_STATE_SUB, ~ ) )         \
1533         {                                                                           \
1534             for (int i=0; i<nr_regions::value;++i)                                                      \
1535             {                                                                                           \
1536                 m_visitors.execute(m_states[i],BOOST_PP_ENUM_PARAMS(n,vis));                            \
1537             }                                                                                           \
1538         }
1539         BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISIT_STATE_EXECUTE, ~)
1540 #undef MSM_VISIT_STATE_EXECUTE
1541 #undef MSM_VISIT_STATE_SUB
1542 
1543     // puts the given event into the deferred queue
1544     template <class Event>
1545     typename::boost::disable_if< typename ::boost::msm::is_kleene_event<Event>::type, void>::type
1546     defer_event(Event const& e)
1547     {
1548         // to call this function, you need either a state with a deferred_events typedef
1549         // or that the fsm provides the activate_deferred_events typedef
1550         BOOST_MPL_ASSERT(( has_fsm_deferred_events<library_sm> ));
1551         execute_return (library_sm::*pf) (Event const&, EventSource) =
1552             &library_sm::process_event_internal;
1553 
1554         // Deferred events are added with a correlation sequence that helps to
1555         // identify when an event was added - This is typically to distinguish
1556         // between events deferred in this processing versus previous.
1557         m_deferred_events_queue.m_deferred_events_queue.push_back(
1558             std::make_pair(
1559                 ::boost::bind(
1560                     pf, this, e, static_cast<EventSource>(EVENT_SOURCE_DIRECT|EVENT_SOURCE_DEFERRED)),
1561                 static_cast<char>(m_deferred_events_queue.m_cur_seq+1)));
1562     }
1563 protected:
1564     template <class KleeneEvent, class Fsm>
1565     struct defer_event_kleene_helper
1566     {
1567         defer_event_kleene_helper(KleeneEvent const& e, Fsm* fsm, bool& found)
1568             : m_event(e), m_fsm(fsm), m_found(found) {}
1569 
1570         // History initializer function object, used with mpl::for_each
1571         template <class Event>
1572         void operator()(Event const& ev)
1573         {
1574             if (m_event.type() == boost::typeindex::type_id<decltype(ev)>().type_info())
1575             {
1576                 m_found = true;
1577                 // to call this function, you need either a state with a deferred_events typedef
1578                 // or that the fsm provides the activate_deferred_events typedef
1579                 BOOST_MPL_ASSERT((has_fsm_deferred_events<library_sm>));
1580                 ::boost::msm::back::execute_return(library_sm:: * pf) (Event const&, ::boost::msm::back::EventSource) =
1581                     &library_sm::process_event_internal;
1582 
1583                 // Deferred events are added with a correlation sequence that helps to
1584                 // identify when an event was added - This is typically to distinguish
1585                 // between events deferred in this processing versus previous.
1586                 m_fsm->m_deferred_events_queue.m_deferred_events_queue.push_back(
1587                     std::make_pair(
1588                         ::boost::bind(
1589                             pf, m_fsm, boost::any_cast<Event>(m_event), static_cast<::boost::msm::back::EventSource>(::boost::msm::back::EVENT_SOURCE_DIRECT | ::boost::msm::back::EVENT_SOURCE_DEFERRED)),
1590                         static_cast<char>(m_fsm->m_deferred_events_queue.m_cur_seq + 1)));
1591             }
1592         }
1593         KleeneEvent const& m_event;
1594         Fsm* m_fsm;
1595         bool& m_found;
1596     };
1597 
1598 public:
1599     template <class Event>
1600     typename::boost::enable_if< typename ::boost::msm::is_kleene_event<Event>::type, void>::type
1601     defer_event(Event const& e)
1602     {
1603         typedef typename generate_event_set<stt>::type event_list;
1604         bool found = false;
1605         boost::fusion::for_each(
1606             event_list(),
1607             defer_event_kleene_helper<Event,library_sm>(e,this,found));
1608         if (!found)
1609         {
1610             for (int i = 0; i < nr_regions::value; ++i)
1611             {
1612                 this->no_transition(e, *this, this->m_states[i]);
1613             }
1614         }
1615     }
1616 
1617 
1618  protected:    // interface for the derived class
1619 
1620      // helper used to fill the initial states
1621      struct init_states
1622      {
1623          init_states(int* const init):m_initial_states(init),m_index(-1){}
1624 
1625          // History initializer function object, used with mpl::for_each
1626          template <class State>
1627          void operator()(::boost::msm::wrap<State> const&)
1628          {
1629              m_initial_states[++m_index]=get_state_id<stt,State>::type::value;
1630          }
1631          int* const m_initial_states;
1632          int m_index;
1633      };
1634  public:
1635      struct update_state
1636      {
1637          update_state(substate_list& to_overwrite_):to_overwrite(&to_overwrite_){}
1638          template<typename StateType>
1639          void operator()(StateType const& astate) const
1640          {
1641              ::boost::fusion::at_key<StateType>(*to_overwrite)=astate;
1642          }
1643          substate_list* to_overwrite;
1644      };
1645      template <class Expr>
1646      void set_states(Expr const& expr)
1647      {
1648          ::boost::fusion::for_each(
1649              ::boost::fusion::as_vector(FoldToList()(expr, boost::fusion::nil_())),update_state(this->m_substate_list));
1650      }
1651 
1652      // Construct with the default initial states
1653      state_machine()
1654          :Derived()
1655          ,m_events_queue()
1656          ,m_deferred_events_queue()
1657          ,m_history()
1658          ,m_event_processing(false)
1659          ,m_is_included(false)
1660          ,m_visitors()
1661          ,m_substate_list()
1662      {
1663          // initialize our list of states with the ones defined in Derived::initial_state
1664          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1665                         (init_states(m_states));
1666          m_history.set_initial_states(m_states);
1667          // create states
1668          fill_states(this);
1669      }
1670 
1671      // Construct with the default initial states and some default argument(s)
1672 #if defined (BOOST_NO_CXX11_RVALUE_REFERENCES)                                      \
1673     || defined (BOOST_NO_CXX11_VARIADIC_TEMPLATES)                                  \
1674     || defined (BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
1675      template <class Expr>
1676      state_machine
1677      (Expr const& expr, typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type* = 0)
1678          :Derived()
1679          , m_events_queue()
1680          , m_deferred_events_queue()
1681          , m_history()
1682          , m_event_processing(false)
1683          , m_is_included(false)
1684          , m_visitors()
1685          , m_substate_list()
1686      {
1687          BOOST_MPL_ASSERT_MSG(
1688              (::boost::proto::matches<Expr, FoldToList>::value),
1689              THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR,
1690              (FoldToList));
1691 
1692          // initialize our list of states with the ones defined in Derived::initial_state
1693          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1694              (init_states(m_states));
1695          m_history.set_initial_states(m_states);
1696          // create states
1697          set_states(expr);
1698          fill_states(this);
1699      }
1700 #define MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB(z, n, unused) ARG ## n t ## n
1701 #define MSM_CONSTRUCTOR_HELPER_EXECUTE(z, n, unused)                                \
1702         template <BOOST_PP_ENUM_PARAMS(n, class ARG)>                               \
1703         state_machine<A0,A1,A2,A3,A4                                                \
1704         >(BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ),                 \
1705         typename ::boost::disable_if<typename ::boost::proto::is_expr<ARG0>::type >::type* =0 )                \
1706         :Derived(BOOST_PP_ENUM_PARAMS(n,t))                                         \
1707          ,m_events_queue()                                                          \
1708          ,m_deferred_events_queue()                                                 \
1709          ,m_history()                                                               \
1710          ,m_event_processing(false)                                                 \
1711          ,m_is_included(false)                                                      \
1712          ,m_visitors()                                                              \
1713          ,m_substate_list()                                                         \
1714      {                                                                              \
1715          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> > \
1716                         (init_states(m_states));                                    \
1717          m_history.set_initial_states(m_states);                                    \
1718          fill_states(this);                                                         \
1719      }                                                                              \
1720         template <class Expr,BOOST_PP_ENUM_PARAMS(n, class ARG)>                    \
1721         state_machine<A0,A1,A2,A3,A4                                                \
1722         >(Expr const& expr,BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ), \
1723         typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type* =0 ) \
1724         :Derived(BOOST_PP_ENUM_PARAMS(n,t))                                         \
1725          ,m_events_queue()                                                          \
1726          ,m_deferred_events_queue()                                                 \
1727          ,m_history()                                                               \
1728          ,m_event_processing(false)                                                 \
1729          ,m_is_included(false)                                                      \
1730          ,m_visitors()                                                              \
1731          ,m_substate_list()                                                         \
1732      {                                                                              \
1733          BOOST_MPL_ASSERT_MSG(                                                      \
1734          ( ::boost::proto::matches<Expr, FoldToList>::value),                       \
1735              THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR,                   \
1736              (FoldToList));                                                         \
1737          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> > \
1738                         (init_states(m_states));                                    \
1739          m_history.set_initial_states(m_states);                                    \
1740          set_states(expr);                                                          \
1741          fill_states(this);                                                         \
1742      }
1743 
1744      BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_CONSTRUCTOR_ARG_SIZE,1), MSM_CONSTRUCTOR_HELPER_EXECUTE, ~)
1745 #undef MSM_CONSTRUCTOR_HELPER_EXECUTE
1746 #undef MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB
1747 
1748 #else
1749     template <class ARG0,class... ARG,class=typename ::boost::disable_if<typename ::boost::proto::is_expr<ARG0>::type >::type>
1750     state_machine(ARG0&& t0,ARG&&... t)
1751     :Derived(std::forward<ARG0>(t0), std::forward<ARG>(t)...)
1752      ,m_events_queue()
1753      ,m_deferred_events_queue()
1754      ,m_history()
1755      ,m_event_processing(false)
1756      ,m_is_included(false)
1757      ,m_visitors()
1758      ,m_substate_list()
1759      {
1760          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1761                         (init_states(m_states));
1762          m_history.set_initial_states(m_states);
1763          fill_states(this);
1764      }
1765     template <class Expr,class... ARG,class=typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type>
1766     state_machine(Expr const& expr,ARG&&... t)
1767     :Derived(std::forward<ARG>(t)...)
1768      ,m_events_queue()
1769      ,m_deferred_events_queue()
1770      ,m_history()
1771      ,m_event_processing(false)
1772      ,m_is_included(false)
1773      ,m_visitors()
1774      ,m_substate_list()
1775      {
1776          BOOST_MPL_ASSERT_MSG(
1777          ( ::boost::proto::matches<Expr, FoldToList>::value),
1778              THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR,
1779              (FoldToList));
1780          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1781                         (init_states(m_states));
1782          m_history.set_initial_states(m_states);
1783          set_states(expr);
1784          fill_states(this);
1785      }
1786 #endif
1787 
1788 
1789      // assignment operator using the copy policy to decide if non_copyable, shallow or deep copying is necessary
1790      library_sm& operator= (library_sm const& rhs)
1791      {
1792          if (this != &rhs)
1793          {
1794             Derived::operator=(rhs);
1795             do_copy(rhs);
1796          }
1797         return *this;
1798      }
1799      state_machine(library_sm const& rhs)
1800          : Derived(rhs)
1801      {
1802         if (this != &rhs)
1803         {
1804             // initialize our list of states with the ones defined in Derived::initial_state
1805             fill_states(this);
1806             do_copy(rhs);
1807         }
1808      }
1809 
1810     // the following 2 functions handle the terminate/interrupt states handling
1811     // if one of these states is found, the first one is used
1812     template <class Event>
1813     bool is_event_handling_blocked_helper( ::boost::mpl::true_ const &)
1814     {
1815         // if the state machine is terminated, do not handle any event
1816         if (is_flag_active< ::boost::msm::TerminateFlag>())
1817             return true;
1818         // if the state machine is interrupted, do not handle any event
1819         // unless the event is the end interrupt event
1820         if ( is_flag_active< ::boost::msm::InterruptedFlag>() &&
1821             !is_flag_active< ::boost::msm::EndInterruptFlag<Event> >())
1822             return true;
1823         return false;
1824     }
1825     // otherwise simple handling, no flag => continue
1826     template <class Event>
1827     bool is_event_handling_blocked_helper( ::boost::mpl::false_ const &)
1828     {
1829         // no terminate/interrupt states detected
1830         return false;
1831     }
1832     void do_handle_prio_msg_queue_deferred_queue(EventSource source, HandledEnum handled, ::boost::mpl::true_ const &)
1833     {
1834         // non-default. Handle msg queue with higher prio than deferred queue
1835         if (!(EVENT_SOURCE_MSG_QUEUE & source))
1836         {
1837             do_post_msg_queue_helper(
1838                 ::boost::mpl::bool_<
1839                     is_no_message_queue<library_sm>::type::value>());
1840             if (!(EVENT_SOURCE_DEFERRED & source))
1841             {
1842                 handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue);
1843                 defer_helper.do_handle_deferred(HANDLED_TRUE & handled);
1844             }
1845         }
1846     }
1847     void do_handle_prio_msg_queue_deferred_queue(EventSource source, HandledEnum handled, ::boost::mpl::false_ const &)
1848     {
1849         // default. Handle deferred queue with higher prio than msg queue
1850         if (!(EVENT_SOURCE_DEFERRED & source))
1851         {
1852             handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue);
1853             defer_helper.do_handle_deferred(HANDLED_TRUE & handled);
1854 
1855             // Handle any new events generated into the queue, but only if
1856             // we're not already processing from the message queue.
1857             if (!(EVENT_SOURCE_MSG_QUEUE & source))
1858             {
1859                 do_post_msg_queue_helper(
1860                     ::boost::mpl::bool_<
1861                         is_no_message_queue<library_sm>::type::value>());
1862             }
1863         }
1864     }
1865     // the following functions handle pre/post-process handling  of a message queue
1866     template <class StateType,class EventType>
1867     bool do_pre_msg_queue_helper(EventType const&, ::boost::mpl::true_ const &)
1868     {
1869         // no message queue needed
1870         return true;
1871     }
1872     template <class StateType,class EventType>
1873     bool do_pre_msg_queue_helper(EventType const& evt, ::boost::mpl::false_ const &)
1874     {
1875         execute_return (library_sm::*pf) (EventType const&, EventSource) =
1876             &library_sm::process_event_internal;
1877 
1878         // if we are already processing an event
1879         if (m_event_processing)
1880         {
1881             // event has to be put into the queue
1882             m_events_queue.m_events_queue.push_back(
1883                 ::boost::bind(
1884                     pf, this, evt,
1885                     static_cast<EventSource>(EVENT_SOURCE_DIRECT | EVENT_SOURCE_MSG_QUEUE)));
1886 
1887             return false;
1888         }
1889 
1890         // event can be handled, processing
1891         m_event_processing = true;
1892         return true;
1893     }
1894     void do_post_msg_queue_helper( ::boost::mpl::true_ const &)
1895     {
1896         // no message queue needed
1897     }
1898     void do_post_msg_queue_helper( ::boost::mpl::false_ const &)
1899     {
1900         process_message_queue(this);
1901     }
1902     void do_allow_event_processing_after_transition( ::boost::mpl::true_ const &)
1903     {
1904         // no message queue needed
1905     }
1906     void do_allow_event_processing_after_transition( ::boost::mpl::false_ const &)
1907     {
1908         m_event_processing = false;
1909     }
1910     // the following 2 functions handle the processing either with a try/catch protection or without
1911     template <class StateType,class EventType>
1912     HandledEnum do_process_helper(EventType const& evt, ::boost::mpl::true_ const &, bool is_direct_call)
1913     {
1914         return this->do_process_event(evt,is_direct_call);
1915     }
1916     template <class StateType,class EventType>
1917     HandledEnum do_process_helper(EventType const& evt, ::boost::mpl::false_ const &, bool is_direct_call)
1918     {
1919         // when compiling without exception support there is no formal parameter "e" in the catch handler.
1920         // Declaring a local variable here does not hurt and will be "used" to make the code in the handler
1921         // compilable although the code will never be executed.
1922         std::exception e;
1923         BOOST_TRY
1924         {
1925             return this->do_process_event(evt,is_direct_call);
1926         }
1927         BOOST_CATCH (std::exception& e)
1928         {
1929             // give a chance to the concrete state machine to handle
1930             this->exception_caught(evt,*this,e);
1931             return ::boost::msm::back::HANDLED_FALSE;
1932         }
1933         BOOST_CATCH_END
1934         return HANDLED_TRUE;
1935     }
1936     // handling of deferred events
1937     // if none is found in the SM, take the following empty main version
1938     template <class StateType, class Enable = int>
1939     struct handle_defer_helper
1940     {
1941         handle_defer_helper(deferred_msg_queue_helper<library_sm>& ){}
1942         void do_handle_deferred(bool)
1943         {
1944         }
1945     };
1946     // otherwise the standard version handling the deferred events
1947     template <class StateType>
1948     struct handle_defer_helper
1949         <StateType, typename enable_if< typename ::boost::msm::back::has_fsm_deferred_events<StateType>::type,int >::type>
1950     {
1951         struct sort_greater
1952         {
1953             bool operator()(
1954                 typename deferred_events_queue_t::value_type const& d1,
1955                 typename deferred_events_queue_t::value_type const& d2)
1956             {
1957                 return d1.second > d2.second;
1958             }
1959         };
1960         struct set_sequence
1961         {
1962             set_sequence(char s) :seq_(s) {}
1963             void operator()(typename deferred_events_queue_t::value_type& d)
1964             {
1965                 d.second = seq_;
1966             }
1967             char seq_;
1968         };
1969         handle_defer_helper(deferred_msg_queue_helper<library_sm>& a_queue):
1970             m_events_queue(a_queue) {}
1971         void do_handle_deferred(bool new_seq=false)
1972         {
1973             // A new sequence is typically started upon initial entry to the
1974             // state, or upon a new transition.  When this occurs we want to
1975             // process all previously deferred events by incrementing the
1976             // correlation sequence.
1977             if (new_seq)
1978             {
1979                 ++m_events_queue.m_cur_seq;
1980             }
1981 
1982             char& cur_seq = m_events_queue.m_cur_seq;
1983 
1984             // Iteratively process all of the events within the deferred
1985             // queue upto (but not including) newly deferred events.
1986             // if we did not defer one in the queue, then we need to try again
1987             bool not_only_deferred = false;
1988             while (!m_events_queue.m_deferred_events_queue.empty())
1989             {
1990                 typename deferred_events_queue_t::value_type& pair =
1991                     m_events_queue.m_deferred_events_queue.front();
1992 
1993                 if (cur_seq != pair.second)
1994                 {
1995                     break;
1996                 }
1997 
1998                 deferred_fct next = pair.first;
1999                 m_events_queue.m_deferred_events_queue.pop_front();
2000                 boost::msm::back::execute_return res = next();
2001                 if (res != ::boost::msm::back::HANDLED_FALSE && res != ::boost::msm::back::HANDLED_DEFERRED)
2002                 {
2003                     not_only_deferred = true;
2004                 }
2005                 if (not_only_deferred)
2006                 {
2007                     // handled one, stop processing deferred until next block reorders
2008                     break;
2009                 }
2010             }
2011             if (not_only_deferred)
2012             {
2013                 // attempt to go back to the situation prior to processing, 
2014                 // in case some deferred events would have been re-queued
2015                 // in that case those would have a higher sequence number
2016                 std::stable_sort(
2017                     m_events_queue.m_deferred_events_queue.begin(),
2018                     m_events_queue.m_deferred_events_queue.end(),
2019                     sort_greater()
2020                 );
2021                 // reset sequence number for all
2022                 std::for_each(
2023                     m_events_queue.m_deferred_events_queue.begin(),
2024                     m_events_queue.m_deferred_events_queue.end(),
2025                     set_sequence(m_events_queue.m_cur_seq + 1)
2026                 );
2027                 // one deferred event was successfully processed, try again
2028                 do_handle_deferred(true);
2029             }
2030         }
2031 
2032     private:
2033         deferred_msg_queue_helper<library_sm>& m_events_queue;
2034     };
2035 
2036     // handling of eventless transitions
2037     // if none is found in the SM, nothing to do
2038     template <class StateType, class Enable = void>
2039     struct handle_eventless_transitions_helper
2040     {
2041         handle_eventless_transitions_helper(library_sm* , bool ){}
2042         void process_completion_event(EventSource = EVENT_SOURCE_DEFAULT){}
2043     };
2044     // otherwise
2045     template <class StateType>
2046     struct handle_eventless_transitions_helper
2047         <StateType, typename enable_if< typename ::boost::msm::back::has_fsm_eventless_transition<StateType>::type >::type>
2048     {
2049         handle_eventless_transitions_helper(library_sm* self_, bool handled_):self(self_),handled(handled_){}
2050         void process_completion_event(EventSource source = EVENT_SOURCE_DEFAULT)
2051         {
2052             typedef typename ::boost::mpl::deref<
2053                 typename ::boost::mpl::begin<
2054                     typename find_completion_events<StateType>::type
2055                         >::type
2056             >::type first_completion_event;
2057             if (handled)
2058             {
2059                 self->process_event_internal(
2060                     first_completion_event(),
2061                     source | EVENT_SOURCE_DIRECT);
2062             }
2063         }
2064 
2065     private:
2066         library_sm* self;
2067         bool        handled;
2068     };
2069 
2070     // helper class called in case the event to process has been found in the fsm's internal stt and is therefore processable
2071     template<class Event>
2072     struct process_fsm_internal_table
2073     {
2074         typedef typename ::boost::mpl::has_key<processable_events_internal_table,Event>::type is_event_processable;
2075 
2076         // forward to the correct do_process
2077         static void process(Event const& evt,library_sm* self_,HandledEnum& result)
2078         {
2079             do_process(evt,self_,result,is_event_processable());
2080         }
2081     private:
2082         // the event is processable, let's try!
2083         static void do_process(Event const& evt,library_sm* self_,HandledEnum& result, ::boost::mpl::true_)
2084         {
2085             if (result != HANDLED_TRUE)
2086             {
2087                 typedef dispatch_table<library_sm,complete_table,Event,CompilePolicy> table;
2088                 HandledEnum res_internal = table::instance().entries[0](*self_, 0, self_->m_states[0], evt);
2089                 result = (HandledEnum)((int)result | (int)res_internal);
2090             }
2091         }
2092         // version doing nothing if the event is not in the internal stt and we can save ourselves the time trying to process
2093         static void do_process(Event const& ,library_sm* ,HandledEnum& , ::boost::mpl::false_)
2094         {
2095             // do nothing
2096         }
2097     };
2098 
2099     template <class StateType,class Enable=void>
2100     struct region_processing_helper
2101     {
2102     public:
2103         region_processing_helper(library_sm* self_,HandledEnum& result_)
2104             :self(self_),result(result_){}
2105         template<class Event>
2106         void process(Event const& evt)
2107         {
2108             // use this table as if it came directly from the user
2109             typedef dispatch_table<library_sm,complete_table,Event,CompilePolicy> table;
2110             // +1 because index 0 is reserved for this fsm
2111             HandledEnum res =
2112                 table::instance().entries[self->m_states[0]+1](
2113                 *self, 0, self->m_states[0], evt);
2114             result = (HandledEnum)((int)result | (int)res);
2115             // process the event in the internal table of this fsm if the event is processable (present in the table)
2116             process_fsm_internal_table<Event>::process(evt,self,result);
2117         }
2118         library_sm*     self;
2119         HandledEnum&    result;
2120     };
2121     // version with visitors
2122     template <class StateType>
2123     struct region_processing_helper<StateType,typename ::boost::enable_if<
2124                         ::boost::mpl::is_sequence<typename StateType::initial_state> >::type>
2125     {
2126         private:
2127         // process event in one region
2128         template <class region_id,int Dummy=0>
2129         struct In
2130         {
2131             template<class Event>
2132             static void process(Event const& evt,library_sm* self_,HandledEnum& result_)
2133             {
2134                 // use this table as if it came directly from the user
2135                 typedef dispatch_table<library_sm,complete_table,Event,CompilePolicy> table;
2136                 // +1 because index 0 is reserved for this fsm
2137                 HandledEnum res =
2138                     table::instance().entries[self_->m_states[region_id::value]+1](
2139                     *self_, region_id::value , self_->m_states[region_id::value], evt);
2140                 result_ = (HandledEnum)((int)result_ | (int)res);
2141                 In< ::boost::mpl::int_<region_id::value+1> >::process(evt,self_,result_);
2142             }
2143         };
2144         template <int Dummy>
2145         struct In< ::boost::mpl::int_<nr_regions::value>,Dummy>
2146         {
2147             // end of processing
2148             template<class Event>
2149             static void process(Event const& evt,library_sm* self_,HandledEnum& result_)
2150             {
2151                 // process the event in the internal table of this fsm if the event is processable (present in the table)
2152                 process_fsm_internal_table<Event>::process(evt,self_,result_);
2153             }
2154         };
2155         public:
2156         region_processing_helper(library_sm* self_,HandledEnum& result_)
2157             :self(self_),result(result_){}
2158         template<class Event>
2159         void process(Event const& evt)
2160         {
2161             In< ::boost::mpl::int_<0> >::process(evt,self,result);
2162         }
2163 
2164         library_sm*     self;
2165         HandledEnum&    result;
2166     };
2167 
2168     // Main function used internally to make transitions
2169     // Can only be called for internally (for example in an action method) generated events.
2170     template<class Event>
2171     execute_return process_event_internal(Event const& evt,
2172                                           EventSource source = EVENT_SOURCE_DEFAULT)
2173     {
2174         // if the state machine has terminate or interrupt flags, check them, otherwise skip
2175         if (is_event_handling_blocked_helper<Event>
2176                 ( ::boost::mpl::bool_<has_fsm_blocking_states<library_sm>::type::value>() ) )
2177         {
2178             return HANDLED_TRUE;
2179         }
2180 
2181         // if a message queue is needed and processing is on the way
2182         if (!do_pre_msg_queue_helper<Event>
2183                 (evt,::boost::mpl::bool_<is_no_message_queue<library_sm>::type::value>()))
2184         {
2185             // wait for the end of current processing
2186             return HANDLED_TRUE;
2187         }
2188         else
2189         {
2190             // Process event
2191             HandledEnum handled = this->do_process_helper<Event>(
2192                 evt,
2193                 ::boost::mpl::bool_<is_no_exception_thrown<library_sm>::type::value>(),
2194                 (EVENT_SOURCE_DIRECT & source));
2195 
2196             // at this point we allow the next transition be executed without enqueing
2197             // so that completion events and deferred events execute now (if any)
2198             do_allow_event_processing_after_transition(
2199                 ::boost::mpl::bool_<is_no_message_queue<library_sm>::type::value>());
2200 
2201             // Process completion transitions BEFORE any other event in the
2202             // pool (UML Standard 2.3 15.3.14)
2203             handle_eventless_transitions_helper<library_sm>
2204                 eventless_helper(this,(HANDLED_TRUE & handled));
2205             eventless_helper.process_completion_event(source);
2206 
2207             // After handling, take care of the deferred events, but only if
2208             // we're not already processing from the deferred queue.
2209             do_handle_prio_msg_queue_deferred_queue(
2210                         source,handled,
2211                         ::boost::mpl::bool_<has_event_queue_before_deferred_queue<library_sm>::type::value>());
2212             return handled;
2213         }
2214     }
2215 
2216     // minimum event processing without exceptions, queues, etc.
2217     template<class Event>
2218     HandledEnum do_process_event(Event const& evt, bool is_direct_call)
2219     {
2220         HandledEnum handled = HANDLED_FALSE;
2221 
2222         // dispatch the event to every region
2223         region_processing_helper<Derived> helper(this,handled);
2224         helper.process(evt);
2225 
2226         // if the event has not been handled and we have orthogonal zones, then
2227         // generate an error on every active state
2228         // for state machine states contained in other state machines, do not handle
2229         // but let the containing sm handle the error, unless the event was generated in this fsm
2230         // (by calling process_event on this fsm object, is_direct_call == true)
2231         // completion events do not produce an error
2232         if ( (!is_contained() || is_direct_call) && !handled && !is_completion_event<Event>::type::value)
2233         {
2234             for (int i=0; i<nr_regions::value;++i)
2235             {
2236                 this->no_transition(evt,*this,this->m_states[i]);
2237             }
2238         }
2239         return handled;
2240     }
2241 
2242     // default row arguments for the compilers which accept this
2243     template <class Event>
2244     bool no_guard(Event const&){return true;}
2245     template <class Event>
2246     void no_action(Event const&){}
2247 
2248 #ifndef BOOST_NO_RTTI
2249     HandledEnum process_any_event( ::boost::any const& evt);
2250 #endif
2251 
2252 private:
2253     // composite accept implementation. First calls accept on the composite, then accept on all its active states.
2254     void composite_accept()
2255     {
2256         this->accept();
2257         this->visit_current_states();
2258     }
2259 
2260 #define MSM_COMPOSITE_ACCEPT_SUB(z, n, unused) ARG ## n vis ## n
2261 #define MSM_COMPOSITE_ACCEPT_SUB2(z, n, unused) boost::ref( vis ## n )
2262 #define MSM_COMPOSITE_ACCEPT_EXECUTE(z, n, unused)                                      \
2263         template <BOOST_PP_ENUM_PARAMS(n, class ARG)>                                   \
2264         void composite_accept(BOOST_PP_ENUM(n, MSM_COMPOSITE_ACCEPT_SUB, ~ ) )               \
2265         {                                                                               \
2266             this->accept(BOOST_PP_ENUM_PARAMS(n,vis));                                        \
2267             this->visit_current_states(BOOST_PP_ENUM(n,MSM_COMPOSITE_ACCEPT_SUB2, ~));        \
2268         }
2269         BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_COMPOSITE_ACCEPT_EXECUTE, ~)
2270 #undef MSM_COMPOSITE_ACCEPT_EXECUTE
2271 #undef MSM_COMPOSITE_ACCEPT_SUB
2272 #undef MSM_COMPOSITE_ACCEPT_SUB2
2273 
2274     // helper used to call the init states at the start of the state machine
2275     template <class Event>
2276     struct call_init
2277     {
2278         call_init(Event const& an_event,library_sm* self_):
2279                 evt(an_event),self(self_){}
2280         template <class State>
2281         void operator()(boost::msm::wrap<State> const&)
2282         {
2283             execute_entry(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
2284         }
2285     private:
2286         Event const& evt;
2287         library_sm* self;
2288     };
2289     // helper for flag handling. Uses OR by default on orthogonal zones.
2290     template <class Flag,bool orthogonalStates>
2291     struct FlagHelper
2292     {
2293         static bool helper(library_sm const& sm,flag_handler* )
2294         {
2295             // by default we use OR to accumulate the flags
2296             return sm.is_flag_active<Flag,Flag_OR>();
2297         }
2298     };
2299     template <class Flag>
2300     struct FlagHelper<Flag,false>
2301     {
2302         static bool helper(library_sm const& sm,flag_handler* flags_entries)
2303         {
2304             // just one active state, so we can call operator[] with 0
2305             return flags_entries[sm.current_state()[0]](sm);
2306         }
2307     };
2308     // handling of flag
2309     // defines a true and false functions plus a forwarding one for composite states
2310     template <class StateType,class Flag>
2311     struct FlagHandler
2312     {
2313         static bool flag_true(library_sm const& )
2314         {
2315             return true;
2316         }
2317         static bool flag_false(library_sm const& )
2318         {
2319             return false;
2320         }
2321         static bool forward(library_sm const& fsm)
2322         {
2323             return ::boost::fusion::at_key<StateType>(fsm.m_substate_list).template is_flag_active<Flag>();
2324         }
2325     };
2326     template <class Flag>
2327     struct init_flags
2328     {
2329     private:
2330         // helper function, helps hiding the forward function for non-state machines states.
2331         template <class T>
2332         void helper (flag_handler* an_entry,int offset, ::boost::mpl::true_ const &  )
2333         {
2334             // composite => forward
2335             an_entry[offset] = &FlagHandler<T,Flag>::forward;
2336         }
2337         template <class T>
2338         void helper (flag_handler* an_entry,int offset, ::boost::mpl::false_ const &  )
2339         {
2340             // default no flag
2341             an_entry[offset] = &FlagHandler<T,Flag>::flag_false;
2342         }
2343         // attributes
2344         flag_handler* entries;
2345 
2346     public:
2347         init_flags(flag_handler* entries_)
2348             : entries(entries_)
2349         {}
2350 
2351         // Flags initializer function object, used with mpl::for_each
2352         template <class StateType>
2353         void operator()( ::boost::msm::wrap<StateType> const& )
2354         {
2355             typedef typename get_flag_list<StateType>::type flags;
2356             typedef typename ::boost::mpl::contains<flags,Flag >::type found;
2357 
2358             BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,StateType>::type::value));
2359             if (found::type::value)
2360             {
2361                 // the type defined the flag => true
2362                 entries[state_id] = &FlagHandler<StateType,Flag>::flag_true;
2363             }
2364             else
2365             {
2366                 // false or forward
2367                 typedef typename ::boost::mpl::and_<
2368                             typename is_composite_state<StateType>::type,
2369                             typename ::boost::mpl::not_<
2370                                     typename has_non_forwarding_flag<Flag>::type>::type >::type composite_no_forward;
2371 
2372                 helper<StateType>(entries,state_id,::boost::mpl::bool_<composite_no_forward::type::value>());
2373             }
2374         }
2375     };
2376     // maintains for every flag a static array containing the flag value for every state
2377     template <class Flag>
2378     flag_handler* get_entries_for_flag() const
2379     {
2380         BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
2381 
2382         static flag_handler flags_entries[max_state];
2383         // build a state list, but only once
2384         static flag_handler* flags_entries_ptr =
2385             (::boost::mpl::for_each<state_list, boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2386                             (init_flags<Flag>(flags_entries)),
2387             flags_entries);
2388         return flags_entries_ptr;
2389     }
2390 
2391     // helper used to create a state using the correct constructor
2392     template <class State, class Enable=void>
2393     struct create_state_helper
2394     {
2395         static void set_sm(library_sm* )
2396         {
2397             // state doesn't need its sm
2398         }
2399     };
2400     // create a state requiring a pointer to the state machine
2401     template <class State>
2402     struct create_state_helper<State,typename boost::enable_if<typename State::needs_sm >::type>
2403     {
2404         static void set_sm(library_sm* sm)
2405         {
2406             // create and set the fsm
2407             ::boost::fusion::at_key<State>(sm->m_substate_list).set_sm_ptr(sm);
2408         }
2409     };
2410         // main unspecialized helper class
2411         template <class StateType,int ARGS>
2412         struct visitor_args;
2413 
2414 #define MSM_VISITOR_ARGS_SUB(z, n, unused) BOOST_PP_CAT(::boost::placeholders::_,BOOST_PP_ADD(n,1))
2415 #define MSM_VISITOR_ARGS_TYPEDEF_SUB(z, n, unused) typename StateType::accept_sig::argument ## n
2416 
2417 #define MSM_VISITOR_ARGS_EXECUTE(z, n, unused)                                              \
2418     template <class StateType>                                                              \
2419     struct visitor_args<StateType,n>                                                        \
2420     {                                                                                       \
2421         template <class State>                                                              \
2422         static typename enable_if_c<!is_composite_state<State>::value,void >::type          \
2423         helper (library_sm* sm,                                                             \
2424         int id,StateType& astate)                                                           \
2425         {                                                                                   \
2426             sm->m_visitors.insert(id, boost::bind(&StateType::accept,                       \
2427                 ::boost::ref(astate) BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, MSM_VISITOR_ARGS_SUB, ~) ));   \
2428         }                                                                                   \
2429         template <class State>                                                              \
2430         static typename enable_if_c<is_composite_state<State>::value,void >::type           \
2431         helper (library_sm* sm,                                                             \
2432         int id,StateType& astate)                                                           \
2433         {                                                                                   \
2434             void (StateType::*caccept)(BOOST_PP_ENUM(n, MSM_VISITOR_ARGS_TYPEDEF_SUB, ~ ) )           \
2435                                         = &StateType::composite_accept;                     \
2436             sm->m_visitors.insert(id, boost::bind(caccept,             \
2437             ::boost::ref(astate) BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, MSM_VISITOR_ARGS_SUB, ~) ));                 \
2438         }                                                                                   \
2439 };
2440 BOOST_PP_REPEAT(BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_ARGS_EXECUTE, ~)
2441 #undef MSM_VISITOR_ARGS_EXECUTE
2442 #undef MSM_VISITOR_ARGS_SUB
2443 
2444 // the IBM compiler seems to have problems with nested classes
2445 // the same seems to apply to the Apple version of gcc 4.0.1 (just in case we do for < 4.1)
2446 // and also to MS VC < 8
2447 #if defined (__IBMCPP__) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2448      public:
2449 #endif
2450     template<class ContainingSM>
2451     void set_containing_sm(ContainingSM* sm)
2452     {
2453         m_is_included=true;
2454         ::boost::fusion::for_each(m_substate_list,add_state<ContainingSM>(this,sm));
2455     }
2456 #if defined (__IBMCPP__) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2457      private:
2458 #endif
2459     // A function object for use with mpl::for_each that stuffs
2460     // states into the state list.
2461     template<class ContainingSM>
2462     struct add_state
2463     {
2464         add_state(library_sm* self_,ContainingSM* sm)
2465             : self(self_),containing_sm(sm){}
2466 
2467         // State is a sub fsm with exit pseudo states and gets a pointer to this fsm, so it can build a callback
2468         template <class StateType>
2469         typename ::boost::enable_if<
2470             typename is_composite_state<StateType>::type,void >::type
2471         new_state_helper(boost::msm::back::dummy<0> = 0) const
2472         {
2473             ::boost::fusion::at_key<StateType>(self->m_substate_list).set_containing_sm(containing_sm);
2474         }
2475         // State is a sub fsm without exit pseudo states and does not get a callback to this fsm
2476         // or state is a normal state and needs nothing except creation
2477         template <class StateType>
2478         typename ::boost::enable_if<
2479             typename boost::mpl::and_<typename boost::mpl::not_
2480                                                     <typename is_composite_state<StateType>::type>::type,
2481                                       typename boost::mpl::not_
2482                                                     <typename is_pseudo_exit<StateType>::type>::type
2483                    >::type,void>::type
2484         new_state_helper( ::boost::msm::back::dummy<1> = 0) const
2485         {
2486             //nothing to do
2487         }
2488         // state is exit pseudo state and gets callback to target fsm
2489         template <class StateType>
2490         typename ::boost::enable_if<typename is_pseudo_exit<StateType>::type,void >::type
2491         new_state_helper( ::boost::msm::back::dummy<2> = 0) const
2492         {
2493             execute_return (ContainingSM::*pf) (typename StateType::event const& evt)=
2494                 &ContainingSM::process_event;
2495             ::boost::function<execute_return (typename StateType::event const&)> fct =
2496                 ::boost::bind(pf,containing_sm,::boost::placeholders::_1);
2497             ::boost::fusion::at_key<StateType>(self->m_substate_list).set_forward_fct(fct);
2498         }
2499         // for every defined state in the sm
2500         template <class State>
2501         void operator()( State const&) const
2502         {
2503             //create a new state with the defined id and type
2504             BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
2505 
2506             this->new_state_helper<State>(),
2507             create_state_helper<State>::set_sm(self);
2508             // create a visitor callback
2509             visitor_helper(state_id,::boost::fusion::at_key<State>(self->m_substate_list),
2510                            ::boost::mpl::bool_<has_accept_sig<State>::type::value>());
2511         }
2512     private:
2513         // support possible use of a visitor if accept_sig is defined
2514         template <class StateType>
2515         void visitor_helper(int id,StateType& astate, ::boost::mpl::true_ const & ) const
2516         {
2517             visitor_args<StateType,StateType::accept_sig::args_number>::
2518                 template helper<StateType>(self,id,astate);
2519         }
2520         template <class StateType>
2521         void visitor_helper(int ,StateType& , ::boost::mpl::false_ const &) const
2522         {
2523             // nothing to do
2524         }
2525 
2526         library_sm*      self;
2527         ContainingSM*    containing_sm;
2528     };
2529 
2530      // helper used to copy every state if needed
2531      struct copy_helper
2532      {
2533          copy_helper(library_sm* sm):
2534            m_sm(sm){}
2535          template <class StateType>
2536          void operator()( ::boost::msm::wrap<StateType> const& )
2537          {
2538             BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,StateType>::type::value));
2539             // possibly also set the visitor
2540             visitor_helper<StateType>(state_id);
2541 
2542             // and for states that keep a pointer to the fsm, reset the pointer
2543             create_state_helper<StateType>::set_sm(m_sm);
2544          }
2545          template <class StateType>
2546          typename ::boost::enable_if<typename has_accept_sig<StateType>::type,void >::type
2547              visitor_helper(int id) const
2548          {
2549              visitor_args<StateType,StateType::accept_sig::args_number>::template helper<StateType>
2550                  (m_sm,id,::boost::fusion::at_key<StateType>(m_sm->m_substate_list));
2551          }
2552          template <class StateType>
2553          typename ::boost::disable_if<typename has_accept_sig<StateType>::type,void >::type
2554              visitor_helper(int) const
2555          {
2556              // nothing to do
2557          }
2558 
2559          library_sm*     m_sm;
2560      };
2561      // helper to copy the active states attribute
2562      template <class region_id,int Dummy=0>
2563      struct region_copy_helper
2564      {
2565          static void do_copy(library_sm* self_,library_sm const& rhs)
2566          {
2567              self_->m_states[region_id::value] = rhs.m_states[region_id::value];
2568              region_copy_helper< ::boost::mpl::int_<region_id::value+1> >::do_copy(self_,rhs);
2569          }
2570      };
2571      template <int Dummy>
2572      struct region_copy_helper< ::boost::mpl::int_<nr_regions::value>,Dummy>
2573      {
2574          // end of processing
2575          static void do_copy(library_sm*,library_sm const& ){}
2576      };
2577      // copy functions for deep copy (no need of a 2nd version for NoCopy as noncopyable handles it)
2578      void do_copy (library_sm const& rhs,
2579               ::boost::msm::back::dummy<0> = 0)
2580      {
2581          // deep copy simply assigns the data
2582          region_copy_helper< ::boost::mpl::int_<0> >::do_copy(this,rhs);
2583          m_events_queue = rhs.m_events_queue;
2584          m_deferred_events_queue = rhs.m_deferred_events_queue;
2585          m_history = rhs.m_history;
2586          m_event_processing = rhs.m_event_processing;
2587          m_is_included = rhs.m_is_included;
2588          m_substate_list = rhs.m_substate_list;
2589          // except for the states themselves, which get duplicated
2590 
2591          ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2592                         (copy_helper(this));
2593      }
2594 
2595      // helper used to call the correct entry/exit method
2596      // unfortunately in O(number of states in the sub-sm) but should be better than a virtual call
2597      template<class Event,bool is_entry>
2598      struct entry_exit_helper
2599      {
2600          entry_exit_helper(int id,Event const& e,library_sm* self_):
2601             state_id(id),evt(e),self(self_){}
2602          // helper for entry actions
2603          template <class IsEntry,class State>
2604          typename ::boost::enable_if<typename IsEntry::type,void >::type
2605          helper( ::boost::msm::back::dummy<0> = 0)
2606          {
2607              BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,State>::value));
2608              if (id == state_id)
2609              {
2610                  execute_entry<State>(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
2611              }
2612          }
2613          // helper for exit actions
2614          template <class IsEntry,class State>
2615          typename boost::disable_if<typename IsEntry::type,void >::type
2616          helper( ::boost::msm::back::dummy<1> = 0)
2617          {
2618              BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,State>::value));
2619              if (id == state_id)
2620              {
2621                  execute_exit<State>(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
2622              }
2623          }
2624          // iterates through all states to find the one to be activated
2625          template <class State>
2626          void operator()( ::boost::msm::wrap<State> const&)
2627          {
2628              entry_exit_helper<Event,is_entry>::template helper< ::boost::mpl::bool_<is_entry>,State >();
2629          }
2630      private:
2631          int            state_id;
2632          Event const&   evt;
2633          library_sm*    self;
2634      };
2635 
2636      // helper to start the fsm
2637      template <class region_id,int Dummy=0>
2638      struct region_start_helper
2639      {
2640          template<class Event>
2641          static void do_start(library_sm* self_,Event const& incomingEvent)
2642          {
2643              //forward the event for handling by sub state machines
2644              ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2645                  (entry_exit_helper<Event,true>(self_->m_states[region_id::value],incomingEvent,self_));
2646              region_start_helper
2647                  < ::boost::mpl::int_<region_id::value+1> >::do_start(self_,incomingEvent);
2648          }
2649      };
2650      template <int Dummy>
2651      struct region_start_helper< ::boost::mpl::int_<nr_regions::value>,Dummy>
2652      {
2653          // end of processing
2654          template<class Event>
2655          static void do_start(library_sm*,Event const& ){}
2656      };
2657      // start for states machines which are themselves embedded in other state machines (composites)
2658      template <class Event>
2659      void internal_start(Event const& incomingEvent)
2660      {
2661          region_start_helper< ::boost::mpl::int_<0> >::do_start(this,incomingEvent);
2662          // give a chance to handle an anonymous (eventless) transition
2663          handle_eventless_transitions_helper<library_sm> eventless_helper(this,true);
2664          eventless_helper.process_completion_event();
2665      }
2666 
2667      template <class StateType>
2668      struct find_region_id
2669      {
2670          template <int region,int Dummy=0>
2671          struct In
2672          {
2673              enum {region_index=region};
2674          };
2675          // if the user provides no region, find it!
2676          template<int Dummy>
2677          struct In<-1,Dummy>
2678          {
2679              typedef typename build_orthogonal_regions<
2680                  library_sm,
2681                  initial_states
2682              >::type all_regions;
2683              enum {region_index= find_region_index<all_regions,StateType>::value };
2684          };
2685          enum {region_index = In<StateType::zone_index>::region_index };
2686      };
2687      // helper used to set the correct state as active state upon entry into a fsm
2688      struct direct_event_start_helper
2689      {
2690          direct_event_start_helper(library_sm* self_):self(self_){}
2691          // this variant is for the standard case, entry due to activation of the containing FSM
2692          template <class EventType,class FsmType>
2693          typename ::boost::disable_if<typename has_direct_entry<EventType>::type,void>::type
2694              operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<0> = 0)
2695          {
2696              (static_cast<Derived*>(self))->on_entry(evt,fsm);
2697              self->internal_start(evt);
2698          }
2699 
2700          // this variant is for the direct entry case (just one entry, not a sequence of entries)
2701          template <class EventType,class FsmType>
2702          typename ::boost::enable_if<
2703              typename ::boost::mpl::and_<
2704                         typename ::boost::mpl::not_< typename is_pseudo_entry<
2705                                     typename EventType::active_state>::type >::type,
2706                         typename ::boost::mpl::and_<typename has_direct_entry<EventType>::type,
2707                                                     typename ::boost::mpl::not_<typename ::boost::mpl::is_sequence
2708                                                             <typename EventType::active_state>::type >::type
2709                                                     >::type>::type,void
2710                                   >::type
2711          operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2712          {
2713              (static_cast<Derived*>(self))->on_entry(evt,fsm);
2714              int state_id = get_state_id<stt,typename EventType::active_state::wrapped_entry>::value;
2715              BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index >= 0);
2716              BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index < nr_regions::value);
2717              // just set the correct zone, the others will be default/history initialized
2718              self->m_states[find_region_id<typename EventType::active_state::wrapped_entry>::region_index] = state_id;
2719              self->internal_start(evt.m_event);
2720          }
2721 
2722          // this variant is for the fork entry case (a sequence on entries)
2723          template <class EventType,class FsmType>
2724          typename ::boost::enable_if<
2725              typename ::boost::mpl::and_<
2726                     typename ::boost::mpl::not_<
2727                                     typename is_pseudo_entry<typename EventType::active_state>::type >::type,
2728                     typename ::boost::mpl::and_<typename has_direct_entry<EventType>::type,
2729                                                 typename ::boost::mpl::is_sequence<
2730                                                                 typename EventType::active_state>::type
2731                                                 >::type>::type,void
2732                                 >::type
2733          operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<2> = 0)
2734          {
2735              (static_cast<Derived*>(self))->on_entry(evt,fsm);
2736              ::boost::mpl::for_each<typename EventType::active_state,
2737                                     ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2738                                                         (fork_helper<EventType>(self,evt));
2739              // set the correct zones, the others (if any) will be default/history initialized
2740              self->internal_start(evt.m_event);
2741          }
2742 
2743          // this variant is for the pseudo state entry case
2744          template <class EventType,class FsmType>
2745          typename ::boost::enable_if<
2746              typename is_pseudo_entry<typename EventType::active_state >::type,void
2747                                     >::type
2748          operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<3> = 0)
2749          {
2750              // entry on the FSM
2751              (static_cast<Derived*>(self))->on_entry(evt,fsm);
2752              int state_id = get_state_id<stt,typename EventType::active_state::wrapped_entry>::value;
2753              BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index >= 0);
2754              BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index < nr_regions::value);
2755              // given region starts with the entry pseudo state as active state
2756              self->m_states[find_region_id<typename EventType::active_state::wrapped_entry>::region_index] = state_id;
2757              self->internal_start(evt.m_event);
2758              // and we process the transition in the zone of the newly active state
2759              // (entry pseudo states are, according to UML, a state connecting 1 transition outside to 1 inside
2760              self->process_event(evt.m_event);
2761          }
2762      private:
2763          // helper for the fork case, does almost like the direct entry
2764          library_sm* self;
2765          template <class EventType>
2766          struct fork_helper
2767          {
2768              fork_helper(library_sm* self_,EventType const& evt_):
2769                 helper_self(self_),helper_evt(evt_){}
2770              template <class StateType>
2771              void operator()( ::boost::msm::wrap<StateType> const& )
2772              {
2773                  int state_id = get_state_id<stt,typename StateType::wrapped_entry>::value;
2774                  BOOST_STATIC_ASSERT(find_region_id<typename StateType::wrapped_entry>::region_index >= 0);
2775                  BOOST_STATIC_ASSERT(find_region_id<typename StateType::wrapped_entry>::region_index < nr_regions::value);
2776                  helper_self->m_states[find_region_id<typename StateType::wrapped_entry>::region_index] = state_id;
2777              }
2778          private:
2779              library_sm*        helper_self;
2780              EventType const&   helper_evt;
2781          };
2782      };
2783 
2784      // helper for entry
2785      template <class region_id,int Dummy=0>
2786      struct region_entry_exit_helper
2787      {
2788          template<class Event>
2789          static void do_entry(library_sm* self_,Event const& incomingEvent)
2790          {
2791              self_->m_states[region_id::value] =
2792                  self_->m_history.history_entry(incomingEvent)[region_id::value];
2793              region_entry_exit_helper
2794                  < ::boost::mpl::int_<region_id::value+1> >::do_entry(self_,incomingEvent);
2795          }
2796          template<class Event>
2797          static void do_exit(library_sm* self_,Event const& incomingEvent)
2798          {
2799              ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2800                  (entry_exit_helper<Event,false>(self_->m_states[region_id::value],incomingEvent,self_));
2801              region_entry_exit_helper
2802                  < ::boost::mpl::int_<region_id::value+1> >::do_exit(self_,incomingEvent);
2803          }
2804      };
2805      template <int Dummy>
2806      struct region_entry_exit_helper< ::boost::mpl::int_<nr_regions::value>,Dummy>
2807      {
2808          // end of processing
2809          template<class Event>
2810          static void do_entry(library_sm*,Event const& ){}
2811          template<class Event>
2812          static void do_exit(library_sm*,Event const& ){}
2813      };
2814      // entry/exit for states machines which are themselves embedded in other state machines (composites)
2815      template <class Event,class FsmType>
2816      void do_entry(Event const& incomingEvent,FsmType& fsm)
2817      {
2818         // by default we activate the history/init states, can be overwritten by direct_event_start_helper
2819         region_entry_exit_helper< ::boost::mpl::int_<0> >::do_entry(this,incomingEvent);
2820         // block immediate handling of events
2821         m_event_processing = true;
2822         // if the event is generating a direct entry/fork, set the current state(s) to the direct state(s)
2823         direct_event_start_helper(this)(incomingEvent,fsm);
2824         // handle messages which were generated and blocked in the init calls
2825         m_event_processing = false;
2826         // look for deferred events waiting
2827         handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue);
2828         defer_helper.do_handle_deferred(true);
2829         process_message_queue(this);
2830      }
2831      template <class Event,class FsmType>
2832      void do_exit(Event const& incomingEvent,FsmType& fsm)
2833      {
2834         // first recursively exit the sub machines
2835         // forward the event for handling by sub state machines
2836         region_entry_exit_helper< ::boost::mpl::int_<0> >::do_exit(this,incomingEvent);
2837         // then call our own exit
2838         (static_cast<Derived*>(this))->on_exit(incomingEvent,fsm);
2839         // give the history a chance to handle this (or not).
2840         m_history.history_exit(this->m_states);
2841         // history decides what happens with deferred events
2842         if (!m_history.process_deferred_events(incomingEvent))
2843         {
2844             clear_deferred_queue();
2845         }
2846      }
2847 
2848     // the IBM and VC<8 compilers seem to have problems with the friend declaration of dispatch_table
2849 #if defined (__IBMCPP__) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2850      public:
2851 #endif
2852     // no transition for event.
2853     template <class Event>
2854     static HandledEnum call_no_transition(library_sm& , int , int , Event const& )
2855     {
2856         return HANDLED_FALSE;
2857     }
2858     // no transition for event for internal transitions (not an error).
2859     template <class Event>
2860     static HandledEnum call_no_transition_internal(library_sm& , int , int , Event const& )
2861     {
2862         //// reject to give others a chance to handle
2863         //return HANDLED_GUARD_REJECT;
2864         return HANDLED_FALSE;
2865     }
2866     // called for deferred events. Address set in the dispatch_table at init
2867     template <class Event>
2868     static HandledEnum defer_transition(library_sm& fsm, int , int , Event const& e)
2869     {
2870         fsm.defer_event(e);
2871         return HANDLED_DEFERRED;
2872     }
2873     // called for completion events. Default address set in the dispatch_table at init
2874     // prevents no-transition detection for completion events
2875     template <class Event>
2876     static HandledEnum default_eventless_transition(library_sm&, int, int , Event const&)
2877     {
2878         return HANDLED_FALSE;
2879     }
2880 #if defined (__IBMCPP__) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2881      private:
2882 #endif
2883     // removes one event from the message queue and processes it
2884     template <class StateType>
2885     void process_message_queue(StateType*,
2886                                typename ::boost::disable_if<typename is_no_message_queue<StateType>::type,void >::type* = 0)
2887     {
2888         // Iteratively process all events from the message queue.
2889         while (!m_events_queue.m_events_queue.empty())
2890         {
2891             transition_fct next = m_events_queue.m_events_queue.front();
2892             m_events_queue.m_events_queue.pop_front();
2893             next();
2894         }
2895     }
2896     template <class StateType>
2897     void process_message_queue(StateType*,
2898                                typename ::boost::enable_if<typename is_no_message_queue<StateType>::type,void >::type* = 0)
2899     {
2900         // nothing to process
2901     }
2902     // helper function. In cases where the event is wrapped (target is a direct entry states)
2903     // we want to send only the real event to on_entry, not the wrapper.
2904     template <class EventType>
2905     static
2906     typename boost::enable_if<typename has_direct_entry<EventType>::type,typename EventType::contained_event const& >::type
2907     remove_direct_entry_event_wrapper(EventType const& evt,boost::msm::back::dummy<0> = 0)
2908     {
2909         return evt.m_event;
2910     }
2911     template <class EventType>
2912     static typename boost::disable_if<typename has_direct_entry<EventType>::type,EventType const& >::type
2913     remove_direct_entry_event_wrapper(EventType const& evt,boost::msm::back::dummy<1> = 0)
2914     {
2915         // identity. No wrapper
2916         return evt;
2917     }
2918     // calls the entry/exit or on_entry/on_exit depending on the state type
2919     // (avoids calling virtually)
2920     // variant for FSMs
2921     template <class StateType,class EventType,class FsmType>
2922     static
2923         typename boost::enable_if<typename is_composite_state<StateType>::type,void >::type
2924         execute_entry(StateType& astate,EventType const& evt,FsmType& fsm,boost::msm::back::dummy<0> = 0)
2925     {
2926         // calls on_entry on the fsm then handles direct entries, fork, entry pseudo state
2927         astate.do_entry(evt,fsm);
2928     }
2929     // variant for states
2930     template <class StateType,class EventType,class FsmType>
2931     static
2932         typename ::boost::disable_if<
2933             typename ::boost::mpl::or_<typename is_composite_state<StateType>::type,
2934                                        typename is_pseudo_exit<StateType>::type >::type,void >::type
2935     execute_entry(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2936     {
2937         // simple call to on_entry
2938         astate.on_entry(remove_direct_entry_event_wrapper(evt),fsm);
2939     }
2940     // variant for exit pseudo states
2941     template <class StateType,class EventType,class FsmType>
2942     static
2943         typename ::boost::enable_if<typename is_pseudo_exit<StateType>::type,void >::type
2944     execute_entry(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<2> = 0)
2945     {
2946         // calls on_entry on the state then forward the event to the transition which should be defined inside the
2947         // contained fsm
2948         astate.on_entry(evt,fsm);
2949         astate.forward_event(evt);
2950     }
2951     template <class StateType,class EventType,class FsmType>
2952     static
2953         typename ::boost::enable_if<typename is_composite_state<StateType>::type,void >::type
2954     execute_exit(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<0> = 0)
2955     {
2956         astate.do_exit(evt,fsm);
2957     }
2958     template <class StateType,class EventType,class FsmType>
2959     static
2960         typename ::boost::disable_if<typename is_composite_state<StateType>::type,void >::type
2961     execute_exit(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2962     {
2963         // simple call to on_exit
2964         astate.on_exit(evt,fsm);
2965     }
2966 
2967     // helper allowing special handling of direct entries / fork
2968     template <class StateType,class TargetType,class EventType,class FsmType>
2969     static
2970         typename ::boost::disable_if<
2971             typename ::boost::mpl::or_<typename has_explicit_entry_state<TargetType>::type,
2972                                        ::boost::mpl::is_sequence<TargetType> >::type,void>::type
2973     convert_event_and_execute_entry(StateType& astate,EventType const& evt, FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2974     {
2975         // if the target is a normal state, do the standard entry handling
2976         execute_entry<StateType>(astate,evt,fsm);
2977     }
2978     template <class StateType,class TargetType,class EventType,class FsmType>
2979     static
2980         typename ::boost::enable_if<
2981             typename ::boost::mpl::or_<typename has_explicit_entry_state<TargetType>::type,
2982                                        ::boost::mpl::is_sequence<TargetType> >::type,void >::type
2983     convert_event_and_execute_entry(StateType& astate,EventType const& evt, FsmType& fsm, ::boost::msm::back::dummy<0> = 0)
2984     {
2985         // for the direct entry, pack the event in a wrapper so that we handle it differently during fsm entry
2986         execute_entry(astate,msm::back::direct_entry_event<TargetType,EventType>(evt),fsm);
2987     }
2988 
2989     // creates all the states
2990     template <class ContainingSM>
2991     void fill_states(ContainingSM* containing_sm=0)
2992     {
2993         // checks that regions are truly orthogonal
2994         FsmCheckPolicy::template check_orthogonality<library_sm>();
2995         // checks that all states are reachable
2996         FsmCheckPolicy::template check_unreachable_states<library_sm>();
2997 
2998         BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
2999         // allocate the place without reallocation
3000         m_visitors.fill_visitors(max_state);
3001         ::boost::fusion::for_each(m_substate_list,add_state<ContainingSM>(this,containing_sm));
3002 
3003     }
3004 
3005 private:
3006     template <class StateType,class Enable=void>
3007     struct msg_queue_helper
3008     {
3009     public:
3010         msg_queue_helper():m_events_queue(){}
3011         events_queue_t              m_events_queue;
3012     };
3013     template <class StateType>
3014     struct msg_queue_helper<StateType,
3015         typename ::boost::enable_if<typename is_no_message_queue<StateType>::type >::type>
3016     {
3017     };
3018 
3019     template <class Fsm,class Stt, class Event, class Compile>
3020     friend struct dispatch_table;
3021 
3022     // data members
3023     int                             m_states[nr_regions::value];
3024     msg_queue_helper<library_sm>    m_events_queue;
3025     deferred_msg_queue_helper
3026         <library_sm>                m_deferred_events_queue;
3027     concrete_history                m_history;
3028     bool                            m_event_processing;
3029     bool                            m_is_included;
3030     visitor_fct_helper<BaseState>   m_visitors;
3031     substate_list                   m_substate_list;
3032 
3033 
3034 };
3035 
3036 } } }// boost::msm::back
3037 #endif //BOOST_MSM_BACK_STATEMACHINE_H