Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / msm / back / state_machine.hpp
1 // Copyright 2008 Christophe Henry
2 // henry UNDERSCORE christophe AT hotmail DOT com
3 // This is an extended version of the state machine available in the boost::mpl library
4 // Distributed under the same license as the original.
5 // Copyright for the original version:
6 // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
7 // under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10
11 #ifndef BOOST_MSM_BACK_STATEMACHINE_H
12 #define BOOST_MSM_BACK_STATEMACHINE_H
13
14 #include <exception>
15 #include <vector>
16 #include <functional>
17 #include <numeric>
18 #include <utility>
19
20 #include <boost/detail/no_exceptions_support.hpp>
21
22 #include <boost/mpl/contains.hpp>
23 #include <boost/mpl/deref.hpp>
24 #include <boost/mpl/assert.hpp>
25
26 #include <boost/fusion/container/vector/convert.hpp>
27 #include <boost/fusion/include/as_vector.hpp>
28 #include <boost/fusion/include/as_set.hpp>
29 #include <boost/fusion/container/set.hpp>
30 #include <boost/fusion/include/set.hpp>
31 #include <boost/fusion/include/set_fwd.hpp>
32 #include <boost/fusion/include/mpl.hpp>
33 #include <boost/fusion/sequence/intrinsic/at_key.hpp>
34 #include <boost/fusion/include/at_key.hpp>
35 #include <boost/fusion/algorithm/iteration/for_each.hpp>
36 #include <boost/fusion/include/for_each.hpp>
37
38 #include <boost/assert.hpp>
39 #include <boost/ref.hpp>
40 #include <boost/type_traits.hpp>
41 #include <boost/utility/enable_if.hpp>
42 #include <boost/type_traits/is_convertible.hpp>
43
44 #include <boost/bind.hpp>
45 #include <boost/function.hpp>
46 #ifndef BOOST_NO_RTTI
47 #include <boost/any.hpp>
48 #endif
49
50 #include <boost/serialization/base_object.hpp>
51
52 #include <boost/parameter.hpp>
53
54 #include <boost/msm/active_state_switching_policies.hpp>
55 #include <boost/msm/row_tags.hpp>
56 #include <boost/msm/msm_grammar.hpp>
57 #include <boost/msm/back/fold_to_list.hpp>
58 #include <boost/msm/back/metafunctions.hpp>
59 #include <boost/msm/back/history_policies.hpp>
60 #include <boost/msm/back/common_types.hpp>
61 #include <boost/msm/back/args.hpp>
62 #include <boost/msm/back/default_compile_policy.hpp>
63 #include <boost/msm/back/dispatch_table.hpp>
64 #include <boost/msm/back/no_fsm_check.hpp>
65 #include <boost/msm/back/queue_container_deque.hpp>
66
67 BOOST_MPL_HAS_XXX_TRAIT_DEF(accept_sig)
68 BOOST_MPL_HAS_XXX_TRAIT_DEF(no_automatic_create)
69 BOOST_MPL_HAS_XXX_TRAIT_DEF(non_forwarding_flag)
70 BOOST_MPL_HAS_XXX_TRAIT_DEF(direct_entry)
71 BOOST_MPL_HAS_XXX_TRAIT_DEF(initial_event)
72 BOOST_MPL_HAS_XXX_TRAIT_DEF(final_event)
73 BOOST_MPL_HAS_XXX_TRAIT_DEF(do_serialize)
74 BOOST_MPL_HAS_XXX_TRAIT_DEF(history_policy)
75 BOOST_MPL_HAS_XXX_TRAIT_DEF(fsm_check)
76 BOOST_MPL_HAS_XXX_TRAIT_DEF(compile_policy)
77 BOOST_MPL_HAS_XXX_TRAIT_DEF(queue_container_policy)
78 BOOST_MPL_HAS_XXX_TRAIT_DEF(using_declared_table)
79 BOOST_MPL_HAS_XXX_TRAIT_DEF(event_queue_before_deferred_queue)
80
81 #ifndef BOOST_MSM_CONSTRUCTOR_ARG_SIZE
82 #define BOOST_MSM_CONSTRUCTOR_ARG_SIZE 5 // default max number of arguments for constructors
83 #endif
84
85 namespace boost { namespace msm { namespace back
86 {
87 // event used internally for wrapping a direct entry
88 template <class StateType,class Event>
89 struct direct_entry_event
90 {
91     typedef int direct_entry;
92     typedef StateType active_state;
93     typedef Event contained_event;
94
95     direct_entry_event(Event const& evt):m_event(evt){}
96     Event const& m_event;
97 };
98
99 // This declares the statically-initialized dispatch_table instance.
100 template <class Fsm,class Stt, class Event,class CompilePolicy>
101 const boost::msm::back::dispatch_table<Fsm,Stt, Event,CompilePolicy>
102 dispatch_table<Fsm,Stt, Event,CompilePolicy>::instance;
103
104 BOOST_PARAMETER_TEMPLATE_KEYWORD(front_end)
105 BOOST_PARAMETER_TEMPLATE_KEYWORD(history_policy)
106 BOOST_PARAMETER_TEMPLATE_KEYWORD(compile_policy)
107 BOOST_PARAMETER_TEMPLATE_KEYWORD(fsm_check_policy)
108 BOOST_PARAMETER_TEMPLATE_KEYWORD(queue_container_policy)
109
110 typedef ::boost::parameter::parameters<
111     ::boost::parameter::required< ::boost::msm::back::tag::front_end >
112   , ::boost::parameter::optional<
113         ::boost::parameter::deduced< ::boost::msm::back::tag::history_policy>, has_history_policy< ::boost::mpl::_ >
114     >
115   , ::boost::parameter::optional<
116         ::boost::parameter::deduced< ::boost::msm::back::tag::compile_policy>, has_compile_policy< ::boost::mpl::_ >
117     >
118   , ::boost::parameter::optional<
119         ::boost::parameter::deduced< ::boost::msm::back::tag::fsm_check_policy>, has_fsm_check< ::boost::mpl::_ >
120     >
121   , ::boost::parameter::optional<
122         ::boost::parameter::deduced< ::boost::msm::back::tag::queue_container_policy>,
123         has_queue_container_policy< ::boost::mpl::_ >
124     >
125 > state_machine_signature;
126
127 // just here to disable use of proto when not needed
128 template <class T, class F,class Enable=void>
129 struct make_euml_terminal;
130 template <class T,class F>
131 struct make_euml_terminal<T,F,typename ::boost::disable_if<has_using_declared_table<F> >::type>
132 {};
133 template <class T,class F>
134 struct make_euml_terminal<T,F,typename ::boost::enable_if<has_using_declared_table<F> >::type>
135     : public proto::extends<typename proto::terminal< boost::msm::state_tag>::type, T, boost::msm::state_domain>
136 {};
137
138 // library-containing class for state machines.  Pass the actual FSM class as
139 // the Concrete parameter.
140 // A0=Derived,A1=NoHistory,A2=CompilePolicy,A3=FsmCheckPolicy >
141 template <
142       class A0
143     , class A1 = parameter::void_
144     , class A2 = parameter::void_
145     , class A3 = parameter::void_
146     , class A4 = parameter::void_
147 >
148 class state_machine : //public Derived
149     public ::boost::parameter::binding<
150             typename state_machine_signature::bind<A0,A1,A2,A3,A4>::type, ::boost::msm::back::tag::front_end
151     >::type
152     , public make_euml_terminal<state_machine<A0,A1,A2,A3,A4>,
153                          typename ::boost::parameter::binding<
154                                     typename state_machine_signature::bind<A0,A1,A2,A3,A4>::type, ::boost::msm::back::tag::front_end
155                          >::type
156       >
157 {
158 public:
159     // Create ArgumentPack
160     typedef typename
161         state_machine_signature::bind<A0,A1,A2,A3,A4>::type
162         state_machine_args;
163
164     // Extract first logical parameter.
165     typedef typename ::boost::parameter::binding<
166         state_machine_args, ::boost::msm::back::tag::front_end>::type Derived;
167
168     typedef typename ::boost::parameter::binding<
169         state_machine_args, ::boost::msm::back::tag::history_policy, NoHistory >::type              HistoryPolicy;
170
171     typedef typename ::boost::parameter::binding<
172         state_machine_args, ::boost::msm::back::tag::compile_policy, favor_runtime_speed >::type    CompilePolicy;
173
174     typedef typename ::boost::parameter::binding<
175         state_machine_args, ::boost::msm::back::tag::fsm_check_policy, no_fsm_check >::type         FsmCheckPolicy;
176
177     typedef typename ::boost::parameter::binding<
178         state_machine_args, ::boost::msm::back::tag::queue_container_policy,
179         queue_container_deque >::type                                                               QueueContainerPolicy;
180
181 private:
182
183     typedef boost::msm::back::state_machine<
184         A0,A1,A2,A3,A4>                             library_sm;
185
186     typedef ::boost::function<
187         execute_return ()>                          transition_fct;
188     typedef ::boost::function<
189         execute_return () >                         deferred_fct;
190     typedef typename QueueContainerPolicy::
191         template In<
192             std::pair<deferred_fct,char> >::type    deferred_events_queue_t;
193     typedef typename QueueContainerPolicy::
194         template In<transition_fct>::type           events_queue_t;
195
196     typedef typename boost::mpl::eval_if<
197         typename is_active_state_switch_policy<Derived>::type,
198         get_active_state_switch_policy<Derived>,
199         // default
200         ::boost::mpl::identity<active_state_switch_after_entry>
201     >::type active_state_switching;
202
203     typedef bool (*flag_handler)(library_sm const&);
204
205     // all state machines are friend with each other to allow embedding any of them in another fsm
206     template <class ,class , class, class, class
207     > friend class boost::msm::back::state_machine;
208
209     // helper to add, if needed, visitors to all states
210     // version without visitors
211     template <class StateType,class Enable=void>
212     struct visitor_fct_helper
213     {
214     public:
215         visitor_fct_helper(){}
216         void fill_visitors(int)
217         {
218         }
219         template <class FCT>
220         void insert(int,FCT)
221         {
222         }
223         template <class VISITOR>
224         void execute(int,VISITOR)
225         {
226         }
227     };
228     // version with visitors
229     template <class StateType>
230     struct visitor_fct_helper<StateType,typename ::boost::enable_if<has_accept_sig<StateType> >::type>
231     {
232     public:
233         visitor_fct_helper():m_state_visitors(){}
234         void fill_visitors(int number_of_states)
235         {
236             m_state_visitors.resize(number_of_states);
237         }
238         template <class FCT>
239         void insert(int index,FCT fct)
240         {
241             m_state_visitors[index]=fct;
242         }
243         void execute(int index)
244         {
245             m_state_visitors[index]();
246         }
247
248 #define MSM_VISITOR_HELPER_EXECUTE_SUB(z, n, unused) ARG ## n vis ## n
249 #define MSM_VISITOR_HELPER_EXECUTE(z, n, unused)                                    \
250         template <BOOST_PP_ENUM_PARAMS(n, class ARG)>                               \
251         void execute(int index BOOST_PP_COMMA_IF(n)                                 \
252                      BOOST_PP_ENUM(n, MSM_VISITOR_HELPER_EXECUTE_SUB, ~ ) )         \
253         {                                                                           \
254             m_state_visitors[index](BOOST_PP_ENUM_PARAMS(n,vis));                   \
255         }
256         BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_HELPER_EXECUTE, ~)
257 #undef MSM_VISITOR_HELPER_EXECUTE
258 #undef MSM_VISITOR_HELPER_EXECUTE_SUB
259     private:
260         typedef typename StateType::accept_sig::type                  visitor_fct;
261         typedef std::vector<visitor_fct>                              visitors;
262
263         visitors                                                      m_state_visitors;
264     };
265
266     template <class StateType,class Enable=int>
267     struct deferred_msg_queue_helper
268     {
269         void clear(){}
270     };
271     template <class StateType>
272     struct deferred_msg_queue_helper<StateType,
273         typename ::boost::enable_if<
274             typename ::boost::msm::back::has_fsm_deferred_events<StateType>::type,int >::type>
275     {
276     public:
277         deferred_msg_queue_helper():m_deferred_events_queue(),m_cur_seq(0){}
278         void clear()
279         {
280             m_deferred_events_queue.clear();
281         }
282         deferred_events_queue_t         m_deferred_events_queue;
283         char m_cur_seq;
284     };
285
286  public:
287     // tags
288     typedef int composite_tag;
289
290     // in case someone needs to know
291     typedef HistoryPolicy               history_policy;
292
293     struct InitEvent { };
294     struct ExitEvent { };
295     // flag handling
296     struct Flag_AND
297     {
298         typedef std::logical_and<bool> type;
299     };
300     struct Flag_OR
301     {
302      typedef std::logical_or<bool> type;
303     };
304     typedef typename Derived::BaseAllStates     BaseState;
305     typedef Derived                             ConcreteSM;
306
307     // if the front-end fsm provides an initial_event typedef, replace InitEvent by this one
308     typedef typename ::boost::mpl::eval_if<
309         typename has_initial_event<Derived>::type,
310         get_initial_event<Derived>,
311         ::boost::mpl::identity<InitEvent>
312     >::type fsm_initial_event;
313
314     // if the front-end fsm provides an exit_event typedef, replace ExitEvent by this one
315     typedef typename ::boost::mpl::eval_if<
316         typename has_final_event<Derived>::type,
317         get_final_event<Derived>,
318         ::boost::mpl::identity<ExitEvent>
319     >::type fsm_final_event;
320
321     template <class ExitPoint>
322     struct exit_pt : public ExitPoint
323     {
324         // tags
325         typedef ExitPoint           wrapped_exit;
326         typedef int                 pseudo_exit;
327         typedef library_sm          owner;
328         typedef int                 no_automatic_create;
329         typedef typename
330             ExitPoint::event        Event;
331         typedef ::boost::function<execute_return (Event const&)>
332                                     forwarding_function;
333
334         // forward event to the higher-level FSM
335         template <class ForwardEvent>
336         void forward_event(ForwardEvent const& incomingEvent)
337         {
338             // use helper to forward or not
339             ForwardHelper< ::boost::is_convertible<ForwardEvent,Event>::value>::helper(incomingEvent,m_forward);
340         }
341         void set_forward_fct(::boost::function<execute_return (Event const&)> fct)
342         {
343             m_forward = fct;
344         }
345         exit_pt():m_forward(){}
346         // by assignments, we keep our forwarding functor unchanged as our containing SM did not change
347     template <class RHS>
348         exit_pt(RHS&):m_forward(){}
349         exit_pt<ExitPoint>& operator= (const exit_pt<ExitPoint>& )
350         {
351             return *this;
352         }
353     private:
354          forwarding_function          m_forward;
355
356          // using partial specialization instead of enable_if because of VC8 bug
357         template <bool OwnEvent, int Dummy=0>
358         struct ForwardHelper
359         {
360             template <class ForwardEvent>
361             static void helper(ForwardEvent const& ,forwarding_function& )
362             {
363                 // Not our event, assert
364                 BOOST_ASSERT(false);
365             }
366         };
367         template <int Dummy>
368         struct ForwardHelper<true,Dummy>
369         {
370             template <class ForwardEvent>
371             static void helper(ForwardEvent const& incomingEvent,forwarding_function& forward_fct)
372             {
373                 // call if handler set, if not, this state is simply a terminate state
374                 if (forward_fct)
375                     forward_fct(incomingEvent);
376             }
377         };
378
379     };
380     template <class EntryPoint>
381     struct entry_pt : public EntryPoint
382     {
383         // tags
384         typedef EntryPoint          wrapped_entry;
385         typedef int                 pseudo_entry;
386         typedef library_sm          owner;
387         typedef int                 no_automatic_create;
388     };
389     template <class EntryPoint>
390     struct direct : public EntryPoint
391     {
392         // tags
393         typedef EntryPoint          wrapped_entry;
394         typedef int                 explicit_entry_state;
395         typedef library_sm          owner;
396         typedef int                 no_automatic_create;
397     };
398     typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
399     // Template used to form rows in the transition table
400     template<
401         typename ROW
402     >
403     struct row_
404     {
405         //typedef typename ROW::Source T1;
406         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
407         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
408         typedef typename ROW::Evt transition_event;
409         // if the source is an exit pseudo state, then
410         // current_state_type becomes the result of get_owner
411         // meaning the containing SM from which the exit occurs
412         typedef typename ::boost::mpl::eval_if<
413                 typename has_pseudo_exit<T1>::type,
414                 get_owner<T1,library_sm>,
415                 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
416
417         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
418         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
419         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
420         typedef typename ::boost::mpl::eval_if<
421             typename ::boost::mpl::is_sequence<T2>::type,
422             get_fork_owner<T2,library_sm>,
423             ::boost::mpl::eval_if<
424                     typename has_no_automatic_create<T2>::type,
425                     get_owner<T2,library_sm>,
426                     ::boost::mpl::identity<T2> >
427         >::type next_state_type;
428
429         // if a guard condition is here, call it to check that the event is accepted
430         static bool check_guard(library_sm& fsm,transition_event const& evt)
431         {
432             if ( ROW::guard_call(fsm,evt,
433                                  ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
434                                  ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
435                                  fsm.m_substate_list ) )
436                 return true;
437             return false;
438         }
439         // Take the transition action and return the next state.
440         static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
441         {
442
443             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
444             BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
445             BOOST_ASSERT(state == (current_state));
446             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
447             if (has_pseudo_exit<T1>::type::value &&
448                 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
449             {
450                 return HANDLED_FALSE;
451             }
452             if (!check_guard(fsm,evt))
453             {
454                 // guard rejected the event, we stay in the current one
455                 return HANDLED_GUARD_REJECT;
456             }
457             fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
458
459             // the guard condition has already been checked
460             execute_exit<current_state_type>
461                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
462             fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
463
464             // then call the action method
465             HandledEnum res = ROW::action_call(fsm,evt,
466                              ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
467                              ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
468                              fsm.m_substate_list);
469             fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
470
471             // and finally the entry method of the new current state
472             convert_event_and_execute_entry<next_state_type,T2>
473                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
474             fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
475             return res;
476         }
477     };
478
479     // row having only a guard condition
480     template<
481         typename ROW
482     >
483     struct g_row_
484     {
485         //typedef typename ROW::Source T1;
486         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
487         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
488         typedef typename ROW::Evt transition_event;
489         // if the source is an exit pseudo state, then
490         // current_state_type becomes the result of get_owner
491         // meaning the containing SM from which the exit occurs
492         typedef typename ::boost::mpl::eval_if<
493                 typename has_pseudo_exit<T1>::type,
494                 get_owner<T1,library_sm>,
495                 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
496
497         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
498         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
499         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
500         typedef typename ::boost::mpl::eval_if<
501             typename ::boost::mpl::is_sequence<T2>::type,
502             get_fork_owner<T2,library_sm>,
503             ::boost::mpl::eval_if<
504                     typename has_no_automatic_create<T2>::type,
505                     get_owner<T2,library_sm>,
506                     ::boost::mpl::identity<T2> >
507         >::type next_state_type;
508
509         // if a guard condition is defined, call it to check that the event is accepted
510         static bool check_guard(library_sm& fsm,transition_event const& evt)
511         {
512             if ( ROW::guard_call(fsm,evt,
513                                  ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
514                                  ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
515                                  fsm.m_substate_list ))
516                 return true;
517             return false;
518         }
519         // Take the transition action and return the next state.
520         static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
521         {
522             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
523             BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
524             BOOST_ASSERT(state == (current_state));
525             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
526             if (has_pseudo_exit<T1>::type::value &&
527                 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
528             {
529                 return HANDLED_FALSE;
530             }
531             if (!check_guard(fsm,evt))
532             {
533                 // guard rejected the event, we stay in the current one
534                 return HANDLED_GUARD_REJECT;
535             }
536             fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
537
538             // the guard condition has already been checked
539             execute_exit<current_state_type>
540                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
541             fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
542             fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
543
544             // and finally the entry method of the new current state
545             convert_event_and_execute_entry<next_state_type,T2>
546                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
547             fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
548             return HANDLED_TRUE;
549         }
550     };
551
552     // row having only an action method
553     template<
554         typename ROW
555     >
556     struct a_row_
557     {
558         //typedef typename ROW::Source T1;
559         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
560         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
561         typedef typename ROW::Evt transition_event;
562         // if the source is an exit pseudo state, then
563         // current_state_type becomes the result of get_owner
564         // meaning the containing SM from which the exit occurs
565         typedef typename ::boost::mpl::eval_if<
566                 typename has_pseudo_exit<T1>::type,
567                 get_owner<T1,library_sm>,
568                 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
569
570         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
571         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
572         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
573         typedef typename ::boost::mpl::eval_if<
574             typename ::boost::mpl::is_sequence<T2>::type,
575             get_fork_owner<T2,library_sm>,
576             ::boost::mpl::eval_if<
577                     typename has_no_automatic_create<T2>::type,
578                     get_owner<T2,library_sm>,
579                     ::boost::mpl::identity<T2> >
580         >::type next_state_type;
581
582         // Take the transition action and return the next state.
583         static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
584         {
585             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
586             BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
587             BOOST_ASSERT(state == (current_state));
588
589             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
590             if (has_pseudo_exit<T1>::type::value &&
591                 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
592             {
593                 return HANDLED_FALSE;
594             }
595             fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
596
597             // no need to check the guard condition
598             // first call the exit method of the current state
599             execute_exit<current_state_type>
600                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
601             fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
602
603             // then call the action method
604             HandledEnum res = ROW::action_call(fsm,evt,
605                             ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
606                             ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
607                             fsm.m_substate_list);
608             fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
609
610             // and finally the entry method of the new current state
611             convert_event_and_execute_entry<next_state_type,T2>
612                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
613             fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
614             return res;
615         }
616     };
617
618     // row having no guard condition or action, simply transitions
619     template<
620         typename ROW
621     >
622     struct _row_
623     {
624         //typedef typename ROW::Source T1;
625         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
626         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
627         typedef typename ROW::Evt transition_event;
628         // if the source is an exit pseudo state, then
629         // current_state_type becomes the result of get_owner
630         // meaning the containing SM from which the exit occurs
631         typedef typename ::boost::mpl::eval_if<
632                 typename has_pseudo_exit<T1>::type,
633                 get_owner<T1,library_sm>,
634                 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
635
636         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
637         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
638         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
639         typedef typename ::boost::mpl::eval_if<
640             typename ::boost::mpl::is_sequence<T2>::type,
641             get_fork_owner<T2,library_sm>,
642             ::boost::mpl::eval_if<
643                     typename has_no_automatic_create<T2>::type,
644                     get_owner<T2,library_sm>,
645                     ::boost::mpl::identity<T2> >
646         >::type next_state_type;
647
648         // Take the transition action and return the next state.
649         static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
650         {
651             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
652             BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
653             BOOST_ASSERT(state == (current_state));
654
655             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
656             if (has_pseudo_exit<T1>::type::value &&
657                 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
658             {
659                 return HANDLED_FALSE;
660             }
661             fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
662
663             // first call the exit method of the current state
664             execute_exit<current_state_type>
665                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
666             fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
667             fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
668
669
670             // and finally the entry method of the new current state
671             convert_event_and_execute_entry<next_state_type,T2>
672                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
673             fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
674             return HANDLED_TRUE;
675         }
676     };
677     // "i" rows are rows for internal transitions
678     template<
679         typename ROW
680     >
681     struct irow_
682     {
683         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
684         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
685         typedef typename ROW::Evt transition_event;
686         typedef typename ROW::Source current_state_type;
687         typedef T2 next_state_type;
688
689         // if a guard condition is here, call it to check that the event is accepted
690         static bool check_guard(library_sm& fsm,transition_event const& evt)
691         {
692             if ( ROW::guard_call(fsm,evt,
693                                  ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
694                                  ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
695                                  fsm.m_substate_list))
696                 return true;
697             return false;
698         }
699         // Take the transition action and return the next state.
700         static HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
701         {
702
703             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
704             BOOST_ASSERT(state == (current_state));
705             if (!check_guard(fsm,evt))
706             {
707                 // guard rejected the event, we stay in the current one
708                 return HANDLED_GUARD_REJECT;
709             }
710
711             // call the action method
712             HandledEnum res = ROW::action_call(fsm,evt,
713                              ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
714                              ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
715                              fsm.m_substate_list);
716             return res;
717         }
718     };
719
720     // row having only a guard condition
721     template<
722         typename ROW
723     >
724     struct g_irow_
725     {
726         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
727         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
728         typedef typename ROW::Evt transition_event;
729         typedef typename ROW::Source current_state_type;
730         typedef T2 next_state_type;
731
732         // if a guard condition is defined, call it to check that the event is accepted
733         static bool check_guard(library_sm& fsm,transition_event const& evt)
734         {
735             if ( ROW::guard_call(fsm,evt,
736                                  ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
737                                  ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
738                                  fsm.m_substate_list) )
739                 return true;
740             return false;
741         }
742         // Take the transition action and return the next state.
743         static HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
744         {
745             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
746             BOOST_ASSERT(state == (current_state));
747             if (!check_guard(fsm,evt))
748             {
749                 // guard rejected the event, we stay in the current one
750                 return HANDLED_GUARD_REJECT;
751             }
752             return HANDLED_TRUE;
753         }
754     };
755
756     // row having only an action method
757     template<
758         typename ROW
759     >
760     struct a_irow_
761     {
762         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
763         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
764
765         typedef typename ROW::Evt transition_event;
766         typedef typename ROW::Source current_state_type;
767         typedef T2 next_state_type;
768
769         // Take the transition action and return the next state.
770         static HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
771         {
772             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
773             BOOST_ASSERT(state == (current_state));
774
775             // call the action method
776             HandledEnum res = ROW::action_call(fsm,evt,
777                             ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
778                             ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
779                             fsm.m_substate_list);
780
781             return res;
782         }
783     };
784     // row simply ignoring the event
785     template<
786         typename ROW
787     >
788     struct _irow_
789     {
790         typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
791         typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
792         typedef typename ROW::Evt transition_event;
793         typedef typename ROW::Source current_state_type;
794         typedef T2 next_state_type;
795
796         // Take the transition action and return the next state.
797         static HandledEnum execute(library_sm& , int , int state, transition_event const& )
798         {
799             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
800             BOOST_ASSERT(state == (current_state));
801             return HANDLED_TRUE;
802         }
803     };
804     // transitions internal to this state machine (no substate involved)
805     template<
806         typename ROW,
807         typename StateType
808     >
809     struct internal_
810     {
811         typedef StateType current_state_type;
812         typedef StateType next_state_type;
813         typedef typename ROW::Evt transition_event;
814
815         // if a guard condition is here, call it to check that the event is accepted
816         static bool check_guard(library_sm& fsm,transition_event const& evt)
817         {
818             if ( ROW::guard_call(fsm,evt,
819                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
820                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
821                 fsm.m_substate_list) )
822                 return true;
823             return false;
824         }
825         // Take the transition action and return the next state.
826         static HandledEnum execute(library_sm& fsm, int , int , transition_event const& evt)
827         {
828             if (!check_guard(fsm,evt))
829             {
830                 // guard rejected the event, we stay in the current one
831                 return HANDLED_GUARD_REJECT;
832             }
833
834             // then call the action method
835             HandledEnum res = ROW::action_call(fsm,evt,
836                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
837                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
838                 fsm.m_substate_list);
839             return res;
840         }
841     };
842     template<
843         typename ROW
844     >
845     struct internal_ <ROW,library_sm>
846     {
847         typedef library_sm current_state_type;
848         typedef library_sm next_state_type;
849         typedef typename ROW::Evt transition_event;
850
851         // if a guard condition is here, call it to check that the event is accepted
852         static bool check_guard(library_sm& fsm,transition_event const& evt)
853         {
854             if ( ROW::guard_call(fsm,evt,
855                 fsm,
856                 fsm,
857                 fsm.m_substate_list) )
858                 return true;
859             return false;
860         }
861         // Take the transition action and return the next state.
862         static HandledEnum execute(library_sm& fsm, int , int , transition_event const& evt)
863         {
864             if (!check_guard(fsm,evt))
865             {
866                 // guard rejected the event, we stay in the current one
867                 return HANDLED_GUARD_REJECT;
868             }
869
870             // then call the action method
871             HandledEnum res = ROW::action_call(fsm,evt,
872                 fsm,
873                 fsm,
874                 fsm.m_substate_list);
875             return res;
876         }
877     };
878
879     template<
880         typename ROW,
881         typename StateType
882     >
883     struct a_internal_
884     {
885         typedef StateType current_state_type;
886         typedef StateType next_state_type;
887         typedef typename ROW::Evt transition_event;
888
889         // Take the transition action and return the next state.
890         static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
891         {
892             // then call the action method
893             HandledEnum res = ROW::action_call(fsm,evt,
894                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
895                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
896                 fsm.m_substate_list);
897             return res;
898         }
899     };
900     template<
901         typename ROW
902     >
903     struct a_internal_ <ROW,library_sm>
904     {
905         typedef library_sm current_state_type;
906         typedef library_sm next_state_type;
907         typedef typename ROW::Evt transition_event;
908
909         // Take the transition action and return the next state.
910         static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
911         {
912             // then call the action method
913             HandledEnum res = ROW::action_call(fsm,evt,
914                 fsm,
915                 fsm,
916                 fsm.m_substate_list);
917             return res;
918         }
919     };
920     template<
921         typename ROW,
922         typename StateType
923     >
924     struct g_internal_
925     {
926         typedef StateType current_state_type;
927         typedef StateType next_state_type;
928         typedef typename ROW::Evt transition_event;
929
930         // if a guard condition is here, call it to check that the event is accepted
931         static bool check_guard(library_sm& fsm,transition_event const& evt)
932         {
933             if ( ROW::guard_call(fsm,evt,
934                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
935                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
936                 fsm.m_substate_list) )
937                 return true;
938             return false;
939         }
940         // Take the transition action and return the next state.
941         static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
942         {
943             if (!check_guard(fsm,evt))
944             {
945                 // guard rejected the event, we stay in the current one
946                 return HANDLED_GUARD_REJECT;
947             }
948             return HANDLED_TRUE;
949         }
950     };
951     template<
952         typename ROW
953     >
954     struct g_internal_ <ROW,library_sm>
955     {
956         typedef library_sm current_state_type;
957         typedef library_sm next_state_type;
958         typedef typename ROW::Evt transition_event;
959
960         // if a guard condition is here, call it to check that the event is accepted
961         static bool check_guard(library_sm& fsm,transition_event const& evt)
962         {
963             if ( ROW::guard_call(fsm,evt,
964                 fsm,
965                 fsm,
966                 fsm.m_substate_list) )
967                 return true;
968             return false;
969         }
970         // Take the transition action and return the next state.
971         static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
972         {
973             if (!check_guard(fsm,evt))
974             {
975                 // guard rejected the event, we stay in the current one
976                 return HANDLED_GUARD_REJECT;
977             }
978             return HANDLED_TRUE;
979         }
980     };
981     template<
982         typename ROW,
983         typename StateType
984     >
985     struct _internal_
986     {
987         typedef StateType current_state_type;
988         typedef StateType next_state_type;
989         typedef typename ROW::Evt transition_event;
990         static HandledEnum execute(library_sm& , int , int , transition_event const& )
991         {
992             return HANDLED_TRUE;
993         }
994     };
995     template<
996         typename ROW
997     >
998     struct _internal_ <ROW,library_sm>
999     {
1000         typedef library_sm current_state_type;
1001         typedef library_sm next_state_type;
1002         typedef typename ROW::Evt transition_event;
1003         static HandledEnum execute(library_sm& , int , int , transition_event const& )
1004         {
1005             return HANDLED_TRUE;
1006         }
1007     };
1008     // Template used to form forwarding rows in the transition table for every row of a composite SM
1009     template<
1010         typename T1
1011         , class Evt
1012     >
1013     struct frow
1014     {
1015         typedef T1                  current_state_type;
1016         typedef T1                  next_state_type;
1017         typedef Evt                 transition_event;
1018         // tag to find out if a row is a forwarding row
1019         typedef int                 is_frow;
1020
1021         // Take the transition action and return the next state.
1022         static HandledEnum execute(library_sm& fsm, int region_index, int , transition_event const& evt)
1023         {
1024             // false as second parameter because this event is forwarded from outer fsm
1025             execute_return res =
1026                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list)).process_event_internal(evt);
1027             fsm.m_states[region_index]=get_state_id<stt,T1>::type::value;
1028             return res;
1029         }
1030         // helper metafunctions used by dispatch table and give the frow a new event
1031         // (used to avoid double entries in a table because of base events)
1032         template <class NewEvent>
1033         struct replace_event
1034         {
1035             typedef frow<T1,NewEvent> type;
1036         };
1037     };
1038
1039     template <class Tag, class Transition,class StateType>
1040     struct create_backend_stt
1041     {
1042     };
1043     template <class Transition,class StateType>
1044     struct create_backend_stt<g_row_tag,Transition,StateType>
1045     {
1046         typedef g_row_<Transition> type;
1047     };
1048     template <class Transition,class StateType>
1049     struct create_backend_stt<a_row_tag,Transition,StateType>
1050     {
1051         typedef a_row_<Transition> type;
1052     };
1053     template <class Transition,class StateType>
1054     struct create_backend_stt<_row_tag,Transition,StateType>
1055     {
1056         typedef _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     // internal transitions
1064     template <class Transition,class StateType>
1065     struct create_backend_stt<g_irow_tag,Transition,StateType>
1066     {
1067         typedef g_irow_<Transition> type;
1068     };
1069     template <class Transition,class StateType>
1070     struct create_backend_stt<a_irow_tag,Transition,StateType>
1071     {
1072         typedef a_irow_<Transition> type;
1073     };
1074     template <class Transition,class StateType>
1075     struct create_backend_stt<irow_tag,Transition,StateType>
1076     {
1077         typedef 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<sm_a_i_row_tag,Transition,StateType>
1086     {
1087         typedef a_internal_<Transition,StateType> type;
1088     };
1089     template <class Transition,class StateType>
1090     struct create_backend_stt<sm_g_i_row_tag,Transition,StateType>
1091     {
1092         typedef g_internal_<Transition,StateType> type;
1093     };
1094     template <class Transition,class StateType>
1095     struct create_backend_stt<sm_i_row_tag,Transition,StateType>
1096     {
1097         typedef 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=void>
1105     struct make_row_tag
1106     {
1107         typedef typename create_backend_stt<typename Transition::row_type_tag,Transition,StateType>::type type;
1108     };
1109
1110     // add to the stt the initial states which could be missing (if not being involved in a transition)
1111     template <class BaseType, class stt_simulated = typename BaseType::transition_table>
1112     struct create_real_stt
1113     {
1114         //typedef typename BaseType::transition_table stt_simulated;
1115         typedef typename ::boost::mpl::fold<
1116             stt_simulated,mpl::vector0<>,
1117             ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1118                                      make_row_tag< ::boost::mpl::placeholders::_2 , BaseType > >
1119         >::type type;
1120     };
1121
1122     template <class Table,class Intermediate,class StateType>
1123     struct add_forwarding_row_helper
1124     {
1125         typedef typename generate_event_set<Table>::type all_events;
1126         typedef typename ::boost::mpl::fold<
1127             all_events, Intermediate,
1128             ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1129             frow<StateType, ::boost::mpl::placeholders::_2> > >::type type;
1130     };
1131     // gets the transition table from a composite and make from it a forwarding row
1132     template <class StateType,class IsComposite>
1133     struct get_internal_transition_table
1134     {
1135         // first get the table of a composite
1136         typedef typename recursive_get_transition_table<StateType>::type original_table;
1137
1138         // we now look for the events the composite has in its internal transitions
1139         // the internal ones are searched recursively in sub-sub... states
1140         // we go recursively because our states can also have internal tables or substates etc.
1141         typedef typename recursive_get_internal_transition_table<StateType, ::boost::mpl::true_>::type recursive_istt;
1142         typedef typename ::boost::mpl::fold<
1143                     recursive_istt,::boost::mpl::vector0<>,
1144                     ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1145                                              make_row_tag< ::boost::mpl::placeholders::_2 , StateType> >
1146                 >::type recursive_istt_with_tag;
1147
1148         typedef typename ::boost::mpl::insert_range< original_table, typename ::boost::mpl::end<original_table>::type,
1149                                                      recursive_istt_with_tag>::type table_with_all_events;
1150
1151         // and add for every event a forwarding row
1152         typedef typename ::boost::mpl::eval_if<
1153                 typename CompilePolicy::add_forwarding_rows,
1154                 add_forwarding_row_helper<table_with_all_events,::boost::mpl::vector0<>,StateType>,
1155                 ::boost::mpl::identity< ::boost::mpl::vector0<> >
1156         >::type type;
1157     };
1158     template <class StateType>
1159     struct get_internal_transition_table<StateType, ::boost::mpl::false_ >
1160     {
1161         typedef typename create_real_stt<StateType, typename StateType::internal_transition_table >::type type;
1162     };
1163     // typedefs used internally
1164     typedef typename create_real_stt<Derived>::type real_transition_table;
1165     typedef typename create_stt<library_sm>::type stt;
1166     typedef typename get_initial_states<typename Derived::initial_state>::type initial_states;
1167     typedef typename generate_state_set<stt>::type state_list;
1168     typedef typename HistoryPolicy::template apply<nr_regions::value>::type concrete_history;
1169
1170     typedef typename ::boost::fusion::result_of::as_set<state_list>::type substate_list;
1171     typedef typename ::boost::msm::back::generate_event_set<
1172         typename create_real_stt<library_sm, typename library_sm::internal_transition_table >::type
1173     >::type processable_events_internal_table;
1174
1175     // extends the transition table with rows from composite states
1176     template <class Composite>
1177     struct extend_table
1178     {
1179         // add the init states
1180         //typedef typename create_stt<Composite>::type stt;
1181         typedef typename Composite::stt Stt;
1182
1183         // add the internal events defined in the internal_transition_table
1184         // Note: these are added first because they must have a lesser prio
1185         // than the deeper transitions in the sub regions
1186         // table made of a stt + internal transitions of composite
1187         typedef typename ::boost::mpl::fold<
1188             typename Composite::internal_transition_table,::boost::mpl::vector0<>,
1189             ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1190                                      make_row_tag< ::boost::mpl::placeholders::_2 , Composite> >
1191         >::type internal_stt;
1192
1193         typedef typename ::boost::mpl::insert_range<
1194             Stt,
1195             typename ::boost::mpl::end<Stt>::type,
1196             internal_stt
1197             //typename get_internal_transition_table<Composite, ::boost::mpl::true_ >::type
1198         >::type stt_plus_internal;
1199
1200         // for every state, add its transition table (if any)
1201         // transformed as frow
1202         typedef typename ::boost::mpl::fold<state_list,stt_plus_internal,
1203                 ::boost::mpl::insert_range<
1204                         ::boost::mpl::placeholders::_1,
1205                         ::boost::mpl::end< ::boost::mpl::placeholders::_1>,
1206                         get_internal_transition_table<
1207                                 ::boost::mpl::placeholders::_2,
1208                                 is_composite_state< ::boost::mpl::placeholders::_2> > >
1209         >::type type;
1210     };
1211     // extend the table with tables from composite states
1212     typedef typename extend_table<library_sm>::type complete_table;
1213      // build a sequence of regions
1214      typedef typename get_regions_as_sequence<typename Derived::initial_state>::type seq_initial_states;
1215     // Member functions
1216
1217     // start the state machine (calls entry of the initial state)
1218     void start()
1219     {
1220          // reinitialize our list of currently active states with the ones defined in Derived::initial_state
1221          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1222                         (init_states(m_states));
1223         // call on_entry on this SM
1224         (static_cast<Derived*>(this))->on_entry(fsm_initial_event(),*this);
1225         ::boost::mpl::for_each<initial_states, boost::msm::wrap<mpl::placeholders::_1> >
1226             (call_init<fsm_initial_event>(fsm_initial_event(),this));
1227         // give a chance to handle an anonymous (eventless) transition
1228         handle_eventless_transitions_helper<library_sm> eventless_helper(this,true);
1229         eventless_helper.process_completion_event();
1230     }
1231
1232     // start the state machine (calls entry of the initial state passing incomingEvent to on_entry's)
1233     template <class Event>
1234     void start(Event const& incomingEvent)
1235     {
1236         // reinitialize our list of currently active states with the ones defined in Derived::initial_state
1237         ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1238                         (init_states(m_states));
1239         // call on_entry on this SM
1240         (static_cast<Derived*>(this))->on_entry(incomingEvent,*this);
1241         ::boost::mpl::for_each<initial_states, boost::msm::wrap<mpl::placeholders::_1> >
1242             (call_init<Event>(incomingEvent,this));
1243         // give a chance to handle an anonymous (eventless) transition
1244         handle_eventless_transitions_helper<library_sm> eventless_helper(this,true);
1245         eventless_helper.process_completion_event();
1246     }
1247
1248     // stop the state machine (calls exit of the current state)
1249     void stop()
1250     {
1251         do_exit(fsm_final_event(),*this);
1252     }
1253
1254     // stop the state machine (calls exit of the current state passing finalEvent to on_exit's)
1255     template <class Event>
1256     void stop(Event const& finalEvent)
1257     {
1258         do_exit(finalEvent,*this);
1259     }
1260
1261     // Main function used by clients of the derived FSM to make transitions.
1262     template<class Event>
1263     execute_return process_event(Event const& evt)
1264     {
1265         return process_event_internal(evt, EVENT_SOURCE_DIRECT);
1266     }
1267
1268     template <class EventType>
1269     void enqueue_event_helper(EventType const& evt, ::boost::mpl::false_ const &)
1270     {
1271         execute_return (library_sm::*pf) (EventType const&, EventSource) =
1272             &library_sm::process_event_internal;
1273
1274         m_events_queue.m_events_queue.push_back(
1275             ::boost::bind(
1276                 pf, this, evt,
1277                 static_cast<EventSource>(EVENT_SOURCE_MSG_QUEUE)));
1278     }
1279     template <class EventType>
1280     void enqueue_event_helper(EventType const& , ::boost::mpl::true_ const &)
1281     {
1282         // no queue
1283     }
1284
1285     void execute_queued_events_helper(::boost::mpl::false_ const &)
1286     {
1287         while(!m_events_queue.m_events_queue.empty())
1288         {
1289             transition_fct to_call = m_events_queue.m_events_queue.front();
1290             m_events_queue.m_events_queue.pop_front();
1291             to_call();
1292         }
1293     }
1294     void execute_queued_events_helper(::boost::mpl::true_ const &)
1295     {
1296         // no queue required
1297     }
1298     void execute_single_queued_event_helper(::boost::mpl::false_ const &)
1299     {
1300         transition_fct to_call = m_events_queue.m_events_queue.front();
1301         m_events_queue.m_events_queue.pop_front();
1302         to_call();
1303     }
1304     void execute_single_queued_event_helper(::boost::mpl::true_ const &)
1305     {
1306         // no queue required
1307     }
1308     // enqueues an event in the message queue
1309     // call execute_queued_events to process all queued events.
1310     // Be careful if you do this during event processing, the event will be processed immediately
1311     // and not kept in the queue
1312     template <class EventType>
1313     void enqueue_event(EventType const& evt)
1314     {
1315         enqueue_event_helper<EventType>(evt, typename is_no_message_queue<library_sm>::type());
1316     }
1317
1318     // empty the queue and process events
1319     void execute_queued_events()
1320     {
1321         execute_queued_events_helper(typename is_no_message_queue<library_sm>::type());
1322     }
1323     void execute_single_queued_event()
1324     {
1325         execute_single_queued_event_helper(typename is_no_message_queue<library_sm>::type());
1326     }
1327     typename events_queue_t::size_type get_message_queue_size() const
1328     {
1329         return m_events_queue.m_events_queue.size();
1330     }
1331
1332     events_queue_t& get_message_queue()
1333     {
1334         return m_events_queue.m_events_queue;
1335     }
1336
1337     const events_queue_t& get_message_queue() const
1338     {
1339         return m_events_queue.m_events_queue;
1340     }
1341
1342     void clear_deferred_queue()
1343     {
1344         m_deferred_events_queue.clear();
1345     }
1346
1347     deferred_events_queue_t& get_deferred_queue()
1348     {
1349         return m_deferred_events_queue.m_deferred_events_queue;
1350     }
1351
1352     const deferred_events_queue_t& get_deferred_queue() const
1353     {
1354         return m_deferred_events_queue.m_deferred_events_queue;
1355     }
1356
1357     // Getter that returns the current state of the FSM
1358     const int* current_state() const
1359     {
1360         return this->m_states;
1361     }
1362
1363     template <class Archive>
1364     struct serialize_state
1365     {
1366         serialize_state(Archive& ar):ar_(ar){}
1367
1368         template<typename T>
1369         typename ::boost::enable_if<
1370             typename ::boost::mpl::or_<
1371                 typename has_do_serialize<T>::type,
1372                 typename is_composite_state<T>::type
1373             >::type
1374             ,void
1375         >::type
1376         operator()(T& t) const
1377         {
1378             ar_ & t;
1379         }
1380         template<typename T>
1381         typename ::boost::disable_if<
1382             typename ::boost::mpl::or_<
1383                 typename has_do_serialize<T>::type,
1384                 typename is_composite_state<T>::type
1385             >::type
1386             ,void
1387         >::type
1388         operator()(T&) const
1389         {
1390             // no state to serialize
1391         }
1392         Archive& ar_;
1393     };
1394
1395     template<class Archive>
1396     void serialize(Archive & ar, const unsigned int)
1397     {
1398         // invoke serialization of the base class
1399         (serialize_state<Archive>(ar))(boost::serialization::base_object<Derived>(*this));
1400         // now our attributes
1401         ar & m_states;
1402         // queues cannot be serialized => skip
1403         ar & m_history;
1404         ar & m_event_processing;
1405         ar & m_is_included;
1406         // visitors cannot be serialized => skip
1407         ::boost::fusion::for_each(m_substate_list, serialize_state<Archive>(ar));
1408     }
1409
1410     // linearly search for the state with the given id
1411     struct get_state_id_helper
1412     {
1413         get_state_id_helper(int id,const BaseState** res,const library_sm* self_):
1414         result_state(res),searched_id(id),self(self_) {}
1415
1416         template <class StateType>
1417         void operator()(boost::msm::wrap<StateType> const&)
1418         {
1419             // look for the state id until found
1420             BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,StateType>::value));
1421             if (!*result_state && (id == searched_id))
1422             {
1423                 *result_state = &::boost::fusion::at_key<StateType>(self->m_substate_list);
1424             }
1425         }
1426         const BaseState**  result_state;
1427         int                searched_id;
1428         const library_sm* self;
1429     };
1430     // return the state whose id is passed or 0 if not found
1431     // caution if you need this, you probably need polymorphic states
1432     // complexity: O(number of states)
1433     BaseState* get_state_by_id(int id)
1434     {
1435         const BaseState*  result_state=0;
1436         ::boost::mpl::for_each<state_list,
1437             ::boost::msm::wrap< ::boost::mpl::placeholders::_1> > (get_state_id_helper(id,&result_state,this));
1438         return const_cast<BaseState*>(result_state);
1439     }
1440     const BaseState* get_state_by_id(int id) const
1441     {
1442         const BaseState*  result_state=0;
1443         ::boost::mpl::for_each<state_list,
1444             ::boost::msm::wrap< ::boost::mpl::placeholders::_1> > (get_state_id_helper(id,&result_state,this));
1445         return result_state;
1446     }
1447     // true if the sm is used in another sm
1448     bool is_contained() const
1449     {
1450         return m_is_included;
1451     }
1452     // get the history policy class
1453     concrete_history& get_history()
1454     {
1455         return m_history;
1456     }
1457     concrete_history const& get_history() const
1458     {
1459         return m_history;
1460     }
1461     // get a state (const version)
1462     // as a pointer
1463     template <class State>
1464     typename ::boost::enable_if<typename ::boost::is_pointer<State>::type,State >::type
1465     get_state(::boost::msm::back::dummy<0> = 0) const
1466     {
1467         return const_cast<State >
1468             (&
1469                 (::boost::fusion::at_key<
1470                     typename ::boost::remove_const<typename ::boost::remove_pointer<State>::type>::type>(m_substate_list)));
1471     }
1472     // as a reference
1473     template <class State>
1474     typename ::boost::enable_if<typename ::boost::is_reference<State>::type,State >::type
1475     get_state(::boost::msm::back::dummy<1> = 0) const
1476     {
1477         return const_cast<State >
1478             ( ::boost::fusion::at_key<
1479                 typename ::boost::remove_const<typename ::boost::remove_reference<State>::type>::type>(m_substate_list) );
1480     }
1481     // get a state (non const version)
1482     // as a pointer
1483     template <class State>
1484     typename ::boost::enable_if<typename ::boost::is_pointer<State>::type,State >::type
1485     get_state(::boost::msm::back::dummy<0> = 0)
1486     {
1487         return &(static_cast<typename boost::add_reference<typename ::boost::remove_pointer<State>::type>::type >
1488         (::boost::fusion::at_key<typename ::boost::remove_pointer<State>::type>(m_substate_list)));
1489     }
1490     // as a reference
1491     template <class State>
1492     typename ::boost::enable_if<typename ::boost::is_reference<State>::type,State >::type
1493     get_state(::boost::msm::back::dummy<1> = 0)
1494     {
1495         return ::boost::fusion::at_key<typename ::boost::remove_reference<State>::type>(m_substate_list);
1496     }
1497     // checks if a flag is active using the BinaryOp as folding function
1498     template <class Flag,class BinaryOp>
1499     bool is_flag_active() const
1500     {
1501         flag_handler* flags_entries = get_entries_for_flag<Flag>();
1502         bool res = (*flags_entries[ m_states[0] ])(*this);
1503         for (int i = 1; i < nr_regions::value ; ++i)
1504         {
1505             res = typename BinaryOp::type() (res,(*flags_entries[ m_states[i] ])(*this));
1506         }
1507         return res;
1508     }
1509     // checks if a flag is active using no binary op if 1 region, or OR if > 1 regions
1510     template <class Flag>
1511     bool is_flag_active() const
1512     {
1513         return FlagHelper<Flag,(nr_regions::value>1)>::helper(*this,get_entries_for_flag<Flag>());
1514     }
1515     // visit the currently active states (if these are defined as visitable
1516     // by implementing accept)
1517     void visit_current_states()
1518     {
1519         for (int i=0; i<nr_regions::value;++i)
1520         {
1521             m_visitors.execute(m_states[i]);
1522         }
1523     }
1524 #define MSM_VISIT_STATE_SUB(z, n, unused) ARG ## n vis ## n
1525 #define MSM_VISIT_STATE_EXECUTE(z, n, unused)                                    \
1526         template <BOOST_PP_ENUM_PARAMS(n, class ARG)>                               \
1527         void visit_current_states(BOOST_PP_ENUM(n, MSM_VISIT_STATE_SUB, ~ ) )         \
1528         {                                                                           \
1529             for (int i=0; i<nr_regions::value;++i)                                                      \
1530             {                                                                                           \
1531                 m_visitors.execute(m_states[i],BOOST_PP_ENUM_PARAMS(n,vis));                            \
1532             }                                                                                           \
1533         }
1534         BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISIT_STATE_EXECUTE, ~)
1535 #undef MSM_VISIT_STATE_EXECUTE
1536 #undef MSM_VISIT_STATE_SUB
1537
1538     // puts the given event into the deferred queue
1539     template <class Event>
1540     void defer_event(Event const& e)
1541     {
1542         // to call this function, you need either a state with a deferred_events typedef
1543         // or that the fsm provides the activate_deferred_events typedef
1544         BOOST_MPL_ASSERT(( has_fsm_deferred_events<library_sm> ));
1545         execute_return (library_sm::*pf) (Event const&, EventSource) =
1546             &library_sm::process_event_internal;
1547
1548         // Deferred events are added with a correlation sequence that helps to
1549         // identify when an event was added - This is typically to distinguish
1550         // between events deferred in this processing versus previous.
1551         m_deferred_events_queue.m_deferred_events_queue.push_back(
1552             std::make_pair(
1553                 ::boost::bind(
1554                     pf, this, e, static_cast<EventSource>(EVENT_SOURCE_DIRECT|EVENT_SOURCE_DEFERRED)),
1555                 static_cast<char>(m_deferred_events_queue.m_cur_seq+1)));
1556     }
1557
1558  protected:    // interface for the derived class
1559
1560      // helper used to fill the initial states
1561      struct init_states
1562      {
1563          init_states(int* const init):m_initial_states(init),m_index(-1){}
1564
1565          // History initializer function object, used with mpl::for_each
1566          template <class State>
1567          void operator()(::boost::msm::wrap<State> const&)
1568          {
1569              m_initial_states[++m_index]=get_state_id<stt,State>::type::value;
1570          }
1571          int* const m_initial_states;
1572          int m_index;
1573      };
1574  public:
1575      struct update_state
1576      {
1577          update_state(substate_list& to_overwrite_):to_overwrite(&to_overwrite_){}
1578          template<typename StateType>
1579          void operator()(StateType const& astate) const
1580          {
1581              ::boost::fusion::at_key<StateType>(*to_overwrite)=astate;
1582          }
1583          substate_list* to_overwrite;
1584      };
1585      template <class Expr>
1586      void set_states(Expr const& expr)
1587      {
1588          ::boost::fusion::for_each(
1589              ::boost::fusion::as_vector(FoldToList()(expr, boost::fusion::nil_())),update_state(this->m_substate_list));
1590      }
1591
1592      // Construct with the default initial states
1593      state_machine<A0,A1,A2,A3,A4 >()
1594          :Derived()
1595          ,m_events_queue()
1596          ,m_deferred_events_queue()
1597          ,m_history()
1598          ,m_event_processing(false)
1599          ,m_is_included(false)
1600          ,m_visitors()
1601          ,m_substate_list()
1602      {
1603          // initialize our list of states with the ones defined in Derived::initial_state
1604          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1605                         (init_states(m_states));
1606          m_history.set_initial_states(m_states);
1607          // create states
1608          fill_states(this);
1609      }
1610      template <class Expr>
1611      state_machine<A0,A1,A2,A3,A4 >
1612          (Expr const& expr,typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type* =0)
1613          :Derived()
1614          ,m_events_queue()
1615          ,m_deferred_events_queue()
1616          ,m_history()
1617          ,m_event_processing(false)
1618          ,m_is_included(false)
1619          ,m_visitors()
1620          ,m_substate_list()
1621      {
1622          BOOST_MPL_ASSERT_MSG(
1623              ( ::boost::proto::matches<Expr, FoldToList>::value),
1624              THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR,
1625              (FoldToList));
1626
1627          // initialize our list of states with the ones defined in Derived::initial_state
1628          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1629                         (init_states(m_states));
1630          m_history.set_initial_states(m_states);
1631          // create states
1632          set_states(expr);
1633          fill_states(this);
1634      }
1635      // Construct with the default initial states and some default argument(s)
1636 #if defined (BOOST_NO_CXX11_RVALUE_REFERENCES)                                      \
1637     || defined (BOOST_NO_CXX11_VARIADIC_TEMPLATES)                                  \
1638     || defined (BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
1639 #define MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB(z, n, unused) ARG ## n t ## n
1640 #define MSM_CONSTRUCTOR_HELPER_EXECUTE(z, n, unused)                                \
1641         template <BOOST_PP_ENUM_PARAMS(n, class ARG)>                               \
1642         state_machine<A0,A1,A2,A3,A4                                                \
1643         >(BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ),                 \
1644         typename ::boost::disable_if<typename ::boost::proto::is_expr<ARG0>::type >::type* =0 )                \
1645         :Derived(BOOST_PP_ENUM_PARAMS(n,t))                                         \
1646          ,m_events_queue()                                                          \
1647          ,m_deferred_events_queue()                                                 \
1648          ,m_history()                                                               \
1649          ,m_event_processing(false)                                                 \
1650          ,m_is_included(false)                                                      \
1651          ,m_visitors()                                                              \
1652          ,m_substate_list()                                                         \
1653      {                                                                              \
1654          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> > \
1655                         (init_states(m_states));                                    \
1656          m_history.set_initial_states(m_states);                                    \
1657          fill_states(this);                                                         \
1658      }                                                                              \
1659         template <class Expr,BOOST_PP_ENUM_PARAMS(n, class ARG)>                    \
1660         state_machine<A0,A1,A2,A3,A4                                                \
1661         >(Expr const& expr,BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ), \
1662         typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type* =0 ) \
1663         :Derived(BOOST_PP_ENUM_PARAMS(n,t))                                         \
1664          ,m_events_queue()                                                          \
1665          ,m_deferred_events_queue()                                                 \
1666          ,m_history()                                                               \
1667          ,m_event_processing(false)                                                 \
1668          ,m_is_included(false)                                                      \
1669          ,m_visitors()                                                              \
1670          ,m_substate_list()                                                         \
1671      {                                                                              \
1672          BOOST_MPL_ASSERT_MSG(                                                      \
1673          ( ::boost::proto::matches<Expr, FoldToList>::value),                       \
1674              THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR,                   \
1675              (FoldToList));                                                         \
1676          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> > \
1677                         (init_states(m_states));                                    \
1678          m_history.set_initial_states(m_states);                                    \
1679          set_states(expr);                                                          \
1680          fill_states(this);                                                         \
1681      }
1682
1683      BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_CONSTRUCTOR_ARG_SIZE,1), MSM_CONSTRUCTOR_HELPER_EXECUTE, ~)
1684 #undef MSM_CONSTRUCTOR_HELPER_EXECUTE
1685 #undef MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB
1686
1687 #else
1688     template <class ARG0,class... ARG,class=typename ::boost::disable_if<typename ::boost::proto::is_expr<ARG0>::type >::type>
1689     state_machine<A0,A1,A2,A3,A4
1690     >(ARG0&& t0,ARG&&... t)
1691     :Derived(std::forward<ARG0>(t0), std::forward<ARG>(t)...)
1692      ,m_events_queue()
1693      ,m_deferred_events_queue()
1694      ,m_history()
1695      ,m_event_processing(false)
1696      ,m_is_included(false)
1697      ,m_visitors()
1698      ,m_substate_list()
1699      {
1700          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1701                         (init_states(m_states));
1702          m_history.set_initial_states(m_states);
1703          fill_states(this);
1704      }
1705     template <class Expr,class... ARG,class=typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type>
1706     state_machine<A0,A1,A2,A3,A4
1707     >(Expr const& expr,ARG&&... t)
1708     :Derived(std::forward<ARG>(t)...)
1709      ,m_events_queue()
1710      ,m_deferred_events_queue()
1711      ,m_history()
1712      ,m_event_processing(false)
1713      ,m_is_included(false)
1714      ,m_visitors()
1715      ,m_substate_list()
1716      {
1717          BOOST_MPL_ASSERT_MSG(
1718          ( ::boost::proto::matches<Expr, FoldToList>::value),
1719              THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR,
1720              (FoldToList));
1721          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1722                         (init_states(m_states));
1723          m_history.set_initial_states(m_states);
1724          set_states(expr);
1725          fill_states(this);
1726      }
1727 #endif
1728
1729
1730      // assignment operator using the copy policy to decide if non_copyable, shallow or deep copying is necessary
1731      library_sm& operator= (library_sm const& rhs)
1732      {
1733          if (this != &rhs)
1734          {
1735             Derived::operator=(rhs);
1736             do_copy(rhs);
1737          }
1738         return *this;
1739      }
1740      state_machine<A0,A1,A2,A3,A4>
1741          (library_sm const& rhs)
1742          : Derived(rhs)
1743      {
1744         if (this != &rhs)
1745         {
1746             // initialize our list of states with the ones defined in Derived::initial_state
1747             fill_states(this);
1748             do_copy(rhs);
1749         }
1750      }
1751
1752     // the following 2 functions handle the terminate/interrupt states handling
1753     // if one of these states is found, the first one is used
1754     template <class Event>
1755     bool is_event_handling_blocked_helper( ::boost::mpl::true_ const &)
1756     {
1757         // if the state machine is terminated, do not handle any event
1758         if (is_flag_active< ::boost::msm::TerminateFlag>())
1759             return true;
1760         // if the state machine is interrupted, do not handle any event
1761         // unless the event is the end interrupt event
1762         if ( is_flag_active< ::boost::msm::InterruptedFlag>() &&
1763             !is_flag_active< ::boost::msm::EndInterruptFlag<Event> >())
1764             return true;
1765         return false;
1766     }
1767     // otherwise simple handling, no flag => continue
1768     template <class Event>
1769     bool is_event_handling_blocked_helper( ::boost::mpl::false_ const &)
1770     {
1771         // no terminate/interrupt states detected
1772         return false;
1773     }
1774     void do_handle_prio_msg_queue_deferred_queue(EventSource source, HandledEnum handled, ::boost::mpl::true_ const &)
1775     {
1776         // non-default. Handle msg queue with higher prio than deferred queue
1777         if (!(EVENT_SOURCE_MSG_QUEUE & source))
1778         {
1779             do_post_msg_queue_helper(
1780                 ::boost::mpl::bool_<
1781                     is_no_message_queue<library_sm>::type::value>());
1782             if (!(EVENT_SOURCE_DEFERRED & source))
1783             {
1784                 handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue);
1785                 defer_helper.do_handle_deferred(HANDLED_TRUE & handled);
1786             }
1787         }
1788     }
1789     void do_handle_prio_msg_queue_deferred_queue(EventSource source, HandledEnum handled, ::boost::mpl::false_ const &)
1790     {
1791         // default. Handle deferred queue with higher prio than msg queue
1792         if (!(EVENT_SOURCE_DEFERRED & source))
1793         {
1794             handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue);
1795             defer_helper.do_handle_deferred(HANDLED_TRUE & handled);
1796
1797             // Handle any new events generated into the queue, but only if
1798             // we're not already processing from the message queue.
1799             if (!(EVENT_SOURCE_MSG_QUEUE & source))
1800             {
1801                 do_post_msg_queue_helper(
1802                     ::boost::mpl::bool_<
1803                         is_no_message_queue<library_sm>::type::value>());
1804             }
1805         }
1806     }
1807     // the following functions handle pre/post-process handling  of a message queue
1808     template <class StateType,class EventType>
1809     bool do_pre_msg_queue_helper(EventType const&, ::boost::mpl::true_ const &)
1810     {
1811         // no message queue needed
1812         return true;
1813     }
1814     template <class StateType,class EventType>
1815     bool do_pre_msg_queue_helper(EventType const& evt, ::boost::mpl::false_ const &)
1816     {
1817         execute_return (library_sm::*pf) (EventType const&, EventSource) =
1818             &library_sm::process_event_internal;
1819
1820         // if we are already processing an event
1821         if (m_event_processing)
1822         {
1823             // event has to be put into the queue
1824             m_events_queue.m_events_queue.push_back(
1825                 ::boost::bind(
1826                     pf, this, evt,
1827                     static_cast<EventSource>(EVENT_SOURCE_DIRECT | EVENT_SOURCE_MSG_QUEUE)));
1828
1829             return false;
1830         }
1831
1832         // event can be handled, processing
1833         m_event_processing = true;
1834         return true;
1835     }
1836     void do_post_msg_queue_helper( ::boost::mpl::true_ const &)
1837     {
1838         // no message queue needed
1839     }
1840     void do_post_msg_queue_helper( ::boost::mpl::false_ const &)
1841     {
1842         process_message_queue(this);
1843     }
1844     void do_allow_event_processing_after_transition( ::boost::mpl::true_ const &)
1845     {
1846         // no message queue needed
1847     }
1848     void do_allow_event_processing_after_transition( ::boost::mpl::false_ const &)
1849     {
1850         m_event_processing = false;
1851     }
1852     // the following 2 functions handle the processing either with a try/catch protection or without
1853     template <class StateType,class EventType>
1854     HandledEnum do_process_helper(EventType const& evt, ::boost::mpl::true_ const &, bool is_direct_call)
1855     {
1856         return this->do_process_event(evt,is_direct_call);
1857     }
1858     template <class StateType,class EventType>
1859     HandledEnum do_process_helper(EventType const& evt, ::boost::mpl::false_ const &, bool is_direct_call)
1860     {
1861         // when compiling without exception support there is no formal parameter "e" in the catch handler.
1862         // Declaring a local variable here does not hurt and will be "used" to make the code in the handler
1863         // compilable although the code will never be executed.
1864         std::exception e;
1865         BOOST_TRY
1866         {
1867             return this->do_process_event(evt,is_direct_call);
1868         }
1869         BOOST_CATCH (std::exception& e)
1870         {
1871             // give a chance to the concrete state machine to handle
1872             this->exception_caught(evt,*this,e);
1873         }
1874         BOOST_CATCH_END
1875         return HANDLED_TRUE;
1876     }
1877     // handling of deferred events
1878     // if none is found in the SM, take the following empty main version
1879     template <class StateType, class Enable = int>
1880     struct handle_defer_helper
1881     {
1882         handle_defer_helper(deferred_msg_queue_helper<library_sm>& ){}
1883         void do_handle_deferred(bool)
1884         {
1885         }
1886     };
1887     // otherwise the standard version handling the deferred events
1888     template <class StateType>
1889     struct handle_defer_helper
1890         <StateType, typename enable_if< typename ::boost::msm::back::has_fsm_deferred_events<StateType>::type,int >::type>
1891     {
1892         handle_defer_helper(deferred_msg_queue_helper<library_sm>& a_queue):
1893             m_events_queue(a_queue) {}
1894         void do_handle_deferred(bool new_seq=false)
1895         {
1896             // A new sequence is typically started upon initial entry to the
1897             // state, or upon a new transition.  When this occurs we want to
1898             // process all previously deferred events by incrementing the
1899             // correlation sequence.
1900             if (new_seq)
1901             {
1902                 ++m_events_queue.m_cur_seq;
1903             }
1904
1905             char& cur_seq = m_events_queue.m_cur_seq;
1906
1907             // Iteratively process all of the events within the deferred
1908             // queue upto (but not including) newly deferred events.
1909             while (!m_events_queue.m_deferred_events_queue.empty())
1910             {
1911                 typename deferred_events_queue_t::value_type& pair =
1912                     m_events_queue.m_deferred_events_queue.front();
1913
1914                 if (cur_seq != pair.second)
1915                 {
1916                     break;
1917                 }
1918
1919                 deferred_fct next = pair.first;
1920                 m_events_queue.m_deferred_events_queue.pop_front();
1921                 next();
1922             }
1923         }
1924
1925     private:
1926         deferred_msg_queue_helper<library_sm>& m_events_queue;
1927     };
1928
1929     // handling of eventless transitions
1930     // if none is found in the SM, nothing to do
1931     template <class StateType, class Enable = void>
1932     struct handle_eventless_transitions_helper
1933     {
1934         handle_eventless_transitions_helper(library_sm* , bool ){}
1935         void process_completion_event(EventSource = EVENT_SOURCE_DEFAULT){}
1936     };
1937     // otherwise
1938     template <class StateType>
1939     struct handle_eventless_transitions_helper
1940         <StateType, typename enable_if< typename ::boost::msm::back::has_fsm_eventless_transition<StateType>::type >::type>
1941     {
1942         handle_eventless_transitions_helper(library_sm* self_, bool handled_):self(self_),handled(handled_){}
1943         void process_completion_event(EventSource source = EVENT_SOURCE_DEFAULT)
1944         {
1945             typedef typename ::boost::mpl::deref<
1946                 typename ::boost::mpl::begin<
1947                     typename find_completion_events<StateType>::type
1948                         >::type
1949             >::type first_completion_event;
1950             if (handled)
1951             {
1952                 self->process_event_internal(
1953                     first_completion_event(),
1954                     source | EVENT_SOURCE_DIRECT);
1955             }
1956         }
1957
1958     private:
1959         library_sm* self;
1960         bool        handled;
1961     };
1962
1963     // helper class called in case the event to process has been found in the fsm's internal stt and is therefore processable
1964     template<class Event>
1965     struct process_fsm_internal_table
1966     {
1967         typedef typename ::boost::mpl::has_key<processable_events_internal_table,Event>::type is_event_processable;
1968
1969         // forward to the correct do_process
1970         static void process(Event const& evt,library_sm* self_,HandledEnum& result)
1971         {
1972             do_process(evt,self_,result,is_event_processable());
1973         }
1974     private:
1975         // the event is processable, let's try!
1976         static void do_process(Event const& evt,library_sm* self_,HandledEnum& result, ::boost::mpl::true_)
1977         {
1978             if (result != HANDLED_TRUE)
1979             {
1980                 typedef dispatch_table<library_sm,complete_table,Event,CompilePolicy> table;
1981                 HandledEnum res_internal = table::instance.entries[0](*self_, 0, self_->m_states[0], evt);
1982                 result = (HandledEnum)((int)result | (int)res_internal);
1983             }
1984         }
1985         // version doing nothing if the event is not in the internal stt and we can save ourselves the time trying to process
1986         static void do_process(Event const& ,library_sm* ,HandledEnum& , ::boost::mpl::false_)
1987         {
1988             // do nothing
1989         }
1990     };
1991
1992     template <class StateType,class Enable=void>
1993     struct region_processing_helper
1994     {
1995     public:
1996         region_processing_helper(library_sm* self_,HandledEnum& result_)
1997             :self(self_),result(result_){}
1998         template<class Event>
1999         void process(Event const& evt)
2000         {
2001             // use this table as if it came directly from the user
2002             typedef dispatch_table<library_sm,complete_table,Event,CompilePolicy> table;
2003             // +1 because index 0 is reserved for this fsm
2004             HandledEnum res =
2005                 table::instance.entries[self->m_states[0]+1](
2006                 *self, 0, self->m_states[0], evt);
2007             result = (HandledEnum)((int)result | (int)res);
2008             // process the event in the internal table of this fsm if the event is processable (present in the table)
2009             process_fsm_internal_table<Event>::process(evt,self,result);
2010         }
2011         library_sm*     self;
2012         HandledEnum&    result;
2013     };
2014     // version with visitors
2015     template <class StateType>
2016     struct region_processing_helper<StateType,typename ::boost::enable_if<
2017                         ::boost::mpl::is_sequence<typename StateType::initial_state> >::type>
2018     {
2019         private:
2020         // process event in one region
2021         template <class region_id,int Dummy=0>
2022         struct In
2023         {
2024             template<class Event>
2025             static void process(Event const& evt,library_sm* self_,HandledEnum& result_)
2026             {
2027                 // use this table as if it came directly from the user
2028                 typedef dispatch_table<library_sm,complete_table,Event,CompilePolicy> table;
2029                 // +1 because index 0 is reserved for this fsm
2030                 HandledEnum res =
2031                     table::instance.entries[self_->m_states[region_id::value]+1](
2032                     *self_, region_id::value , self_->m_states[region_id::value], evt);
2033                 result_ = (HandledEnum)((int)result_ | (int)res);
2034                 In< ::boost::mpl::int_<region_id::value+1> >::process(evt,self_,result_);
2035             }
2036         };
2037         template <int Dummy>
2038         struct In< ::boost::mpl::int_<nr_regions::value>,Dummy>
2039         {
2040             // end of processing
2041             template<class Event>
2042             static void process(Event const& evt,library_sm* self_,HandledEnum& result_)
2043             {
2044                 // process the event in the internal table of this fsm if the event is processable (present in the table)
2045                 process_fsm_internal_table<Event>::process(evt,self_,result_);
2046             }
2047         };
2048         public:
2049         region_processing_helper(library_sm* self_,HandledEnum& result_)
2050             :self(self_),result(result_){}
2051         template<class Event>
2052         void process(Event const& evt)
2053         {
2054             In< ::boost::mpl::int_<0> >::process(evt,self,result);
2055         }
2056
2057         library_sm*     self;
2058         HandledEnum&    result;
2059     };
2060
2061     // Main function used internally to make transitions
2062     // Can only be called for internally (for example in an action method) generated events.
2063     template<class Event>
2064     execute_return process_event_internal(Event const& evt,
2065                                           EventSource source = EVENT_SOURCE_DEFAULT)
2066     {
2067         // if the state machine has terminate or interrupt flags, check them, otherwise skip
2068         if (is_event_handling_blocked_helper<Event>
2069                 ( ::boost::mpl::bool_<has_fsm_blocking_states<library_sm>::type::value>() ) )
2070         {
2071             return HANDLED_TRUE;
2072         }
2073
2074         // if a message queue is needed and processing is on the way
2075         if (!do_pre_msg_queue_helper<Event>
2076                 (evt,::boost::mpl::bool_<is_no_message_queue<library_sm>::type::value>()))
2077         {
2078             // wait for the end of current processing
2079             return HANDLED_TRUE;
2080         }
2081         else
2082         {
2083             // Process event
2084             HandledEnum handled = this->do_process_helper<Event>(
2085                 evt,
2086                 ::boost::mpl::bool_<is_no_exception_thrown<library_sm>::type::value>(),
2087                 (EVENT_SOURCE_DIRECT & source));
2088
2089             // at this point we allow the next transition be executed without enqueing
2090             // so that completion events and deferred events execute now (if any)
2091             do_allow_event_processing_after_transition(
2092                 ::boost::mpl::bool_<is_no_message_queue<library_sm>::type::value>());
2093
2094             // Process completion transitions BEFORE any other event in the
2095             // pool (UML Standard 2.3 15.3.14)
2096             handle_eventless_transitions_helper<library_sm>
2097                 eventless_helper(this,(HANDLED_TRUE & handled));
2098             eventless_helper.process_completion_event(source);
2099
2100             // After handling, take care of the deferred events, but only if
2101             // we're not already processing from the deferred queue.
2102             do_handle_prio_msg_queue_deferred_queue(
2103                         source,handled,
2104                         ::boost::mpl::bool_<has_event_queue_before_deferred_queue<library_sm>::type::value>());
2105             return handled;
2106         }
2107     }
2108
2109     // minimum event processing without exceptions, queues, etc.
2110     template<class Event>
2111     HandledEnum do_process_event(Event const& evt, bool is_direct_call)
2112     {
2113         HandledEnum handled = HANDLED_FALSE;
2114
2115         // dispatch the event to every region
2116         region_processing_helper<Derived> helper(this,handled);
2117         helper.process(evt);
2118
2119         // if the event has not been handled and we have orthogonal zones, then
2120         // generate an error on every active state
2121         // for state machine states contained in other state machines, do not handle
2122         // but let the containing sm handle the error, unless the event was generated in this fsm
2123         // (by calling process_event on this fsm object, is_direct_call == true)
2124         // completion events do not produce an error
2125         if ( (!is_contained() || is_direct_call) && !handled && !is_completion_event<Event>::type::value)
2126         {
2127             for (int i=0; i<nr_regions::value;++i)
2128             {
2129                 this->no_transition(evt,*this,this->m_states[i]);
2130             }
2131         }
2132         return handled;
2133     }
2134
2135     // default row arguments for the compilers which accept this
2136     template <class Event>
2137     bool no_guard(Event const&){return true;}
2138     template <class Event>
2139     void no_action(Event const&){}
2140
2141 #ifndef BOOST_NO_RTTI
2142     HandledEnum process_any_event( ::boost::any const& evt);
2143 #endif
2144
2145 private:
2146     // composite accept implementation. First calls accept on the composite, then accept on all its active states.
2147     void composite_accept()
2148     {
2149         this->accept();
2150         this->visit_current_states();
2151     }
2152
2153 #define MSM_COMPOSITE_ACCEPT_SUB(z, n, unused) ARG ## n vis ## n
2154 #define MSM_COMPOSITE_ACCEPT_SUB2(z, n, unused) boost::ref( vis ## n )
2155 #define MSM_COMPOSITE_ACCEPT_EXECUTE(z, n, unused)                                      \
2156         template <BOOST_PP_ENUM_PARAMS(n, class ARG)>                                   \
2157         void composite_accept(BOOST_PP_ENUM(n, MSM_COMPOSITE_ACCEPT_SUB, ~ ) )               \
2158         {                                                                               \
2159             this->accept(BOOST_PP_ENUM_PARAMS(n,vis));                                        \
2160             this->visit_current_states(BOOST_PP_ENUM(n,MSM_COMPOSITE_ACCEPT_SUB2, ~));        \
2161         }
2162         BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_COMPOSITE_ACCEPT_EXECUTE, ~)
2163 #undef MSM_COMPOSITE_ACCEPT_EXECUTE
2164 #undef MSM_COMPOSITE_ACCEPT_SUB
2165 #undef MSM_COMPOSITE_ACCEPT_SUB2
2166
2167     // helper used to call the init states at the start of the state machine
2168     template <class Event>
2169     struct call_init
2170     {
2171         call_init(Event const& an_event,library_sm* self_):
2172                 evt(an_event),self(self_){}
2173         template <class State>
2174         void operator()(boost::msm::wrap<State> const&)
2175         {
2176             execute_entry(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
2177         }
2178     private:
2179         Event const& evt;
2180         library_sm* self;
2181     };
2182     // helper for flag handling. Uses OR by default on orthogonal zones.
2183     template <class Flag,bool orthogonalStates>
2184     struct FlagHelper
2185     {
2186         static bool helper(library_sm const& sm,flag_handler* )
2187         {
2188             // by default we use OR to accumulate the flags
2189             return sm.is_flag_active<Flag,Flag_OR>();
2190         }
2191     };
2192     template <class Flag>
2193     struct FlagHelper<Flag,false>
2194     {
2195         static bool helper(library_sm const& sm,flag_handler* flags_entries)
2196         {
2197             // just one active state, so we can call operator[] with 0
2198             return flags_entries[sm.current_state()[0]](sm);
2199         }
2200     };
2201     // handling of flag
2202     // defines a true and false functions plus a forwarding one for composite states
2203     template <class StateType,class Flag>
2204     struct FlagHandler
2205     {
2206         static bool flag_true(library_sm const& )
2207         {
2208             return true;
2209         }
2210         static bool flag_false(library_sm const& )
2211         {
2212             return false;
2213         }
2214         static bool forward(library_sm const& fsm)
2215         {
2216             return ::boost::fusion::at_key<StateType>(fsm.m_substate_list).template is_flag_active<Flag>();
2217         }
2218     };
2219     template <class Flag>
2220     struct init_flags
2221     {
2222     private:
2223         // helper function, helps hiding the forward function for non-state machines states.
2224         template <class T>
2225         void helper (flag_handler* an_entry,int offset, ::boost::mpl::true_ const &  )
2226         {
2227             // composite => forward
2228             an_entry[offset] = &FlagHandler<T,Flag>::forward;
2229         }
2230         template <class T>
2231         void helper (flag_handler* an_entry,int offset, ::boost::mpl::false_ const &  )
2232         {
2233             // default no flag
2234             an_entry[offset] = &FlagHandler<T,Flag>::flag_false;
2235         }
2236         // attributes
2237         flag_handler* entries;
2238
2239     public:
2240         init_flags(flag_handler* entries_)
2241             : entries(entries_)
2242         {}
2243
2244         // Flags initializer function object, used with mpl::for_each
2245         template <class StateType>
2246         void operator()( ::boost::msm::wrap<StateType> const& )
2247         {
2248             typedef typename get_flag_list<StateType>::type flags;
2249             typedef typename ::boost::mpl::contains<flags,Flag >::type found;
2250
2251             BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,StateType>::type::value));
2252             if (found::type::value)
2253             {
2254                 // the type defined the flag => true
2255                 entries[state_id] = &FlagHandler<StateType,Flag>::flag_true;
2256             }
2257             else
2258             {
2259                 // false or forward
2260                 typedef typename ::boost::mpl::and_<
2261                             typename is_composite_state<StateType>::type,
2262                             typename ::boost::mpl::not_<
2263                                     typename has_non_forwarding_flag<Flag>::type>::type >::type composite_no_forward;
2264
2265                 helper<StateType>(entries,state_id,::boost::mpl::bool_<composite_no_forward::type::value>());
2266             }
2267         }
2268     };
2269     // maintains for every flag a static array containing the flag value for every state
2270     template <class Flag>
2271     flag_handler* get_entries_for_flag() const
2272     {
2273         BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
2274
2275         static flag_handler flags_entries[max_state];
2276         // build a state list
2277         ::boost::mpl::for_each<state_list, boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2278                         (init_flags<Flag>(flags_entries));
2279         return flags_entries;
2280     }
2281
2282     // helper used to create a state using the correct constructor
2283     template <class State, class Enable=void>
2284     struct create_state_helper
2285     {
2286         static void set_sm(library_sm* )
2287         {
2288             // state doesn't need its sm
2289         }
2290     };
2291     // create a state requiring a pointer to the state machine
2292     template <class State>
2293     struct create_state_helper<State,typename boost::enable_if<typename State::needs_sm >::type>
2294     {
2295         static void set_sm(library_sm* sm)
2296         {
2297             // create and set the fsm
2298             ::boost::fusion::at_key<State>(sm->m_substate_list).set_sm_ptr(sm);
2299         }
2300     };
2301         // main unspecialized helper class
2302         template <class StateType,int ARGS>
2303         struct visitor_args;
2304
2305 #define MSM_VISITOR_ARGS_SUB(z, n, unused) BOOST_PP_CAT(_,BOOST_PP_ADD(n,1))
2306 #define MSM_VISITOR_ARGS_TYPEDEF_SUB(z, n, unused) typename StateType::accept_sig::argument ## n
2307
2308 #define MSM_VISITOR_ARGS_EXECUTE(z, n, unused)                                              \
2309     template <class StateType>                                                              \
2310     struct visitor_args<StateType,n>                                                        \
2311     {                                                                                       \
2312         template <class State>                                                              \
2313         static typename enable_if_c<!is_composite_state<State>::value,void >::type          \
2314         helper (library_sm* sm,                                                             \
2315         int id,StateType& astate)                                                           \
2316         {                                                                                   \
2317             sm->m_visitors.insert(id, boost::bind(&StateType::accept,                       \
2318                 ::boost::ref(astate) BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, MSM_VISITOR_ARGS_SUB, ~) ));   \
2319         }                                                                                   \
2320         template <class State>                                                              \
2321         static typename enable_if_c<is_composite_state<State>::value,void >::type           \
2322         helper (library_sm* sm,                                                             \
2323         int id,StateType& astate)                                                           \
2324         {                                                                                   \
2325             void (StateType::*caccept)(BOOST_PP_ENUM(n, MSM_VISITOR_ARGS_TYPEDEF_SUB, ~ ) )           \
2326                                         = &StateType::composite_accept;                     \
2327             sm->m_visitors.insert(id, boost::bind(caccept,             \
2328             ::boost::ref(astate) BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, MSM_VISITOR_ARGS_SUB, ~) ));                 \
2329         }                                                                                   \
2330 };
2331 BOOST_PP_REPEAT(BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_ARGS_EXECUTE, ~)
2332 #undef MSM_VISITOR_ARGS_EXECUTE
2333 #undef MSM_VISITOR_ARGS_SUB
2334
2335 // the IBM compiler seems to have problems with nested classes
2336 // the same seems to apply to the Apple version of gcc 4.0.1 (just in case we do for < 4.1)
2337 // and also to MS VC < 8
2338 #if defined (__IBMCPP__) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2339      public:
2340 #endif
2341     template<class ContainingSM>
2342     void set_containing_sm(ContainingSM* sm)
2343     {
2344         m_is_included=true;
2345         ::boost::fusion::for_each(m_substate_list,add_state<ContainingSM>(this,sm));
2346     }
2347 #if defined (__IBMCPP__) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2348      private:
2349 #endif
2350     // A function object for use with mpl::for_each that stuffs
2351     // states into the state list.
2352     template<class ContainingSM>
2353     struct add_state
2354     {
2355         add_state(library_sm* self_,ContainingSM* sm)
2356             : self(self_),containing_sm(sm){}
2357
2358         // State is a sub fsm with exit pseudo states and gets a pointer to this fsm, so it can build a callback
2359         template <class StateType>
2360         typename ::boost::enable_if<
2361             typename is_composite_state<StateType>::type,void >::type
2362         new_state_helper(boost::msm::back::dummy<0> = 0) const
2363         {
2364             ::boost::fusion::at_key<StateType>(self->m_substate_list).set_containing_sm(containing_sm);
2365         }
2366         // State is a sub fsm without exit pseudo states and does not get a callback to this fsm
2367         // or state is a normal state and needs nothing except creation
2368         template <class StateType>
2369         typename ::boost::enable_if<
2370             typename boost::mpl::and_<typename boost::mpl::not_
2371                                                     <typename is_composite_state<StateType>::type>::type,
2372                                       typename boost::mpl::not_
2373                                                     <typename is_pseudo_exit<StateType>::type>::type
2374                    >::type,void>::type
2375         new_state_helper( ::boost::msm::back::dummy<1> = 0) const
2376         {
2377             //nothing to do
2378         }
2379         // state is exit pseudo state and gets callback to target fsm
2380         template <class StateType>
2381         typename ::boost::enable_if<typename is_pseudo_exit<StateType>::type,void >::type
2382         new_state_helper( ::boost::msm::back::dummy<2> = 0) const
2383         {
2384             execute_return (ContainingSM::*pf) (typename StateType::event const& evt)=
2385                 &ContainingSM::process_event;
2386             ::boost::function<execute_return (typename StateType::event const&)> fct =
2387                 ::boost::bind(pf,containing_sm,_1);
2388             ::boost::fusion::at_key<StateType>(self->m_substate_list).set_forward_fct(fct);
2389         }
2390         // for every defined state in the sm
2391         template <class State>
2392         void operator()( State const&) const
2393         {
2394             //create a new state with the defined id and type
2395             BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
2396
2397             this->new_state_helper<State>(),
2398             create_state_helper<State>::set_sm(self);
2399             // create a visitor callback
2400             visitor_helper(state_id,::boost::fusion::at_key<State>(self->m_substate_list),
2401                            ::boost::mpl::bool_<has_accept_sig<State>::type::value>());
2402         }
2403     private:
2404         // support possible use of a visitor if accept_sig is defined
2405         template <class StateType>
2406         void visitor_helper(int id,StateType& astate, ::boost::mpl::true_ const & ) const
2407         {
2408             visitor_args<StateType,StateType::accept_sig::args_number>::
2409                 template helper<StateType>(self,id,astate);
2410         }
2411         template <class StateType>
2412         void visitor_helper(int ,StateType& , ::boost::mpl::false_ const &) const
2413         {
2414             // nothing to do
2415         }
2416
2417         library_sm*      self;
2418         ContainingSM*    containing_sm;
2419     };
2420
2421      // helper used to copy every state if needed
2422      struct copy_helper
2423      {
2424          copy_helper(library_sm* sm):
2425            m_sm(sm){}
2426          template <class StateType>
2427          void operator()( ::boost::msm::wrap<StateType> const& )
2428          {
2429             BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,StateType>::type::value));
2430             // possibly also set the visitor
2431             visitor_helper<StateType>(state_id);
2432
2433             // and for states that keep a pointer to the fsm, reset the pointer
2434             create_state_helper<StateType>::set_sm(m_sm);
2435          }
2436          template <class StateType>
2437          typename ::boost::enable_if<typename has_accept_sig<StateType>::type,void >::type
2438              visitor_helper(int id) const
2439          {
2440              visitor_args<StateType,StateType::accept_sig::args_number>::template helper<StateType>
2441                  (m_sm,id,::boost::fusion::at_key<StateType>(m_sm->m_substate_list));
2442          }
2443          template <class StateType>
2444          typename ::boost::disable_if<typename has_accept_sig<StateType>::type,void >::type
2445              visitor_helper(int) const
2446          {
2447              // nothing to do
2448          }
2449
2450          library_sm*     m_sm;
2451      };
2452      // helper to copy the active states attribute
2453      template <class region_id,int Dummy=0>
2454      struct region_copy_helper
2455      {
2456          static void do_copy(library_sm* self_,library_sm const& rhs)
2457          {
2458              self_->m_states[region_id::value] = rhs.m_states[region_id::value];
2459              region_copy_helper< ::boost::mpl::int_<region_id::value+1> >::do_copy(self_,rhs);
2460          }
2461      };
2462      template <int Dummy>
2463      struct region_copy_helper< ::boost::mpl::int_<nr_regions::value>,Dummy>
2464      {
2465          // end of processing
2466          static void do_copy(library_sm*,library_sm const& ){}
2467      };
2468      // copy functions for deep copy (no need of a 2nd version for NoCopy as noncopyable handles it)
2469      void do_copy (library_sm const& rhs,
2470               ::boost::msm::back::dummy<0> = 0)
2471      {
2472          // deep copy simply assigns the data
2473          region_copy_helper< ::boost::mpl::int_<0> >::do_copy(this,rhs);
2474          m_events_queue = rhs.m_events_queue;
2475          m_deferred_events_queue = rhs.m_deferred_events_queue;
2476          m_history = rhs.m_history;
2477          m_event_processing = rhs.m_event_processing;
2478          m_is_included = rhs.m_is_included;
2479          m_substate_list = rhs.m_substate_list;
2480          // except for the states themselves, which get duplicated
2481
2482          ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2483                         (copy_helper(this));
2484      }
2485
2486      // helper used to call the correct entry/exit method
2487      // unfortunately in O(number of states in the sub-sm) but should be better than a virtual call
2488      template<class Event,bool is_entry>
2489      struct entry_exit_helper
2490      {
2491          entry_exit_helper(int id,Event const& e,library_sm* self_):
2492             state_id(id),evt(e),self(self_){}
2493          // helper for entry actions
2494          template <class IsEntry,class State>
2495          typename ::boost::enable_if<typename IsEntry::type,void >::type
2496          helper( ::boost::msm::back::dummy<0> = 0)
2497          {
2498              BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,State>::value));
2499              if (id == state_id)
2500              {
2501                  execute_entry<State>(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
2502              }
2503          }
2504          // helper for exit actions
2505          template <class IsEntry,class State>
2506          typename boost::disable_if<typename IsEntry::type,void >::type
2507          helper( ::boost::msm::back::dummy<1> = 0)
2508          {
2509              BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,State>::value));
2510              if (id == state_id)
2511              {
2512                  execute_exit<State>(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
2513              }
2514          }
2515          // iterates through all states to find the one to be activated
2516          template <class State>
2517          void operator()( ::boost::msm::wrap<State> const&)
2518          {
2519              entry_exit_helper<Event,is_entry>::template helper< ::boost::mpl::bool_<is_entry>,State >();
2520          }
2521      private:
2522          int            state_id;
2523          Event const&   evt;
2524          library_sm*    self;
2525      };
2526
2527      // helper to start the fsm
2528      template <class region_id,int Dummy=0>
2529      struct region_start_helper
2530      {
2531          template<class Event>
2532          static void do_start(library_sm* self_,Event const& incomingEvent)
2533          {
2534              //forward the event for handling by sub state machines
2535              ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2536                  (entry_exit_helper<Event,true>(self_->m_states[region_id::value],incomingEvent,self_));
2537              region_start_helper
2538                  < ::boost::mpl::int_<region_id::value+1> >::do_start(self_,incomingEvent);
2539          }
2540      };
2541      template <int Dummy>
2542      struct region_start_helper< ::boost::mpl::int_<nr_regions::value>,Dummy>
2543      {
2544          // end of processing
2545          template<class Event>
2546          static void do_start(library_sm*,Event const& ){}
2547      };
2548      // start for states machines which are themselves embedded in other state machines (composites)
2549      template <class Event>
2550      void internal_start(Event const& incomingEvent)
2551      {
2552          region_start_helper< ::boost::mpl::int_<0> >::do_start(this,incomingEvent);
2553          // give a chance to handle an anonymous (eventless) transition
2554          handle_eventless_transitions_helper<library_sm> eventless_helper(this,true);
2555          eventless_helper.process_completion_event();
2556      }
2557
2558      template <class StateType>
2559      struct find_region_id
2560      {
2561          template <int region,int Dummy=0>
2562          struct In
2563          {
2564              enum {region_index=region};
2565          };
2566          // if the user provides no region, find it!
2567          template<int Dummy>
2568          struct In<-1,Dummy>
2569          {
2570              typedef typename build_orthogonal_regions<
2571                  library_sm,
2572                  initial_states
2573              >::type all_regions;
2574              enum {region_index= find_region_index<all_regions,StateType>::value };
2575          };
2576          enum {region_index = In<StateType::zone_index>::region_index };
2577      };
2578      // helper used to set the correct state as active state upon entry into a fsm
2579      struct direct_event_start_helper
2580      {
2581          direct_event_start_helper(library_sm* self_):self(self_){}
2582          // this variant is for the standard case, entry due to activation of the containing FSM
2583          template <class EventType,class FsmType>
2584          typename ::boost::disable_if<typename has_direct_entry<EventType>::type,void>::type
2585              operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<0> = 0)
2586          {
2587              (static_cast<Derived*>(self))->on_entry(evt,fsm);
2588              self->internal_start(evt);
2589          }
2590
2591          // this variant is for the direct entry case (just one entry, not a sequence of entries)
2592          template <class EventType,class FsmType>
2593          typename ::boost::enable_if<
2594              typename ::boost::mpl::and_<
2595                         typename ::boost::mpl::not_< typename is_pseudo_entry<
2596                                     typename EventType::active_state>::type >::type,
2597                         typename ::boost::mpl::and_<typename has_direct_entry<EventType>::type,
2598                                                     typename ::boost::mpl::not_<typename ::boost::mpl::is_sequence
2599                                                             <typename EventType::active_state>::type >::type
2600                                                     >::type>::type,void
2601                                   >::type
2602          operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2603          {
2604              (static_cast<Derived*>(self))->on_entry(evt,fsm);
2605              int state_id = get_state_id<stt,typename EventType::active_state::wrapped_entry>::value;
2606              BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index >= 0);
2607              BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index < nr_regions::value);
2608              // just set the correct zone, the others will be default/history initialized
2609              self->m_states[find_region_id<typename EventType::active_state::wrapped_entry>::region_index] = state_id;
2610              self->internal_start(evt.m_event);
2611          }
2612
2613          // this variant is for the fork entry case (a sequence on entries)
2614          template <class EventType,class FsmType>
2615          typename ::boost::enable_if<
2616              typename ::boost::mpl::and_<
2617                     typename ::boost::mpl::not_<
2618                                     typename is_pseudo_entry<typename EventType::active_state>::type >::type,
2619                     typename ::boost::mpl::and_<typename has_direct_entry<EventType>::type,
2620                                                 typename ::boost::mpl::is_sequence<
2621                                                                 typename EventType::active_state>::type
2622                                                 >::type>::type,void
2623                                 >::type
2624          operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<2> = 0)
2625          {
2626              (static_cast<Derived*>(self))->on_entry(evt,fsm);
2627              ::boost::mpl::for_each<typename EventType::active_state,
2628                                     ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2629                                                         (fork_helper<EventType>(self,evt));
2630              // set the correct zones, the others (if any) will be default/history initialized
2631              self->internal_start(evt.m_event);
2632          }
2633
2634          // this variant is for the pseudo state entry case
2635          template <class EventType,class FsmType>
2636          typename ::boost::enable_if<
2637              typename is_pseudo_entry<typename EventType::active_state >::type,void
2638                                     >::type
2639          operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<3> = 0)
2640          {
2641              // entry on the FSM
2642              (static_cast<Derived*>(self))->on_entry(evt,fsm);
2643              int state_id = get_state_id<stt,typename EventType::active_state::wrapped_entry>::value;
2644              BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index >= 0);
2645              BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index < nr_regions::value);
2646              // given region starts with the entry pseudo state as active state
2647              self->m_states[find_region_id<typename EventType::active_state::wrapped_entry>::region_index] = state_id;
2648              self->internal_start(evt.m_event);
2649              // and we process the transition in the zone of the newly active state
2650              // (entry pseudo states are, according to UML, a state connecting 1 transition outside to 1 inside
2651              self->process_event(evt.m_event);
2652          }
2653      private:
2654          // helper for the fork case, does almost like the direct entry
2655          library_sm* self;
2656          template <class EventType>
2657          struct fork_helper
2658          {
2659              fork_helper(library_sm* self_,EventType const& evt_):
2660                 helper_self(self_),helper_evt(evt_){}
2661              template <class StateType>
2662              void operator()( ::boost::msm::wrap<StateType> const& )
2663              {
2664                  int state_id = get_state_id<stt,typename StateType::wrapped_entry>::value;
2665                  BOOST_STATIC_ASSERT(find_region_id<typename StateType::wrapped_entry>::region_index >= 0);
2666                  BOOST_STATIC_ASSERT(find_region_id<typename StateType::wrapped_entry>::region_index < nr_regions::value);
2667                  helper_self->m_states[find_region_id<typename StateType::wrapped_entry>::region_index] = state_id;
2668              }
2669          private:
2670              library_sm*        helper_self;
2671              EventType const&   helper_evt;
2672          };
2673      };
2674
2675      // helper for entry
2676      template <class region_id,int Dummy=0>
2677      struct region_entry_exit_helper
2678      {
2679          template<class Event>
2680          static void do_entry(library_sm* self_,Event const& incomingEvent)
2681          {
2682              self_->m_states[region_id::value] =
2683                  self_->m_history.history_entry(incomingEvent)[region_id::value];
2684              region_entry_exit_helper
2685                  < ::boost::mpl::int_<region_id::value+1> >::do_entry(self_,incomingEvent);
2686          }
2687          template<class Event>
2688          static void do_exit(library_sm* self_,Event const& incomingEvent)
2689          {
2690              ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2691                  (entry_exit_helper<Event,false>(self_->m_states[region_id::value],incomingEvent,self_));
2692              region_entry_exit_helper
2693                  < ::boost::mpl::int_<region_id::value+1> >::do_exit(self_,incomingEvent);
2694          }
2695      };
2696      template <int Dummy>
2697      struct region_entry_exit_helper< ::boost::mpl::int_<nr_regions::value>,Dummy>
2698      {
2699          // end of processing
2700          template<class Event>
2701          static void do_entry(library_sm*,Event const& ){}
2702          template<class Event>
2703          static void do_exit(library_sm*,Event const& ){}
2704      };
2705      // entry/exit for states machines which are themselves embedded in other state machines (composites)
2706      template <class Event,class FsmType>
2707      void do_entry(Event const& incomingEvent,FsmType& fsm)
2708      {
2709         // by default we activate the history/init states, can be overwritten by direct_event_start_helper
2710         region_entry_exit_helper< ::boost::mpl::int_<0> >::do_entry(this,incomingEvent);
2711         // block immediate handling of events
2712         m_event_processing = true;
2713         // if the event is generating a direct entry/fork, set the current state(s) to the direct state(s)
2714         direct_event_start_helper(this)(incomingEvent,fsm);
2715         // handle messages which were generated and blocked in the init calls
2716         m_event_processing = false;
2717         // look for deferred events waiting
2718         handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue);
2719         defer_helper.do_handle_deferred(true);
2720         process_message_queue(this);
2721      }
2722      template <class Event,class FsmType>
2723      void do_exit(Event const& incomingEvent,FsmType& fsm)
2724      {
2725         // first recursively exit the sub machines
2726         // forward the event for handling by sub state machines
2727         region_entry_exit_helper< ::boost::mpl::int_<0> >::do_exit(this,incomingEvent);
2728         // then call our own exit
2729         (static_cast<Derived*>(this))->on_exit(incomingEvent,fsm);
2730         // give the history a chance to handle this (or not).
2731         m_history.history_exit(this->m_states);
2732         // history decides what happens with deferred events
2733         if (!m_history.process_deferred_events(incomingEvent))
2734         {
2735             clear_deferred_queue();
2736         }
2737      }
2738
2739     // the IBM and VC<8 compilers seem to have problems with the friend declaration of dispatch_table
2740 #if defined (__IBMCPP__) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2741      public:
2742 #endif
2743     // no transition for event.
2744     template <class Event>
2745     static HandledEnum call_no_transition(library_sm& , int , int , Event const& )
2746     {
2747         return HANDLED_FALSE;
2748     }
2749     // no transition for event for internal transitions (not an error).
2750     template <class Event>
2751     static HandledEnum call_no_transition_internal(library_sm& , int , int , Event const& )
2752     {
2753         //// reject to give others a chance to handle
2754         //return HANDLED_GUARD_REJECT;
2755         return HANDLED_FALSE;
2756     }
2757     // called for deferred events. Address set in the dispatch_table at init
2758     template <class Event>
2759     static HandledEnum defer_transition(library_sm& fsm, int , int , Event const& e)
2760     {
2761         fsm.defer_event(e);
2762         return HANDLED_DEFERRED;
2763     }
2764     // called for completion events. Default address set in the dispatch_table at init
2765     // prevents no-transition detection for completion events
2766     template <class Event>
2767     static HandledEnum default_eventless_transition(library_sm&, int, int , Event const&)
2768     {
2769         return HANDLED_FALSE;
2770     }
2771 #if defined (__IBMCPP__) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2772      private:
2773 #endif
2774     // removes one event from the message queue and processes it
2775     template <class StateType>
2776     void process_message_queue(StateType*,
2777                                typename ::boost::disable_if<typename is_no_message_queue<StateType>::type,void >::type* = 0)
2778     {
2779         // Iteratively process all events from the message queue.
2780         while (!m_events_queue.m_events_queue.empty())
2781         {
2782             transition_fct next = m_events_queue.m_events_queue.front();
2783             m_events_queue.m_events_queue.pop_front();
2784             next();
2785         }
2786     }
2787     template <class StateType>
2788     void process_message_queue(StateType*,
2789                                typename ::boost::enable_if<typename is_no_message_queue<StateType>::type,void >::type* = 0)
2790     {
2791         // nothing to process
2792     }
2793     // helper function. In cases where the event is wrapped (target is a direct entry states)
2794     // we want to send only the real event to on_entry, not the wrapper.
2795     template <class EventType>
2796     static
2797     typename boost::enable_if<typename has_direct_entry<EventType>::type,typename EventType::contained_event const& >::type
2798     remove_direct_entry_event_wrapper(EventType const& evt,boost::msm::back::dummy<0> = 0)
2799     {
2800         return evt.m_event;
2801     }
2802     template <class EventType>
2803     static typename boost::disable_if<typename has_direct_entry<EventType>::type,EventType const& >::type
2804     remove_direct_entry_event_wrapper(EventType const& evt,boost::msm::back::dummy<1> = 0)
2805     {
2806         // identity. No wrapper
2807         return evt;
2808     }
2809     // calls the entry/exit or on_entry/on_exit depending on the state type
2810     // (avoids calling virtually)
2811     // variant for FSMs
2812     template <class StateType,class EventType,class FsmType>
2813     static
2814         typename boost::enable_if<typename is_composite_state<StateType>::type,void >::type
2815         execute_entry(StateType& astate,EventType const& evt,FsmType& fsm,boost::msm::back::dummy<0> = 0)
2816     {
2817         // calls on_entry on the fsm then handles direct entries, fork, entry pseudo state
2818         astate.do_entry(evt,fsm);
2819     }
2820     // variant for states
2821     template <class StateType,class EventType,class FsmType>
2822     static
2823         typename ::boost::disable_if<
2824             typename ::boost::mpl::or_<typename is_composite_state<StateType>::type,
2825                                        typename is_pseudo_exit<StateType>::type >::type,void >::type
2826     execute_entry(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2827     {
2828         // simple call to on_entry
2829         astate.on_entry(remove_direct_entry_event_wrapper(evt),fsm);
2830     }
2831     // variant for exit pseudo states
2832     template <class StateType,class EventType,class FsmType>
2833     static
2834         typename ::boost::enable_if<typename is_pseudo_exit<StateType>::type,void >::type
2835     execute_entry(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<2> = 0)
2836     {
2837         // calls on_entry on the state then forward the event to the transition which should be defined inside the
2838         // contained fsm
2839         astate.on_entry(evt,fsm);
2840         astate.forward_event(evt);
2841     }
2842     template <class StateType,class EventType,class FsmType>
2843     static
2844         typename ::boost::enable_if<typename is_composite_state<StateType>::type,void >::type
2845     execute_exit(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<0> = 0)
2846     {
2847         astate.do_exit(evt,fsm);
2848     }
2849     template <class StateType,class EventType,class FsmType>
2850     static
2851         typename ::boost::disable_if<typename is_composite_state<StateType>::type,void >::type
2852     execute_exit(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2853     {
2854         // simple call to on_exit
2855         astate.on_exit(evt,fsm);
2856     }
2857
2858     // helper allowing special handling of direct entries / fork
2859     template <class StateType,class TargetType,class EventType,class FsmType>
2860     static
2861         typename ::boost::disable_if<
2862             typename ::boost::mpl::or_<typename has_explicit_entry_state<TargetType>::type,
2863                                        ::boost::mpl::is_sequence<TargetType> >::type,void>::type
2864     convert_event_and_execute_entry(StateType& astate,EventType const& evt, FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2865     {
2866         // if the target is a normal state, do the standard entry handling
2867         execute_entry<StateType>(astate,evt,fsm);
2868     }
2869     template <class StateType,class TargetType,class EventType,class FsmType>
2870     static
2871         typename ::boost::enable_if<
2872             typename ::boost::mpl::or_<typename has_explicit_entry_state<TargetType>::type,
2873                                        ::boost::mpl::is_sequence<TargetType> >::type,void >::type
2874     convert_event_and_execute_entry(StateType& astate,EventType const& evt, FsmType& fsm, ::boost::msm::back::dummy<0> = 0)
2875     {
2876         // for the direct entry, pack the event in a wrapper so that we handle it differently during fsm entry
2877         execute_entry(astate,msm::back::direct_entry_event<TargetType,EventType>(evt),fsm);
2878     }
2879
2880     // creates all the states
2881     template <class ContainingSM>
2882     void fill_states(ContainingSM* containing_sm=0)
2883     {
2884         // checks that regions are truly orthogonal
2885         FsmCheckPolicy::template check_orthogonality<library_sm>();
2886         // checks that all states are reachable
2887         FsmCheckPolicy::template check_unreachable_states<library_sm>();
2888
2889         BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
2890         // allocate the place without reallocation
2891         m_visitors.fill_visitors(max_state);
2892         ::boost::fusion::for_each(m_substate_list,add_state<ContainingSM>(this,containing_sm));
2893
2894     }
2895
2896 private:
2897     template <class StateType,class Enable=void>
2898     struct msg_queue_helper
2899     {
2900     public:
2901         msg_queue_helper():m_events_queue(){}
2902         events_queue_t              m_events_queue;
2903     };
2904     template <class StateType>
2905     struct msg_queue_helper<StateType,
2906         typename ::boost::enable_if<typename is_no_message_queue<StateType>::type >::type>
2907     {
2908     };
2909
2910     template <class Fsm,class Stt, class Event, class Compile>
2911     friend struct dispatch_table;
2912
2913     // data members
2914     int                             m_states[nr_regions::value];
2915     msg_queue_helper<library_sm>    m_events_queue;
2916     deferred_msg_queue_helper
2917         <library_sm>                m_deferred_events_queue;
2918     concrete_history                m_history;
2919     bool                            m_event_processing;
2920     bool                            m_is_included;
2921     visitor_fct_helper<BaseState>   m_visitors;
2922     substate_list                   m_substate_list;
2923
2924
2925 };
2926
2927 } } }// boost::msm::back
2928 #endif //BOOST_MSM_BACK_STATEMACHINE_H