Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r51209 - sandbox/msm/boost/msm
From: christophe.j.henry_at_[hidden]
Date: 2009-02-11 17:08:59


Author: chenry
Date: 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
New Revision: 51209
URL: http://svn.boost.org/trac/boost/changeset/51209

Log:
new visitor version (no doc yet)
Added:
   sandbox/msm/boost/msm/args.hpp (contents, props changed)
   sandbox/msm/boost/msm/common_types.hpp (contents, props changed)
   sandbox/msm/boost/msm/dispatch_table.hpp (contents, props changed)
   sandbox/msm/boost/msm/states.hpp (contents, props changed)
Removed:
   sandbox/msm/boost/msm/visitable_policies.hpp
Text files modified:
   sandbox/msm/boost/msm/bind_helpers.hpp | 11
   sandbox/msm/boost/msm/copy_policies.hpp | 18
   sandbox/msm/boost/msm/history_policies.hpp | 14
   sandbox/msm/boost/msm/metafunctions.hpp | 228 ++++----
   sandbox/msm/boost/msm/state_machine.hpp | 992 ++++++++++++++-------------------------
   sandbox/msm/boost/msm/tools.hpp | 14
   6 files changed, 510 insertions(+), 767 deletions(-)

Added: sandbox/msm/boost/msm/args.hpp
==============================================================================
--- (empty file)
+++ sandbox/msm/boost/msm/args.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,59 @@
+// Copyright 2008 Christophe Henry
+// henry UNDERSCORE christophe AT hotmail DOT com
+// This is an extended version of the state machine available in the boost::mpl library
+// Distributed under the same license as the original.
+// Copyright for the original version:
+// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
+// under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MSM_ARGS_H
+#define BOOST_MSM_ARGS_H
+
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/control/expr_if.hpp>
+#include <boost/preprocessor/punctuation/comma.hpp>
+#include <boost/preprocessor/arithmetic/add.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/comparison/less.hpp>
+#include <boost/preprocessor/arithmetic/dec.hpp>
+
+namespace boost { namespace msm
+{
+struct none {};
+#define MSM_ARGS_PRINT(z, n, data) data
+#define MSM_ARGS_NONE_PRINT(z, n, data) class data ## n = none \
+ BOOST_PP_COMMA_IF( BOOST_PP_LESS(n, BOOST_PP_DEC(BOOST_MSM_VISITOR_ARG_SIZE) ) )
+
+#define MSM_VISITOR_MAIN_ARGS(n) \
+ template <class RES, \
+ BOOST_PP_REPEAT(BOOST_MSM_VISITOR_ARG_SIZE, MSM_ARGS_NONE_PRINT, ARG)> \
+ struct args \
+ { \
+ typedef ::boost::function<RES(BOOST_PP_ENUM_PARAMS(n, ARG))> type; \
+ enum {args_number=n}; \
+ };
+
+#define MSM_VISITOR_ARGS(z, n, unused) \
+ template <class RES BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class ARG)> \
+ struct args<RES, \
+ BOOST_PP_ENUM_PARAMS(n,ARG) \
+ BOOST_PP_COMMA_IF(n) \
+ BOOST_PP_ENUM(BOOST_PP_SUB(BOOST_MSM_VISITOR_ARG_SIZE,n), MSM_ARGS_PRINT, none) \
+ > \
+ { \
+ typedef ::boost::function<RES(BOOST_PP_ENUM_PARAMS(n, ARG))> type; \
+ enum {args_number=n}; \
+ };
+MSM_VISITOR_MAIN_ARGS(BOOST_MSM_VISITOR_ARG_SIZE)
+BOOST_PP_REPEAT(BOOST_MSM_VISITOR_ARG_SIZE, MSM_VISITOR_ARGS, ~)
+
+#undef MSM_VISITOR_ARGS
+#undef MSM_ARGS_PRINT
+
+}}
+
+#endif //BOOST_MSM_ARGS_H

Modified: sandbox/msm/boost/msm/bind_helpers.hpp
==============================================================================
--- sandbox/msm/boost/msm/bind_helpers.hpp (original)
+++ sandbox/msm/boost/msm/bind_helpers.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
@@ -1,6 +1,3 @@
-#ifndef BIND_HELPERS_H
-#define BIND_HELPERS_H
-
 // Copyright 2008 Christophe Henry
 // henry UNDERSCORE christophe AT hotmail DOT com
 // This is an extended version of the state machine available in the boost::mpl library
@@ -10,7 +7,11 @@
 // under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
-//
+
+#ifndef BOOST_MSM_BIND_HELPERS_H
+#define BOOST_MSM_BIND_HELPERS_H
+
+#include <functional>
 
 namespace boost { namespace msm
 {
@@ -35,4 +36,4 @@
             }
     };
 } } //boost::msm
-#endif //BIND_HELPERS_H
+#endif //BOOST_MSM_BIND_HELPERS_H

Added: sandbox/msm/boost/msm/common_types.hpp
==============================================================================
--- (empty file)
+++ sandbox/msm/boost/msm/common_types.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,33 @@
+// Copyright 2008 Christophe Henry
+// henry UNDERSCORE christophe AT hotmail DOT com
+// This is an extended version of the state machine available in the boost::mpl library
+// Distributed under the same license as the original.
+// Copyright for the original version:
+// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
+// under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MSM_COMMON_TYPES_H
+#define BOOST_MSM_COMMON_TYPES_H
+
+namespace boost { namespace msm
+{
+// used for disable_if
+template <int> struct dummy { dummy(int) {} };
+// return value for transition handling
+typedef enum
+{
+ HANDLED_FALSE=0,
+ HANDLED_TRUE =1,
+ HANDLED_GUARD_REJECT=2
+} HandledEnum;
+typedef ::boost::tuple<HandledEnum,const std::vector<int>*> execute_return;
+
+// wrapper for mpl::for_each as showed in the C++ Template Metaprogramming ch. 9
+template <class T>
+struct wrap{};
+
+}}
+
+#endif //BOOST_MSM_COMMON_TYPES_H

Modified: sandbox/msm/boost/msm/copy_policies.hpp
==============================================================================
--- sandbox/msm/boost/msm/copy_policies.hpp (original)
+++ sandbox/msm/boost/msm/copy_policies.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
@@ -1,5 +1,3 @@
-#ifndef COPY_POLICIES_H
-#define COPY_POLICIES_H
 // Copyright 2008 Christophe Henry
 // henry UNDERSCORE christophe AT hotmail DOT com
 // This is an extended version of the state machine available in the boost::mpl library
@@ -9,33 +7,35 @@
 // under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
-//
 
-#include <boost/utility.hpp>
+#ifndef BOOST_MSM_COPY_POLICIES_H
+#define BOOST_MSM_COPY_POLICIES_H
 
+#include <boost/utility.hpp>
+#include <boost/mpl/bool.hpp>
 
 namespace boost { namespace msm
 {
     // deactivates copy
- struct NoCopy : boost::noncopyable
+ struct NoCopy : ::boost::noncopyable
     {
             // tags
- typedef mpl::bool_<false> shallow_copy;
+ typedef ::boost::mpl::bool_<false> shallow_copy;
     };
         
     // activate the shallow copy flag
     struct ShallowCopy
     {
             // tags
- typedef mpl::bool_<true> shallow_copy;
+ typedef ::boost::mpl::bool_<true> shallow_copy;
     };
     // deactivate the shallow copy flag
     struct DeepCopy
     {
             // tags
- typedef mpl::bool_<false> shallow_copy;
+ typedef ::boost::mpl::bool_<false> shallow_copy;
     };
 } } //boost::msm
 
 
-#endif //COPY_POLICIES_H
+#endif //BOOST_MSM_COPY_POLICIES_H

Added: sandbox/msm/boost/msm/dispatch_table.hpp
==============================================================================
--- (empty file)
+++ sandbox/msm/boost/msm/dispatch_table.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,228 @@
+// Copyright 2008 Christophe Henry
+// henry UNDERSCORE christophe AT hotmail DOT com
+// This is an extended version of the state machine available in the boost::mpl library
+// Distributed under the same license as the original.
+// Copyright for the original version:
+// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
+// under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MSM_DISPATCH_TABLE_H
+#define BOOST_MSM_DISPATCH_TABLE_H
+
+#include <utility>
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/empty.hpp>
+#include <boost/mpl/reverse_fold.hpp>
+#include <boost/mpl/greater.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/filter_view.hpp>
+#include <boost/mpl/pop_front.hpp>
+#include <boost/mpl/for_each.hpp>
+#include <boost/mpl/map.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/push_back.hpp>
+
+#include <boost/msm/metafunctions.hpp>
+#include <boost/msm/common_types.hpp>
+#include <boost/msm/states.hpp>
+
+namespace boost { namespace msm
+{
+
+// forward declaration
+template<class Derived,class HistoryPolicy,class BaseState,class CopyPolicy>
+class state_machine;
+
+// Generates a singleton runtime lookup table that maps current state
+// to a function that makes the SM take its transition on the given
+// Event type.
+template <class Fsm, class HistoryPolicy,class BaseState, class CopyPolicy,class Stt, class Event>
+struct dispatch_table
+{
+ private:
+ // This is a table of these function pointers.
+ typedef typename Fsm::pBaseState pstate_base;
+ typedef std::pair<int,HandledEnum> (*cell)(Fsm&, int, pstate_base*,Event const&);
+ typedef bool (*guard)(Fsm&, Event const&);
+
+ // class used to build a chain (or sequence) of transitions for a given event and start state
+ // (like an UML diamond). Allows transition conflicts.
+ template< typename Seq,typename AnEvent,typename State >
+ struct chain_row
+ {
+ typedef State current_state_type;
+ typedef AnEvent event;
+
+ // helper for building a disable/enable_if-controlled execute function
+ struct execute_helper
+ {
+ template <class Sequence>
+ static std::pair<int,HandledEnum> execute(
+ Fsm& fsm, int state, pstate_base* all_states, Event const& evt,
+ typename ::boost::enable_if<typename ::boost::mpl::empty<Sequence>::type,void >::type* dmy=0)
+ {
+ // if at least one guard rejected, this will be ignored, otherwise will generate an error
+ return std::make_pair(state,HANDLED_FALSE);
+ }
+
+ template <class Sequence>
+ static std::pair<int,HandledEnum> execute(
+ Fsm& fsm, int state, pstate_base* all_states, Event const& evt,
+ typename ::boost::disable_if<typename ::boost::mpl::empty<Sequence>::type,void >::type* dmy=0)
+ {
+ // try the first guard
+ typedef typename ::boost::mpl::front<Sequence>::type first_row;
+ std::pair<int,HandledEnum> res = first_row::execute(fsm,state,all_states,evt);
+ if (HANDLED_TRUE!=res.second)
+ {
+ // if the first rejected, move on to the next one
+ std::pair<int,HandledEnum> sub_res =
+ execute<typename ::boost::mpl::pop_front<Sequence>::type>(fsm,state,all_states,evt);
+ // if at least one guards rejects, the event will not generate a call to no_transition
+ HandledEnum handled = ((HANDLED_GUARD_REJECT==sub_res.second) ||
+ (HANDLED_GUARD_REJECT==res.second))?
+ HANDLED_GUARD_REJECT:sub_res.second;
+ return std::make_pair(sub_res.first,handled);
+ }
+ return res;
+ }
+ };
+ // Take the transition action and return the next state.
+ static std::pair<int,HandledEnum> execute(Fsm& fsm, int state, pstate_base* all_states, Event const& evt)
+ {
+ // forward to helper
+ return execute_helper::template execute<Seq>(fsm,state,all_states,evt);
+ }
+ };
+ // nullary metafunction whose only job is to prevent early evaluation of _1
+ template< typename Entry >
+ struct make_chain_row_from_map_entry
+ {
+ typedef chain_row<typename Entry::second,Event,
+ typename Entry::first > type;
+ };
+ // Compute the maximum state value in the sm so we know how big
+ // to make the table
+ typedef typename generate_state_set<Stt>::type state_list;
+ BOOST_STATIC_CONSTANT(int, max_state = ( ::boost::mpl::size<state_list>::value));
+
+ // A function object for use with mpl::for_each that stuffs
+ // transitions into cells.
+ struct init_cell
+ {
+ init_cell(dispatch_table* self_)
+ : self(self_)
+ {}
+
+ // Cell initializer function object, used with mpl::for_each
+ template <class Transition>
+ void operator()(Transition const&) const
+ {
+ typedef typename create_stt<Fsm>::type stt;
+ BOOST_STATIC_CONSTANT(int, state_id =
+ (get_state_id<stt,typename Transition::current_state_type>::value));
+ self->entries[state_id] = &Transition::execute;
+ }
+
+ dispatch_table* self;
+ };
+ struct default_init_cell
+ {
+ default_init_cell(dispatch_table* self_,cell* tofill_entries_)
+ : self(self_),tofill_entries(tofill_entries_)
+ {}
+ // Cell default-initializer function object, used with mpl::for_each
+ // initializes with call_no_transition or defer_transition
+ template <class State>
+ typename ::boost::disable_if<typename has_state_delayed_event<State,Event>::type,void >::type
+ operator()(boost::msm::wrap<State> const&,boost::msm::dummy<0> = 0)
+ {
+ typedef typename create_stt<Fsm>::type stt;
+ BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
+ cell call_no_transition = &state_machine<Fsm,HistoryPolicy,BaseState,CopyPolicy>::call_no_transition;
+ tofill_entries[state_id] = call_no_transition;
+ }
+ template <class State>
+ typename ::boost::enable_if<typename has_state_delayed_event<State,Event>::type,void >::type
+ operator()(boost::msm::wrap<State> const&,boost::msm::dummy<1> = 0)
+ {
+ typedef typename create_stt<Fsm>::type stt;
+ BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
+ cell call_no_transition = &state_machine<Fsm,HistoryPolicy,BaseState,CopyPolicy>::defer_transition;
+ tofill_entries[state_id] = call_no_transition;
+ }
+ dispatch_table* self;
+ cell* tofill_entries;
+ };
+ public:
+ // initialize the dispatch table for a given Event and Fsm
+ dispatch_table()
+ {
+ // Initialize cells for no transition
+ ::boost::mpl::for_each<typename generate_state_set<Stt>::type,
+ boost::msm::wrap< ::boost::mpl::placeholders::_1> >
+ (default_init_cell(this,entries));
+
+ // build chaining rows for rows coming from the same state and the current event
+ // first we build a map of sequence for every source
+ // in reverse order so that the frow's are handled first (UML priority)
+ typedef typename ::boost::mpl::reverse_fold<
+ // filter on event
+ ::boost::mpl::filter_view
+ <Stt, ::boost::is_same<transition_event< ::boost::mpl::placeholders::_>, Event> >,
+ // build a map
+ ::boost::mpl::map<>,
+ ::boost::mpl::if_<
+ // if we already have a row on this source state
+ ::boost::mpl::has_key< ::boost::mpl::placeholders::_1,
+ transition_source_type< ::boost::mpl::placeholders::_2> >,
+ // insert a new element in the value type
+ ::boost::mpl::insert<
+ ::boost::mpl::placeholders::_1,
+ ::boost::mpl::pair<transition_source_type< ::boost::mpl::placeholders::_2>,
+ ::boost::mpl::push_back<
+ ::boost::mpl::at< ::boost::mpl::placeholders::_1,
+ transition_source_type< ::boost::mpl::placeholders::_2> >,
+ ::boost::mpl::placeholders::_2 >
+ > >,
+ // first row on this source state, make a vector with 1 element
+ ::boost::mpl::insert<
+ ::boost::mpl::placeholders::_1,
+ ::boost::mpl::pair<transition_source_type< ::boost::mpl::placeholders::_2>,
+ make_vector< ::boost::mpl::placeholders::_2> > >
+ >
+ >::type map_of_row_seq;
+ // and then build chaining rows for all source states having more than 1 row
+ typedef typename ::boost::mpl::fold<
+ map_of_row_seq,::boost::mpl::vector<>,
+ ::boost::mpl::if_<
+ ::boost::mpl::greater< ::boost::mpl::size<
+ ::boost::mpl::second< ::boost::mpl::placeholders::_2> >,
+ ::boost::mpl::int_<1> >,
+ // we need row chaining
+ ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
+ make_chain_row_from_map_entry< ::boost::mpl::placeholders::_2> >,
+ // just one row, no chaining, we rebuild the row like it was before
+ ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
+ get_first_element_pair_second< ::boost::mpl::placeholders::_2> >
+ > >::type chained_rows;
+ // Go back and fill in cells for matching transitions.
+ ::boost::mpl::for_each<chained_rows>(init_cell(this));
+ }
+
+ // The singleton instance.
+ static const dispatch_table instance;
+
+ public: // data members
+ cell entries[max_state];
+};
+
+}} // boost::msm
+
+
+#endif //BOOST_MSM_DISPATCH_TABLE_H

Modified: sandbox/msm/boost/msm/history_policies.hpp
==============================================================================
--- sandbox/msm/boost/msm/history_policies.hpp (original)
+++ sandbox/msm/boost/msm/history_policies.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
@@ -1,6 +1,3 @@
-#ifndef HISTORY_POLICIES_H
-#define HISTORY_POLICIES_H
-
 // Copyright 2008 Christophe Henry
 // henry UNDERSCORE christophe AT hotmail DOT com
 // This is an extended version of the state machine available in the boost::mpl library
@@ -10,7 +7,12 @@
 // under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
-//
+
+#ifndef BOOST_MSM_HISTORY_POLICIES_H
+#define BOOST_MSM_HISTORY_POLICIES_H
+
+#include <vector>
+#include <boost/mpl/contains.hpp>
 
 namespace boost { namespace msm
 {
@@ -87,7 +89,7 @@
     template <class Event>
         std::vector<int>& history_entry(Event const&)
     {
- if (mpl::contains<Events,Event>::value)
+ if ( ::boost::mpl::contains<Events,Event>::value)
                 {
                     return m_currentStates;
             }
@@ -100,4 +102,4 @@
 };
 
 } }//boost::msm
-#endif //HISTORY_POLICIES_H
+#endif //BOOST_MSM_HISTORY_POLICIES_H

Modified: sandbox/msm/boost/msm/metafunctions.hpp
==============================================================================
--- sandbox/msm/boost/msm/metafunctions.hpp (original)
+++ sandbox/msm/boost/msm/metafunctions.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
@@ -1,6 +1,3 @@
-#ifndef METAFUNCTIONS_H
-#define METAFUNCTIONS_H
-
 // Copyright 2008 Christophe Henry
 // henry UNDERSCORE christophe AT hotmail DOT com
 // This is an extended version of the state machine available in the boost::mpl library
@@ -10,7 +7,9 @@
 // under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
-//
+
+#ifndef BOOST_MSM_METAFUNCTIONS_H
+#define BOOST_MSM_METAFUNCTIONS_H
 
 #include <boost/mpl/copy_if.hpp>
 #include <boost/mpl/unique.hpp>
@@ -54,12 +53,12 @@
 template <class Id,class Transition>
 struct make_pair_source_state_id
 {
- typedef typename mpl::pair<typename Transition::current_state_type,Id> type;
+ typedef typename ::boost::mpl::pair<typename Transition::current_state_type,Id> type;
 };
 template <class Id,class Transition>
 struct make_pair_target_state_id
 {
- typedef typename mpl::pair<typename Transition::next_state_type,Id> type;
+ typedef typename ::boost::mpl::pair<typename Transition::next_state_type,Id> type;
 };
 
 // iterates through a transition table and automatically generates ids starting at 0
@@ -69,53 +68,57 @@
 struct generate_state_ids
 {
     typedef typename
- mpl::fold<
- stt,mpl::pair<mpl::map< >,mpl::int_<0> >,
- mpl::pair<
- mpl::if_<
- mpl::has_key<mpl::first<mpl::placeholders::_1>,transition_source_type<mpl::placeholders::_2> >,
- mpl::first<mpl::placeholders::_1>,
- mpl::insert<mpl::first<mpl::placeholders::_1>,
- make_pair_source_state_id<mpl::second<mpl::placeholders::_1 >,
- mpl::placeholders::_2> >
+ ::boost::mpl::fold<
+ stt,::boost::mpl::pair< ::boost::mpl::map< >, ::boost::mpl::int_<0> >,
+ ::boost::mpl::pair<
+ ::boost::mpl::if_<
+ ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
+ transition_source_type< ::boost::mpl::placeholders::_2> >,
+ ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
+ ::boost::mpl::insert< ::boost::mpl::first<mpl::placeholders::_1>,
+ make_pair_source_state_id< ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
+ ::boost::mpl::placeholders::_2> >
>,
- mpl::if_<
- mpl::has_key<mpl::first<mpl::placeholders::_1>,transition_source_type<mpl::placeholders::_2> >,
- mpl::second<mpl::placeholders::_1 >,
- mpl::next<mpl::second<mpl::placeholders::_1 > >
+ ::boost::mpl::if_<
+ ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
+ transition_source_type< ::boost::mpl::placeholders::_2> >,
+ ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
+ ::boost::mpl::next< ::boost::mpl::second<mpl::placeholders::_1 > >
>
> //pair
>::type source_state_ids;
- typedef typename mpl::first<source_state_ids>::type source_state_map;
- typedef typename mpl::second<source_state_ids>::type highest_state_id;
+ typedef typename ::boost::mpl::first<source_state_ids>::type source_state_map;
+ typedef typename ::boost::mpl::second<source_state_ids>::type highest_state_id;
 
 
     typedef typename
- mpl::fold<
- stt,mpl::pair<source_state_map,highest_state_id >,
- mpl::pair<
- mpl::if_<
- mpl::has_key<mpl::first<mpl::placeholders::_1>,transition_target_type<mpl::placeholders::_2> >,
- mpl::first<mpl::placeholders::_1>,
- mpl::insert<mpl::first<mpl::placeholders::_1>,
- make_pair_target_state_id<mpl::second<mpl::placeholders::_1 >,
- mpl::placeholders::_2> >
+ ::boost::mpl::fold<
+ stt,::boost::mpl::pair<source_state_map,highest_state_id >,
+ ::boost::mpl::pair<
+ ::boost::mpl::if_<
+ ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
+ transition_target_type< ::boost::mpl::placeholders::_2> >,
+ ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
+ ::boost::mpl::insert< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
+ make_pair_target_state_id< ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
+ ::boost::mpl::placeholders::_2> >
>,
- mpl::if_<
- mpl::has_key<mpl::first<mpl::placeholders::_1>,transition_target_type<mpl::placeholders::_2> >,
- mpl::second<mpl::placeholders::_1 >,
- mpl::next<mpl::second<mpl::placeholders::_1 > >
+ ::boost::mpl::if_<
+ ::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
+ transition_target_type< ::boost::mpl::placeholders::_2> >,
+ ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
+ ::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
>
> //pair
>::type all_state_ids;
- typedef typename mpl::first<all_state_ids>::type type;
+ typedef typename ::boost::mpl::first<all_state_ids>::type type;
 };
 
 // returns the id of a given state
 template <class stt,class State>
 struct get_state_id
 {
- typedef typename mpl::at<typename generate_state_ids<stt>::type,State>::type type;
+ typedef typename ::boost::mpl::at<typename generate_state_ids<stt>::type,State>::type type;
     enum {value = type::value};
 };
 
@@ -123,10 +126,10 @@
 template <class States>
 struct get_initial_states
 {
- typedef typename mpl::if_<
- mpl::is_sequence<States>,
+ typedef typename ::boost::mpl::if_<
+ ::boost::mpl::is_sequence<States>,
             States,
- typename mpl::push_back<mpl::vector<>,States>::type >::type type;
+ typename ::boost::mpl::push_back< ::boost::mpl::vector<>,States>::type >::type type;
 };
 
 // returns a mpl::int_ containing the size of a region. If the argument is not a sequence, returns 1
@@ -134,28 +137,28 @@
 struct get_number_of_regions
 {
     typedef typename mpl::if_<
- mpl::is_sequence<region>,
- mpl::size<region>,
- mpl::int_<1> >::type type;
+ ::boost::mpl::is_sequence<region>,
+ ::boost::mpl::size<region>,
+ ::boost::mpl::int_<1> >::type type;
 };
 
 // builds a mpl::vector of initial states
 template <class region>
 struct get_regions_as_sequence
 {
- typedef typename mpl::if_<
- mpl::is_sequence<region>,
+ typedef typename ::boost::mpl::if_<
+ ::boost::mpl::is_sequence<region>,
             region,
- typename mpl::push_back<mpl::vector<>,region>::type >::type type;
+ typename ::boost::mpl::push_back< ::boost::mpl::vector<>,region>::type >::type type;
 };
 
 template <class ToCreateSeq>
 struct get_explicit_creation_as_sequence
 {
- typedef typename mpl::if_<
- mpl::is_sequence<ToCreateSeq>,
+ typedef typename ::boost::mpl::if_<
+ ::boost::mpl::is_sequence<ToCreateSeq>,
         ToCreateSeq,
- typename mpl::push_back<mpl::vector<>,ToCreateSeq>::type >::type type;
+ typename ::boost::mpl::push_back< ::boost::mpl::vector<>,ToCreateSeq>::type >::type type;
 };
 
 // returns true if 2 transitions have the same source (used to remove duplicates in search of composite states)
@@ -189,8 +192,8 @@
 {
     // instead of the rows we want only the names of the states (from source)
     typedef typename
- mpl::transform<
- stt,transition_source_type<mpl::placeholders::_1> >::type type;
+ ::boost::mpl::transform<
+ stt,transition_source_type< ::boost::mpl::placeholders::_1> >::type type;
 };
 
 // transform a transition table in a container of target states
@@ -199,8 +202,8 @@
 {
     // instead of the rows we want only the names of the states (from source)
     typedef typename
- mpl::transform<
- stt,transition_target_type<mpl::placeholders::_1> >::type type;
+ ::boost::mpl::transform<
+ stt,transition_target_type< ::boost::mpl::placeholders::_1> >::type type;
 };
 
 template <class stt>
@@ -210,14 +213,14 @@
     typedef typename keep_source_names<stt>::type sources;
     typedef typename keep_target_names<stt>::type targets;
     typedef typename
- mpl::fold<
- sources,mpl::set<>,
- mpl::insert<mpl::placeholders::_1,mpl::placeholders::_2>
+ ::boost::mpl::fold<
+ sources, ::boost::mpl::set<>,
+ ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
>::type source_set;
     typedef typename
- mpl::fold<
+ ::boost::mpl::fold<
             targets,source_set,
- mpl::insert<mpl::placeholders::_1,mpl::placeholders::_2>
+ ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
>::type type;
 };
 
@@ -226,12 +229,14 @@
 struct generate_event_set
 {
     typedef typename
- mpl::fold<
- stt,mpl::set<>,
- mpl::if_<
- mpl::has_key<mpl::placeholders::_1, transition_event<mpl::placeholders::_2> >,
- mpl::placeholders::_1,
- mpl::insert<mpl::placeholders::_1,transition_event<mpl::placeholders::_2> > >
+ ::boost::mpl::fold<
+ stt, ::boost::mpl::set<>,
+ ::boost::mpl::if_<
+ ::boost::mpl::has_key< ::boost::mpl::placeholders::_1,
+ transition_event< ::boost::mpl::placeholders::_2> >,
+ ::boost::mpl::placeholders::_1,
+ ::boost::mpl::insert< ::boost::mpl::placeholders::_1,
+ transition_event< ::boost::mpl::placeholders::_2> > >
>::type type;
 };
 
@@ -239,11 +244,11 @@
 template <class State, class Event>
 struct has_state_delayed_event
 {
- typedef typename mpl::find<typename State::deferred_events,Event>::type found;
- typedef typename mpl::if_<
- boost::is_same<found,typename mpl::end<typename State::deferred_events>::type >,
- mpl::bool_<false>,
- mpl::bool_<true> >::type type;
+ typedef typename ::boost::mpl::find<typename State::deferred_events,Event>::type found;
+ typedef typename ::boost::mpl::if_<
+ ::boost::is_same<found,typename ::boost::mpl::end<typename State::deferred_events>::type >,
+ ::boost::mpl::bool_<false>,
+ ::boost::mpl::bool_<true> >::type type;
 };
 
 // Template used to create dummy entries for initial states not found in the stt.
@@ -275,31 +280,31 @@
     typedef typename get_regions_as_sequence<typename Derived::initial_state>::type init_states;
     // iterate through the initial states and add them in the stt if not already there
     typedef typename
- mpl::fold<
+ ::boost::mpl::fold<
             init_states,stt,
- mpl::if_<
- mpl::has_key<states,mpl::placeholders::_2>,
- mpl::placeholders::_1,
- mpl::insert<mpl::placeholders::_1,mpl::end<mpl::placeholders::_1>,
- not_a_row<mpl::placeholders::_2 > >
+ ::boost::mpl::if_<
+ ::boost::mpl::has_key<states, ::boost::mpl::placeholders::_2>,
+ ::boost::mpl::placeholders::_1,
+ ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end<mpl::placeholders::_1>,
+ not_a_row< ::boost::mpl::placeholders::_2 > >
>
>::type with_init;
     // do the same for states marked as explicitly created
     typedef typename get_explicit_creation_as_sequence<
- typename mpl::eval_if<
+ typename ::boost::mpl::eval_if<
             typename has_explicit_creation<Derived>::type,
             get_explicit_creation<Derived>,
- mpl::vector<> >::type
+ ::boost::mpl::vector<> >::type
>::type explicit_created;
 
     typedef typename
- mpl::fold<
+ ::boost::mpl::fold<
             explicit_created,with_init,
- mpl::if_<
- mpl::has_key<states,mpl::placeholders::_2>,
- mpl::placeholders::_1,
- mpl::insert<mpl::placeholders::_1,mpl::end<mpl::placeholders::_1>,
- not_a_row<mpl::placeholders::_2 > >
+ ::boost::mpl::if_<
+ ::boost::mpl::has_key<states, ::boost::mpl::placeholders::_2>,
+ ::boost::mpl::placeholders::_1,
+ ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end<mpl::placeholders::_1>,
+ not_a_row< ::boost::mpl::placeholders::_2 > >
>
>::type type;
 };
@@ -316,17 +321,17 @@
 struct recursive_get_transition_table
 {
     // get the transition table of the state if it's a state machine
- typedef typename mpl::eval_if<typename is_composite_state<Composite>::type,
+ typedef typename ::boost::mpl::eval_if<typename is_composite_state<Composite>::type,
             get_transition_table<Composite>,
- mpl::vector0<> >::type org_table;
+ ::boost::mpl::vector0<> >::type org_table;
 
     typedef typename generate_state_set<org_table>::type states;
 
     // and for every substate, recursively get the transition table if it's a state machine
- typedef typename mpl::fold<
+ typedef typename ::boost::mpl::fold<
             states,org_table,
- mpl::insert_range<mpl::placeholders::_1,mpl::end<mpl::placeholders::_1>,
- recursive_get_transition_table<mpl::placeholders::_2 > >
+ ::boost::mpl::insert_range< ::boost::mpl::placeholders::_1, ::boost::mpl::end<mpl::placeholders::_1>,
+ recursive_get_transition_table< ::boost::mpl::placeholders::_2 > >
>::type type;
 
 };
@@ -334,12 +339,12 @@
 template <class Transition>
 struct make_vector
 {
- typedef mpl::vector<Transition> type;
+ typedef ::boost::mpl::vector<Transition> type;
 };
 template< typename Entry >
 struct get_first_element_pair_second
 {
- typedef typename mpl::front<typename Entry::second>::type type;
+ typedef typename ::boost::mpl::front<typename Entry::second>::type type;
 };
 
 // returns the owner of an explicit_entry state
@@ -348,33 +353,36 @@
 template <class State,class ContainingSM>
 struct get_owner
 {
- typedef typename mpl::if_<
- typename mpl::not_<typename boost::is_same<typename State::owner,ContainingSM>::type>::type,
- typename State::owner, State >::type type;
+ typedef typename ::boost::mpl::if_<
+ typename ::boost::mpl::not_<typename ::boost::is_same<typename State::owner,ContainingSM>::type>::type,
+ typename State::owner,
+ State >::type type;
 };
 template <class Sequence,class ContainingSM>
 struct get_fork_owner
 {
- typedef typename mpl::front<Sequence>::type seq_front;
- typedef typename mpl::if_<
- typename mpl::not_<typename boost::is_same<typename seq_front::owner,ContainingSM>::type>::type,
- typename seq_front::owner, seq_front >::type type;
+ typedef typename ::boost::mpl::front<Sequence>::type seq_front;
+ typedef typename ::boost::mpl::if_<
+ typename ::boost::mpl::not_<
+ typename ::boost::is_same<typename seq_front::owner,ContainingSM>::type>::type,
+ typename seq_front::owner,
+ seq_front >::type type;
 };
 
 // metafunctions used to find out if a state is entry, exit or something else
 template <class State>
 struct is_pseudo_entry
 {
- typedef typename mpl::if_< typename has_pseudo_entry<State>::type,
- mpl::bool_<true>,mpl::bool_<false>
+ typedef typename ::boost::mpl::if_< typename has_pseudo_entry<State>::type,
+ ::boost::mpl::bool_<true>,::boost::mpl::bool_<false>
>::type type;
 };
 // says if a state is an exit pseudo state
 template <class State>
 struct is_pseudo_exit
 {
- typedef typename mpl::if_< typename has_pseudo_exit<State>::type,
- mpl::bool_<true>,mpl::bool_<false>
+ typedef typename ::boost::mpl::if_< typename has_pseudo_exit<State>::type,
+ ::boost::mpl::bool_<true>, ::boost::mpl::bool_<false>
>::type type;
 };
 
@@ -385,34 +393,36 @@
     typedef typename create_stt<StateType>::type Stt;
     typedef typename generate_state_set<Stt>::type state_list;
 
- typedef mpl::bool_<mpl::count_if<state_list,is_pseudo_exit<mpl::placeholders::_1> >::value != 0> type;
+ typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
+ state_list,is_pseudo_exit< ::boost::mpl::placeholders::_1> >::value != 0> type;
 };
 template <class StateType>
 struct has_exit_pseudo_states
 {
- typedef typename mpl::eval_if<typename is_composite_state<StateType>::type,
+ typedef typename ::boost::mpl::eval_if<typename is_composite_state<StateType>::type,
         has_exit_pseudo_states_helper<StateType>,
- mpl::bool_<false> >::type type;
+ ::boost::mpl::bool_<false> >::type type;
 };
 
 
 // helper to find out if a SM has an active exit state and is therefore waiting for exiting
 template <class StateType,class OwnerFct,class FSM>
 inline
-typename boost::enable_if<typename mpl::and_<typename is_composite_state<FSM>::type,
- typename is_pseudo_exit<StateType>::type>,bool >::type
+typename ::boost::enable_if<typename ::boost::mpl::and_<typename is_composite_state<FSM>::type,
+ typename is_pseudo_exit<StateType>::type>,bool >::type
 is_exit_state_active(FSM& fsm)
 {
     typedef typename OwnerFct::type Composite;
     typedef typename create_stt<Composite>::type stt;
     int state_id = get_state_id<stt,StateType>::type::value;
     Composite& comp = fsm.template get_state<Composite&>();
- return (std::find(comp.current_state().begin(),comp.current_state().end(),state_id)!=comp.current_state().end());
+ return (std::find(comp.current_state().begin(),comp.current_state().end(),state_id)
+ !=comp.current_state().end());
 }
 template <class StateType,class OwnerFct,class FSM>
 inline
-typename boost::disable_if<typename mpl::and_<typename is_composite_state<FSM>::type,
- typename is_pseudo_exit<StateType>::type>,bool >::type
+typename ::boost::disable_if<typename ::boost::mpl::and_<typename is_composite_state<FSM>::type,
+ typename is_pseudo_exit<StateType>::type>,bool >::type
 is_exit_state_active(FSM& fsm)
 {
     return false;
@@ -420,4 +430,4 @@
 
 } } //boost::msm
 
-#endif // METAFUNCTIONS_H
+#endif // BOOST_MSM_METAFUNCTIONS_H

Modified: sandbox/msm/boost/msm/state_machine.hpp
==============================================================================
--- sandbox/msm/boost/msm/state_machine.hpp (original)
+++ sandbox/msm/boost/msm/state_machine.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
@@ -1,6 +1,3 @@
-#ifndef STATEMACHINE_H
-#define STATEMACHINE_H
-
 // Copyright 2008 Christophe Henry
 // henry UNDERSCORE christophe AT hotmail DOT com
 // This is an extended version of the state machine available in the boost::mpl library
@@ -10,10 +7,21 @@
 // under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
-//
+
+#ifndef BOOST_MSM_STATEMACHINE_H
+#define BOOST_MSM_STATEMACHINE_H
+
+#ifndef BOOST_MSM_VISITOR_ARG_SIZE
+#define BOOST_MSM_VISITOR_ARG_SIZE 2 // default max number of arguments
+#endif
+
+#include <vector>
+#include <queue>
+#include <functional>
+#include <numeric>
+#include <utility>
 
 #include <boost/mpl/fold.hpp>
-#include <boost/mpl/reverse_fold.hpp>
 #include <boost/mpl/transform.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/mpl/size.hpp>
@@ -21,11 +29,7 @@
 #include <boost/mpl/insert.hpp>
 #include <boost/mpl/insert_range.hpp>
 #include <boost/mpl/for_each.hpp>
-#include <boost/mpl/filter_view.hpp>
-#include <boost/mpl/greater.hpp>
 #include <boost/mpl/front.hpp>
-#include <boost/mpl/pop_front.hpp>
-#include <boost/mpl/empty.hpp>
 #include <boost/mpl/has_xxx.hpp>
 #include <boost/mpl/logical.hpp>
 
@@ -35,10 +39,6 @@
 #include <boost/smart_ptr.hpp>
 #include <boost/tuple/tuple.hpp>
 
-#include <vector>
-#include <queue>
-#include <functional>
-#include <numeric>
 #include <boost/bind.hpp>
 #include <boost/bind/apply.hpp>
 #include <boost/function.hpp>
@@ -46,460 +46,106 @@
 #include <boost/msm/history_policies.hpp>
 #include <boost/msm/bind_helpers.hpp>
 #include <boost/msm/copy_policies.hpp>
-#include <boost/msm/visitable_policies.hpp>
-
-namespace mpl = boost::mpl;
+#include <boost/msm/common_types.hpp>
+#include <boost/msm/args.hpp>
+#include <boost/msm/dispatch_table.hpp>
+#include <boost/msm/states.hpp>
 
-// traits used for entry/exit states
-BOOST_MPL_HAS_XXX_TRAIT_DEF(no_automatic_create)
-BOOST_MPL_HAS_XXX_TRAIT_DEF(direct_entry)
-BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_entry_state)
+BOOST_MPL_HAS_XXX_TRAIT_DEF(accept_sig)
 
 namespace boost { namespace msm
 {
-// the interface for all states. Defines entry and exit functions. Overwrite to implement for any state needing it.
-struct state_base
-{
- // by default are states not polymorphic. Define this symbol to make them polymorphic
- // for example if you need to use a pointer to a state_base in typeid
-#ifdef POLYMORPHIC_STATES
- virtual ~state_base() {}
-#else
- ~state_base() {}
-#endif
- // used only in conjunction with the VisitableStates state_machine policy
- void accept(VisitorBase&){}
- // empty implementation for the states not wishing to define an entry condition
- // will not be called polymorphic way
- template <class Event>
- void on_entry(Event const& ){}
- template <class Event>
- void on_exit(Event const& ){}
-};
-typedef boost::shared_ptr<state_base> pstate_base;
-
-struct NoSMPtr
-{
- // tags
- typedef mpl::bool_<false> needs_sm;
-};
-struct SMPtr
-{
- // tags
- typedef mpl::bool_<true> needs_sm;
-};
-
-// used for disable_if
-template <int> struct dummy { dummy(int) {} };
-
-// return value for transition handling
-typedef enum
-{
- HANDLED_FALSE=0,
- HANDLED_TRUE =1,
- HANDLED_GUARD_REJECT=2
-} HandledEnum;
-typedef boost::tuple<HandledEnum,const std::vector<int>*> execute_return;
-
-// provides the typedefs and interface. Concrete states derive from it.
-// template argument: pointer-to-fsm policy
-template<class SMPtrPolicy = NoSMPtr>
-struct state : public state_base, SMPtrPolicy
-{
- // tags
- // default: no flag
- typedef mpl::vector<> flag_list;
- //default: no deferred events
- typedef mpl::vector<> deferred_events;
- // by default are states not polymorphic. Define this symbol to make them polymorphic
- // for example if you need to use a pointer to a state_base in typeid
-#ifdef POLYMORPHIC_STATES
- virtual ~state() {}
-#else
- ~state() {}
-#endif
-};
-
-// flags used internally to handle terminate / interrupt states
-struct TerminateFlag {};
-struct InterruptedFlag {};
-template <class EndEvent>
-struct EndInterruptFlag {};
-
-// terminate state simply defines the TerminateFlag flag
-// template argument: pointer-to-fsm policy
-template<class SMPtrPolicy = NoSMPtr>
-struct terminate_state : public state_base, SMPtrPolicy
-{
- // tags
- typedef mpl::vector<boost::msm::TerminateFlag> flag_list;
- //default: no deferred events
- typedef mpl::vector<> deferred_events;
- // by default are states not polymorphic. Define this symbol to make them polymorphic
- // for example if you need to use a pointer to a state_base in typeid
-#ifdef POLYMORPHIC_STATES
- virtual ~terminate_state() {}
-#else
- ~terminate_state() {}
-#endif
-};
-
-// terminate state simply defines the InterruptedFlag and EndInterruptFlag<EndInterruptEvent> flags
-// template argument: event which ends the interrupt
-// template argument: pointer-to-fsm policy
-template <class EndInterruptEvent,class SMPtrPolicy = NoSMPtr>
-struct interrupt_state : public state_base, SMPtrPolicy
-{
- // tags
- typedef mpl::vector<boost::msm::InterruptedFlag,
- boost::msm::EndInterruptFlag<EndInterruptEvent> >
- flag_list;
- //default: no deferred events
- typedef mpl::vector<> deferred_events;
- // by default are states not polymorphic. Define this symbol to make them polymorphic
- // for example if you need to use a pointer to a state_base in typeid
-#ifdef POLYMORPHIC_STATES
- virtual ~interrupt_state() {}
-#else
- ~interrupt_state() {}
-#endif
-};
-
-// not a state but a bunch of extra typedefs to handle direct entry into a composite state. To be derived from
-// template argument: containing composite
-// template argument: zone index of this state
-template <class Composite,int ZoneIndex=-1>
-struct explicit_entry
-{
- typedef int no_automatic_create;
- typedef int explicit_entry_state;
- typedef Composite owner;
- enum {zone_index=ZoneIndex};
- template <class ToTest>
- // metafunction helping determine who needs to create this state
- struct is_owning_composite
- {
- typedef typename boost::is_same<Composite,ToTest>::type type;
- };
-};
-
-// to be derived from. Makes a type an entry (pseudo) state. Actually an almost full-fledged state
-// template argument: containing composite
-// template argument: zone index of this state
-// template argument: pointer-to-fsm policy
-template<class Composite,int ZoneIndex=-1,class SMPtrPolicy = NoSMPtr>
-struct entry_pseudo_state
- : public state_base, explicit_entry<Composite,ZoneIndex> ,SMPtrPolicy
-{
- // tags
- typedef int pseudo_entry;
- // default: no flag
- typedef mpl::vector<> flag_list;
- //default: no deferred events
- typedef mpl::vector<> deferred_events;
- // by default are states not polymorphic. Define this symbol to make them polymorphic
- // for example if you need to use a pointer to a state_base in typeid
-#ifdef POLYMORPHIC_STATES
- virtual ~entry_pseudo_state() {}
-#else
- ~entry_pseudo_state() {}
-#endif
-};
-
-// to be derived from. Makes a state an exit (pseudo) state. Actually an almost full-fledged state
-// template argument: containing composite
-// template argument: event to forward
-// template argument: pointer-to-fsm policy
-template<class Composite,class Event,class SMPtrPolicy = NoSMPtr>
-struct exit_pseudo_state : public state_base , SMPtrPolicy
-{
- // tags
- typedef int pseudo_exit;
- typedef int no_automatic_create;
- typedef Composite owner;
- typedef Event event;
-
- // metafunction helping determine who needs to create this state
- template <class ToTest>
- struct is_owning_composite
- {
- typedef typename boost::is_same<Composite,ToTest>::type type;
- };
- // default: no flag
- typedef mpl::vector< > flag_list;
- //default: no deferred events
- typedef mpl::vector<> deferred_events;
-
- // by default are states not polymorphic. Define this symbol to make them polymorphic
- // for example if you need to use a pointer to a state_base in typeid
-#ifdef POLYMORPHIC_STATES
- virtual ~exit_pseudo_state() {}
-#else
- ~exit_pseudo_state() {}
-#endif
- // forward event to the higher-level FSM
- template <class ForwardEvent>
- void forward_event(ForwardEvent const& incomingEvent)
- {
- // use helper to forward or not
- helper(incomingEvent);
- }
- void set_forward_fct(boost::function<execute_return (Event const&)> fct)
- {
- m_forward = fct;
- }
- exit_pseudo_state():m_forward(){}
- // by assignments, we keep our forwarding functor unchanged as our containing SM did not change
- exit_pseudo_state(exit_pseudo_state<Composite,Event>& rhs){}
- exit_pseudo_state<Composite,Event>& operator= (const exit_pseudo_state<Composite,Event>& )
- {
- return *this;
- }
-private:
- boost::function<execute_return (Event const&)> m_forward;
-
- // helper used to forward an event if it is the one we are supposed to
- template <class ForwardEvent>
- typename boost::enable_if<typename boost::is_convertible<ForwardEvent,Event>::type,void >::type
- helper(ForwardEvent const& incomingEvent,boost::msm::dummy<0> = 0)
- {
- // call if handler set, if not, this state is simply a terminate state
- if (m_forward)
- m_forward(incomingEvent);
- }
- template <class ForwardEvent>
- typename boost::disable_if<typename boost::is_convertible<ForwardEvent,Event>::type,void >::type
- helper(ForwardEvent const& incomingEvent,boost::msm::dummy<1> = 0)
- {
- // Not our event, ignore
- }
-};
-
-// wrapper for mpl::for_each as showed in the C++ Template Metaprogramming ch. 9
-template <class T>
-struct wrap{};
-// event used internally for wrapping a direct entry
-template <class StateType,class Event>
-struct direct_entry_event
-{
- typedef int direct_entry;
- typedef StateType active_state;
-
- direct_entry_event(Event const& evt):m_event(evt){}
- Event const& m_event;
-};
-
-// forward declaration
-template<class Derived,class HistoryPolicy,class VisitablePolicy,class CopyPolicy>
-class state_machine;
-
-// Generates a singleton runtime lookup table that maps current state
-// to a function that makes the SM take its transition on the given
-// Event type.
-template <class Fsm, class HistoryPolicy,class VisitablePolicy, class CopyPolicy,class Stt, class Event>
-struct dispatch_table
-{
- private:
- // This is a table of these function pointers.
- typedef std::pair<int,HandledEnum> (*cell)(Fsm&, int, pstate_base*,Event const&);
- typedef bool (*guard)(Fsm&, Event const&);
-
- // class used to build a chain (or sequence) of transitions for a given event and start state
- // (like an UML diamond). Allows transition conflicts.
- template< typename Seq,typename AnEvent,typename State >
- struct chain_row
- {
- typedef State current_state_type;
- typedef AnEvent event;
-
- // helper for building a disable/enable_if-controlled execute function
- struct execute_helper
- {
- template <class Sequence>
- static std::pair<int,HandledEnum> execute(Fsm& fsm, int state, pstate_base* all_states, Event const& evt,
- typename boost::enable_if<typename mpl::empty<Sequence>::type,void >::type* dmy=0)
- {
- // if at least one guard rejected, this will be ignored, otherwise will generate an error
- return std::make_pair(state,HANDLED_FALSE);
- }
-
- template <class Sequence>
- static std::pair<int,HandledEnum> execute(Fsm& fsm, int state, pstate_base* all_states, Event const& evt,
- typename boost::disable_if<typename mpl::empty<Sequence>::type,void >::type* dmy=0)
- {
- // try the first guard
- typedef typename mpl::front<Sequence>::type first_row;
- std::pair<int,HandledEnum> res =
- first_row::execute(fsm,state,all_states,evt);
- if (HANDLED_TRUE!=res.second)
- {
- // if the first rejected, move on to the next one
- std::pair<int,HandledEnum> sub_res =
- execute<typename mpl::pop_front<Sequence>::type>(fsm,state,all_states,evt);
- // if at least one guards rejects, the event will not generate a call to no_transition
- HandledEnum handled = ((HANDLED_GUARD_REJECT==sub_res.second) || (HANDLED_GUARD_REJECT==res.second))?
- HANDLED_GUARD_REJECT:sub_res.second;
- return std::make_pair(sub_res.first,handled);
- }
- return res;
- }
- };
- // Take the transition action and return the next state.
- static std::pair<int,HandledEnum> execute(Fsm& fsm, int state, pstate_base* all_states, Event const& evt)
- {
- // forward to helper
- return execute_helper::template execute<Seq>(fsm,state,all_states,evt);
- }
- };
- // nullary metafunction whose only job is to prevent early evaluation of _1
- template< typename Entry >
- struct make_chain_row_from_map_entry
- {
- typedef chain_row<typename Entry::second,Event,
- typename Entry::first > type;
- };
- // Compute the maximum state value in the sm so we know how big
- // to make the table
- typedef typename generate_state_set<Stt>::type state_list;
- BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
-
- // A function object for use with mpl::for_each that stuffs
- // transitions into cells.
- struct init_cell
- {
- init_cell(dispatch_table* self_)
- : self(self_)
- {}
-
- // Cell initializer function object, used with mpl::for_each
- template <class Transition>
- void operator()(Transition const&) const
- {
- typedef typename create_stt<Fsm>::type stt;
- BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,typename Transition::current_state_type>::value));
- self->entries[state_id] = &Transition::execute;
- }
-
- dispatch_table* self;
- };
- struct default_init_cell
- {
- default_init_cell(dispatch_table* self_,cell* tofill_entries_)
- : self(self_),tofill_entries(tofill_entries_)
- {}
- // Cell default-initializer function object, used with mpl::for_each
- // initializes with call_no_transition or defer_transition
- template <class State>
- typename boost::disable_if<typename has_state_delayed_event<State,Event>::type,void >::type
- operator()(boost::msm::wrap<State> const&,boost::msm::dummy<0> = 0)
- {
- typedef typename create_stt<Fsm>::type stt;
- BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
- cell call_no_transition = &state_machine<Fsm,HistoryPolicy,VisitablePolicy,CopyPolicy>::call_no_transition;
- tofill_entries[state_id] = call_no_transition;
- }
- template <class State>
- typename boost::enable_if<typename has_state_delayed_event<State,Event>::type,void >::type
- operator()(boost::msm::wrap<State> const&,boost::msm::dummy<1> = 0)
- {
- typedef typename create_stt<Fsm>::type stt;
- BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
- cell call_no_transition = &state_machine<Fsm,HistoryPolicy,VisitablePolicy,CopyPolicy>::defer_transition;
- tofill_entries[state_id] = call_no_transition;
- }
- dispatch_table* self;
- cell* tofill_entries;
- };
- public:
- // initialize the dispatch table for a given Event and Fsm
- dispatch_table()
- {
- // Initialize cells for no transition
- mpl::for_each<typename generate_state_set<Stt>::type, boost::msm::wrap<mpl::placeholders::_1> >
- (default_init_cell(this,entries));
-
- // build chaining rows for rows coming from the same state and the current event
- // first we build a map of sequence for every source
- // in reverse order so that the frow's are handled first (UML priority)
- typedef typename mpl::reverse_fold<
- // filter on event
- mpl::filter_view
- <Stt, boost::is_same<transition_event<mpl::placeholders::_>, Event> >,
- // build a map
- mpl::map<>,
- mpl::if_<
- // if we already have a row on this source state
- mpl::has_key<mpl::placeholders::_1,transition_source_type<mpl::placeholders::_2> >,
- // insert a new element in the value type
- mpl::insert<mpl::placeholders::_1,
- mpl::pair<transition_source_type<mpl::placeholders::_2>,
- mpl::push_back<mpl::at<mpl::placeholders::_1,
- transition_source_type<mpl::placeholders::_2> >,
- mpl::placeholders::_2 > > >,
- // first row on this source state, make a vector with 1 element
- mpl::insert<mpl::placeholders::_1,
- mpl::pair<transition_source_type<mpl::placeholders::_2>,
- make_vector<mpl::placeholders::_2> > >
- >
- >::type map_of_row_seq;
- // and then build chaining rows for all source states having more than 1 row
- typedef typename mpl::fold<
- map_of_row_seq,mpl::vector<>,
- mpl::if_<mpl::greater<mpl::size<mpl::second<mpl::placeholders::_2> >,mpl::int_<1> >,
- // we need row chaining
- mpl::push_back<mpl::placeholders::_1,
- make_chain_row_from_map_entry<mpl::placeholders::_2> >,
- // just one row, no chaining, we rebuild the row like it was before
- mpl::push_back<mpl::placeholders::_1, get_first_element_pair_second<mpl::placeholders::_2> >
- > >::type chained_rows;
- // Go back and fill in cells for matching transitions.
- mpl::for_each<
- chained_rows
- >(init_cell(this));
- }
-
- // The singleton instance.
- static const dispatch_table instance;
-
- public: // data members
- cell entries[max_state];
-};
-
 
 // This declares the statically-initialized dispatch_table instance.
-template <class Fsm, class HistoryPolicy,class VisitablePolicy, class CopyPolicy,class Stt, class Event>
-const dispatch_table<Fsm, HistoryPolicy,VisitablePolicy,CopyPolicy,Stt, Event>
-dispatch_table<Fsm, HistoryPolicy,VisitablePolicy,CopyPolicy,Stt, Event>::instance;
+template <class Fsm, class HistoryPolicy,class BaseState, class CopyPolicy,class Stt, class Event>
+const dispatch_table<Fsm, HistoryPolicy,BaseState,CopyPolicy,Stt, Event>
+dispatch_table<Fsm, HistoryPolicy,BaseState,CopyPolicy,Stt, Event>::instance;
 
 // CRTP base class for state machines. Pass the actual FSM class as
 // the Derived parameter.
 template<class Derived,class HistoryPolicy=NoHistory,
- class VisitablePolicy=NotVisitableStates, class CopyPolicy=NoCopy>
-class state_machine : public state_base,public VisitablePolicy,CopyPolicy
+ class BaseState=default_base_state, class CopyPolicy=NoCopy>
+class state_machine : public state_base<BaseState>,CopyPolicy
 {
 private:
- typedef boost::function<
+ typedef ::boost::function<
         execute_return ()> transition_fct;
- typedef boost::function<
+ typedef ::boost::function<
         execute_return () > deferred_fct;
     typedef std::queue<deferred_fct > deferred_events_queue_t;
     typedef std::queue<transition_fct > events_queue_t;
- typedef bool (*flag_handler)(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>&);
-
+ typedef bool (*flag_handler)(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>&);
     // all state machines are friend with each other to allow embedding any of them in another fsm
     template <class ,class ,class,class > friend class state_machine;
 
+ // helper to add, if needed, visitors to all states
+ // version without visitors
+ template <class StateType,class Enable=void>
+ struct visitor_fct_helper
+ {
+ public:
+ visitor_fct_helper(){}
+ void fill_visitors(int number_of_states)
+ {
+ }
+ template <class FCT>
+ void insert(int index,FCT fct)
+ {
+ }
+ template <class VISITOR>
+ void execute(int index,VISITOR vis)
+ {
+ }
+ };
+ // version with visitors
+ template <class StateType>
+ struct visitor_fct_helper<StateType,typename ::boost::enable_if<has_accept_sig<StateType> >::type>
+ {
+ public:
+ visitor_fct_helper():m_state_visitors(){}
+ void fill_visitors(int number_of_states)
+ {
+ m_state_visitors.resize(number_of_states);
+ }
+ template <class FCT>
+ void insert(int index,FCT fct)
+ {
+ m_state_visitors[index]=fct;
+ }
+ void execute(int index)
+ {
+ m_state_visitors[index]();
+ }
+
+#define MSM_VISITOR_HELPER_EXECUTE_SUB(z, n, unused) ARG ## n vis ## n
+#define MSM_VISITOR_HELPER_EXECUTE(z, n, unused) \
+ template <BOOST_PP_ENUM_PARAMS(n, class ARG)> \
+ void execute(int index BOOST_PP_COMMA_IF(n) \
+ BOOST_PP_ENUM(n, MSM_VISITOR_HELPER_EXECUTE_SUB, ~ ) ) \
+ { \
+ m_state_visitors[index](BOOST_PP_ENUM_PARAMS(n,vis)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_HELPER_EXECUTE, ~)
+#undef MSM_VISITOR_HELPER_EXECUTE
+#undef MSM_VISITOR_HELPER_EXECUTE_SUB
+ private:
+ typedef typename StateType::accept_sig::type visitor_fct;
+ typedef std::vector<visitor_fct> visitors;
+
+ visitors m_state_visitors;
+ };
+
  public:
     // tags
     typedef int composite_tag;
 
     // default: no flag
- typedef mpl::vector0<> flag_list;
+ typedef ::boost::mpl::vector0<> flag_list;
     //default: no deferred events
- typedef mpl::vector<> deferred_events;
+ typedef ::boost::mpl::vector<> deferred_events;
     // in case someone needs to know
- typedef HistoryPolicy history_policy;
- typedef CopyPolicy copy_policy;
+ typedef HistoryPolicy history_policy;
+ typedef CopyPolicy copy_policy;
 
     struct InitEvent { };
     // flag handling
@@ -511,6 +157,7 @@
     {
      typedef std::logical_or<bool> type;
     };
+ typedef ::boost::shared_ptr<BaseState> pBaseState;
 
     // Member functions
 
@@ -518,7 +165,8 @@
     void start()
     {
                 typedef typename get_initial_states<typename Derived::initial_state>::type init_states;
- mpl::for_each<init_states, boost::msm::wrap<mpl::placeholders::_1> >(call_init<InitEvent>(&m_state_list[0],InitEvent()));
+ ::boost::mpl::for_each<init_states, boost::msm::wrap<mpl::placeholders::_1> >
+ (call_init<InitEvent>(&m_state_list[0],InitEvent()));
     }
 
     // Main function used by clients of the derived FSM to make
@@ -529,26 +177,27 @@
         // extend the table with tables from composite states
         typedef typename extend_table<Derived>::type complete_table;
         // use this table as if it came directly from the user
- typedef dispatch_table<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy,complete_table,Event> table;
+ typedef dispatch_table<Derived,HistoryPolicy,BaseState,CopyPolicy,complete_table,Event> table;
 
         HandledEnum ret_handled=HANDLED_FALSE;
         // if the state machine is terminated, do not handle any event
- if (is_flag_active<boost::msm::TerminateFlag>())
- return boost::make_tuple(HANDLED_TRUE,&this->m_states);
+ if (is_flag_active< ::boost::msm::TerminateFlag>())
+ return ::boost::make_tuple(HANDLED_TRUE,&this->m_states);
         // if the state machine is interrupted, do not handle any event
         // unless the event is the end interrupt event
- if (is_flag_active<boost::msm::InterruptedFlag>() && !is_flag_active<boost::msm::EndInterruptFlag<Event> >())
- return boost::make_tuple(HANDLED_TRUE,&this->m_states);
+ if ( is_flag_active< ::boost::msm::InterruptedFlag>() &&
+ !is_flag_active< ::boost::msm::EndInterruptFlag<Event> >())
+ return ::boost::make_tuple(HANDLED_TRUE,&this->m_states);
 
         // if we are already processing an event
         if (m_event_processing)
         {
             // event has to be put into the queue
- execute_return (state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>::*pf) (Event const& evt) =
- &state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>::process_event;
- transition_fct f = boost::bind(pf,this,evt);
+ execute_return (state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>::*pf) (Event const& evt) =
+ &state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>::process_event;
+ transition_fct f = ::boost::bind(pf,this,evt);
             m_events_queue.push(f);
- return boost::make_tuple(HANDLED_TRUE,&this->m_states);
+ return ::boost::make_tuple(HANDLED_TRUE,&this->m_states);
         }
         else
         {
@@ -604,7 +253,7 @@
             // now check if some events were generated in a transition and was not handled
             // because of another processing, and if yes, start handling them
             process_message_queue();
- return boost::make_tuple(ret_handled,&this->m_states);
+ return ::boost::make_tuple(ret_handled,&this->m_states);
         }
     }
 
@@ -615,12 +264,12 @@
     }
 
     // return the state whose id is passed or 0 if not found
- // caution if you need this, you probably need to define POLYMORPHIC_STATES
- const state_base* get_state_by_id(int id) const
+ // caution if you need this, you probably need polymorphic states
+ const BaseState* get_state_by_id(int id) const
     {
         typedef typename create_stt<Derived>::type stt;
         typedef typename generate_state_set<stt>::type state_list;
- BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
+ BOOST_STATIC_CONSTANT(int, max_state = ( ::boost::mpl::size<state_list>::value));
         BOOST_ASSERT(id < (max_state));
         if (id < max_state)
             return (this->m_state_list[id]).get();
@@ -635,19 +284,19 @@
     // get a state
     // as a pointer
     template <class State>
- State get_state(typename boost::enable_if<typename boost::is_pointer<State>::type,void >::type* =0)
+ State get_state(typename ::boost::enable_if<typename ::boost::is_pointer<State>::type,void >::type* =0)
     {
         typedef typename create_stt<Derived>::type stt;
- return &(static_cast<typename boost::add_reference<typename boost::remove_pointer<State>::type>::type >
- (*(m_state_list[get_state_id<stt,typename boost::remove_pointer<State>::type>::type::value])));
+ return &(static_cast<typename boost::add_reference<typename ::boost::remove_pointer<State>::type>::type >
+ (*(m_state_list[get_state_id<stt,typename ::boost::remove_pointer<State>::type>::type::value])));
     }
     // as a reference
     template <class State>
- State get_state(typename boost::enable_if<typename boost::is_reference<State>::type,void >::type* =0)
+ State get_state(typename ::boost::enable_if<typename ::boost::is_reference<State>::type,void >::type* =0)
     {
         typedef typename create_stt<Derived>::type stt;
         return static_cast<State >
- (*(m_state_list[get_state_id<stt,typename boost::remove_reference<State>::type>::type::value]));
+ (*(m_state_list[get_state_id<stt,typename ::boost::remove_reference<State>::type>::type::value]));
     }
 
     // checks if a flag is active using the BinaryOp as folding function
@@ -659,12 +308,12 @@
         typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
         return std::accumulate(m_states.begin(),
             m_states.end(),false,
- boost::bind(typename BinaryOp::type(),
- boost::bind(boost::apply<bool>(),
- boost::bind(deref<flag_handler>(),
- boost::bind(plus2<flag_handler*,int>(),
+ ::boost::bind(typename BinaryOp::type(),
+ ::boost::bind(::boost::apply<bool>(),
+ ::boost::bind(::boost::msm::deref<flag_handler>(),
+ ::boost::bind(::boost::msm::plus2<flag_handler*,int>(),
                         flags_entries, _2)),
- boost::ref(*this)), _1));
+ ::boost::ref(*this)), _1));
     }
     // checks if a flag is active using no binary op if 1 region, or OR if > 1 regions
     template <class Flag>
@@ -675,16 +324,31 @@
     }
     // visit the currently active states (if these are defined as visitable
     // by implementing accept)
- void visit_current_states(VisitorBase& vis)
+ void visit_current_states()
     {
         typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
         for (int i=0; i<nr_regions::value;++i)
         {
- VisitablePolicy::execute(m_states[i],vis);
+ m_visitors.execute(m_states[i]);
         }
     }
+#define MSM_VISIT_STATE_SUB(z, n, unused) ARG ## n vis ## n
+#define MSM_VISIT_STATE_EXECUTE(z, n, unused) \
+ template <BOOST_PP_ENUM_PARAMS(n, class ARG)> \
+ void visit_current_states(BOOST_PP_ENUM(n, MSM_VISIT_STATE_SUB, ~ ) ) \
+ { \
+ typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions; \
+ for (int i=0; i<nr_regions::value;++i) \
+ { \
+ m_visitors.execute(m_states[i],BOOST_PP_ENUM_PARAMS(n,vis)); \
+ } \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISIT_STATE_EXECUTE, ~)
+#undef MSM_VISIT_STATE_EXECUTE
+#undef MSM_VISIT_STATE_SUB
+
  protected: // interface for the derived class
- typedef std::vector<pstate_base> pstate_base_list;
+ typedef std::vector<pBaseState> pstate_base_list;
 
      // helper used to fill the initial states
      struct init_states
@@ -693,7 +357,7 @@
 
          // History initializer function object, used with mpl::for_each
          template <class State>
- void operator()(boost::msm::wrap<State> const&)
+ void operator()(::boost::msm::wrap<State> const&)
          {
              typedef typename create_stt<Derived>::type stt;
              m_initial_states.push_back(get_state_id<stt,State>::type::value);
@@ -702,8 +366,7 @@
      };
      // Construct with the default initial states
      state_machine()
- :state_base()
- ,VisitablePolicy()
+ :state_base<BaseState>()
          ,CopyPolicy()
          ,m_states()
              ,m_events_queue()
@@ -712,15 +375,15 @@
              ,m_state_list()
          ,m_event_processing(false)
          ,m_is_included(false)
+ ,m_visitors()
      {
          typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
          m_states.reserve(nr_regions::value);
          // build a sequence of regions if needed
          typedef typename get_regions_as_sequence<typename Derived::initial_state>::type initial_states;
          // initialize our list of states with the ones defined in Derived::initial_state
- mpl::for_each<
- initial_states, boost::msm::wrap<mpl::placeholders::_1>
- >(init_states(m_states));
+ ::boost::mpl::for_each< initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
+ (init_states(m_states));
          m_history.set_initial_states(m_states);
          // create states
          fill_states(this);
@@ -728,8 +391,7 @@
      // template constructor. Needed only for sub-fsms having exit pseudo states.
      template <class ContainingSM>
      state_machine(ContainingSM* containing_sm)
- :state_base()
- ,VisitablePolicy()
+ :state_base<BaseState>()
          ,CopyPolicy()
          ,m_states()
          ,m_events_queue()
@@ -738,22 +400,22 @@
          ,m_state_list()
          ,m_event_processing(false)
          ,m_is_included(true)
+ ,m_visitors()
      {
          typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
          m_states.reserve(nr_regions::value);
          // build a sequence of regions if needed
          typedef typename get_regions_as_sequence<typename Derived::initial_state>::type initial_states;
          // initialize our list of states with the ones defined in Derived::initial_state
- mpl::for_each<
- initial_states, boost::msm::wrap<mpl::placeholders::_1>
- >(init_states(m_states));
+ ::boost::mpl::for_each< initial_states, boost::msm::wrap<mpl::placeholders::_1> >
+ (init_states(m_states));
          m_history.set_initial_states(m_states);
          // create states
          fill_states(containing_sm);
      }
      // assignment operator using the copy policy to decide if non_copyable, shallow or deep copying is necessary
- state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& operator=
- (state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy> const& rhs)
+ state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>& operator=
+ (state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy> const& rhs)
      {
          if (this != &rhs)
          {
@@ -762,8 +424,8 @@
          }
         return *this;
      }
- state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>
- (state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy> const& rhs):CopyPolicy(rhs)
+ state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>
+ (state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy> const& rhs):CopyPolicy(rhs)
      {
         if (this != &rhs)
         {
@@ -801,25 +463,24 @@
         // if the source has no automatic creation (i.e. is an exit pseudo state), then
         // current_state_type becomes the result of get_owner
         // meaning the containing SM from which the exit occurs
- typedef typename mpl::eval_if<
+ typedef typename ::boost::mpl::eval_if<
             typename has_no_automatic_create<T1>::type,
             get_owner<T1,Derived>,
- mpl::identity<T1> >::type current_state_type;
+ ::boost::mpl::identity<T1> >::type current_state_type;
 
         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
- typedef typename mpl::eval_if<
- typename mpl::is_sequence<T2>::type,
+ typedef typename ::boost::mpl::eval_if<
+ typename ::boost::mpl::is_sequence<T2>::type,
             get_fork_owner<T2,Derived>,
- mpl::eval_if<
+ ::boost::mpl::eval_if<
                     typename has_no_automatic_create<T2>::type,
                     get_owner<T2,Derived>,
- mpl::identity<T2> >
+ ::boost::mpl::identity<T2> >
>::type next_state_type;
 
         typedef Event event;
- typedef mpl::bool_<false> internal_event;
 
         // if a guard condition is here, call it to check that the event is accepted
         static bool check_guard(Derived& fsm,Event const& evt)
@@ -829,7 +490,7 @@
             return false;
         }
         // Take the transition action and return the next state.
- static std::pair<int,HandledEnum> execute(Derived& fsm, int state, pstate_base* all_states, Event const& evt)
+ static std::pair<int,HandledEnum> execute(Derived& fsm, int state, pBaseState* all_states, Event const& evt)
         {
             typedef typename create_stt<Derived>::type stt;
 
@@ -837,7 +498,8 @@
             BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
             BOOST_ASSERT(state == (current_state));
             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
- if (!boost::is_same<T1,current_state_type>::value && !is_exit_state_active<T1,get_owner<T1,Derived> >(fsm))
+ if (!::boost::is_same<T1,current_state_type>::value &&
+ !is_exit_state_active<T1,get_owner<T1,Derived> >(fsm))
             {
                 return std::make_pair(current_state,HANDLED_FALSE);
             }
@@ -872,25 +534,24 @@
         // if the source has no automatic creation (i.e. is an exit pseudo state), then
         // current_state_type becomes the result of get_owner
         // meaning the containing SM from which the exit occurs
- typedef typename mpl::eval_if<
+ typedef typename ::boost::mpl::eval_if<
             typename has_no_automatic_create<T1>::type,
             get_owner<T1,Derived>,
- mpl::identity<T1> >::type current_state_type;
+ ::boost::mpl::identity<T1> >::type current_state_type;
 
         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
- typedef typename mpl::eval_if<
- typename mpl::is_sequence<T2>::type,
+ typedef typename ::boost::mpl::eval_if<
+ typename ::boost::mpl::is_sequence<T2>::type,
             get_fork_owner<T2,Derived>,
- mpl::eval_if<
+ ::boost::mpl::eval_if<
                     typename has_no_automatic_create<T2>::type,
                     get_owner<T2,Derived>,
- mpl::identity<T2> >
+ ::boost::mpl::identity<T2> >
>::type next_state_type;
 
         typedef Event event;
- typedef mpl::bool_<false> internal_event;
 
         // if a guard condition is defined, call it to check that the event is accepted
         static bool check_guard(Derived& fsm,Event const& evt)
@@ -900,14 +561,15 @@
             return false;
         }
         // Take the transition action and return the next state.
- static std::pair<int,HandledEnum> execute(Derived& fsm, int state, pstate_base* all_states, Event const& evt)
+ static std::pair<int,HandledEnum> execute(Derived& fsm, int state, pBaseState* all_states, Event const& evt)
         {
             typedef typename create_stt<Derived>::type stt;
             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
             BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
             BOOST_ASSERT(state == (current_state));
             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
- if (!boost::is_same<T1,current_state_type>::value && !is_exit_state_active<T1,get_owner<T1,Derived> >(fsm))
+ if (!::boost::is_same<T1,current_state_type>::value &&
+ !is_exit_state_active<T1,get_owner<T1,Derived> >(fsm))
             {
                 return std::make_pair(current_state,HANDLED_FALSE);
             }
@@ -937,28 +599,27 @@
         // if the source has no automatic creation (i.e. is an exit pseudo state), then
         // current_state_type becomes the result of get_owner
         // meaning the containing SM from which the exit occurs
- typedef typename mpl::eval_if<
+ typedef typename ::boost::mpl::eval_if<
             typename has_no_automatic_create<T1>::type,
             get_owner<T1,Derived>,
- mpl::identity<T1> >::type current_state_type;
+ ::boost::mpl::identity<T1> >::type current_state_type;
 
         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
- typedef typename mpl::eval_if<
- typename mpl::is_sequence<T2>::type,
+ typedef typename ::boost::mpl::eval_if<
+ typename ::boost::mpl::is_sequence<T2>::type,
             get_fork_owner<T2,Derived>,
- mpl::eval_if<
+ ::boost::mpl::eval_if<
                     typename has_no_automatic_create<T2>::type,
                     get_owner<T2,Derived>,
- mpl::identity<T2> >
+ ::boost::mpl::identity<T2> >
>::type next_state_type;
 
         typedef Event event;
- typedef mpl::bool_<false> internal_event;
 
         // Take the transition action and return the next state.
- static std::pair<int,HandledEnum> execute(Derived& fsm, int state, pstate_base* all_states, Event const& evt)
+ static std::pair<int,HandledEnum> execute(Derived& fsm, int state, pBaseState* all_states, Event const& evt)
         {
             typedef typename create_stt<Derived>::type stt;
             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
@@ -966,7 +627,8 @@
             BOOST_ASSERT(state == (current_state));
 
             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
- if (!boost::is_same<T1,current_state_type>::value && !is_exit_state_active<T1,get_owner<T1,Derived> >(fsm))
+ if (!::boost::is_same<T1,current_state_type>::value &&
+ !is_exit_state_active<T1,get_owner<T1,Derived> >(fsm))
             {
                 return std::make_pair(current_state,HANDLED_FALSE);
             }
@@ -995,28 +657,27 @@
         // if the source has no automatic creation (i.e. is an exit pseudo state), then
         // current_state_type becomes the result of get_owner
         // meaning the containing SM from which the exit occurs
- typedef typename mpl::eval_if<
+ typedef typename ::boost::mpl::eval_if<
                 typename has_no_automatic_create<T1>::type,
                 get_owner<T1,Derived>,
- mpl::identity<T1> >::type current_state_type;
+ ::boost::mpl::identity<T1> >::type current_state_type;
 
         // if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
         // else if Target is an explicit_entry, next_state_type becomes the result of get_owner
         // meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
- typedef typename mpl::eval_if<
- typename mpl::is_sequence<T2>::type,
+ typedef typename ::boost::mpl::eval_if<
+ typename ::boost::mpl::is_sequence<T2>::type,
             get_fork_owner<T2,Derived>,
- mpl::eval_if<
+ ::boost::mpl::eval_if<
                     typename has_no_automatic_create<T2>::type,
                     get_owner<T2,Derived>,
- mpl::identity<T2> >
+ ::boost::mpl::identity<T2> >
>::type next_state_type;
 
         typedef Event event;
- typedef mpl::bool_<false> internal_event;
 
         // Take the transition action and return the next state.
- static std::pair<int,HandledEnum> execute(Derived& fsm, int state, pstate_base* all_states, Event const& evt)
+ static std::pair<int,HandledEnum> execute(Derived& fsm, int state, pBaseState* all_states, Event const& evt)
         {
             typedef typename create_stt<Derived>::type stt;
             BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
@@ -1024,7 +685,8 @@
             BOOST_ASSERT(state == (current_state));
 
             // if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
- if (!boost::is_same<T1,current_state_type>::value && !is_exit_state_active<T1,get_owner<T1,Derived> >(fsm))
+ if (!::boost::is_same<T1,current_state_type>::value &&
+ !is_exit_state_active<T1,get_owner<T1,Derived> >(fsm))
             {
                 return std::make_pair(current_state,HANDLED_FALSE);
             }
@@ -1042,7 +704,7 @@
     template <class Event>
         struct call_init
         {
- call_init(pstate_base* states,Event const& an_event):all_states(states),evt(an_event){}
+ call_init(pBaseState* states,Event const& an_event):all_states(states),evt(an_event){}
                 template <class State>
                 void operator()(boost::msm::wrap<State> const&)
                 {
@@ -1050,14 +712,14 @@
                         execute_entry<State>(all_states[get_state_id<stt,State>::type::value].get(),evt);
                 }
         private:
- pstate_base* all_states;
+ pBaseState* all_states;
         Event const& evt;
         };
     // helper for flag handling. Uses OR by default on orthogonal zones.
     template <class Flag,bool orthogonalStates>
     struct FlagHelper
     {
- static bool helper(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& sm,flag_handler* )
+ static bool helper(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>& sm,flag_handler* )
         {
             // by default we use OR to accumulate the flags
             return sm.is_flag_active<Flag,Flag_OR>();
@@ -1066,7 +728,7 @@
     template <class Flag>
     struct FlagHelper<Flag,false>
     {
- static bool helper(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& sm,flag_handler* flags_entries)
+ static bool helper(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>& sm,flag_handler* flags_entries)
         {
             // just one active state, so we can call operator[] with 0
             return flags_entries[sm.current_state()[0]](sm);
@@ -1077,15 +739,15 @@
     template <class StateType,class Flag>
     struct FlagHandler
     {
- static bool flag_true(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& )
+ static bool flag_true(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>& )
         {
             return true;
         }
- static bool flag_false(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& )
+ static bool flag_false(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>& )
         {
             return false;
         }
- static bool forward(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& fsm)
+ static bool forward(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>& fsm)
         {
             typedef typename create_stt<Derived>::type stt;
             return (static_cast<StateType& >
@@ -1098,14 +760,14 @@
     private:
         // helper function, helps hiding the forward function for non-state machines states.
         template <class T>
- typename boost::enable_if<typename is_composite_state<T>::type,void >::type
+ typename ::boost::enable_if<typename is_composite_state<T>::type,void >::type
             helper (flag_handler* an_entry,int offset,boost::msm::dummy<0> = 0 )
         {
             // composite => forward
             an_entry[offset] = &FlagHandler<T,Flag>::forward;
         }
         template <class T>
- typename boost::disable_if<typename is_composite_state<T>::type,void >::type
+ typename ::boost::disable_if<typename is_composite_state<T>::type,void >::type
             helper (flag_handler* an_entry,int offset,boost::msm::dummy<1> = 0 )
         {
             // default no flag
@@ -1121,10 +783,10 @@
 
         // Flags initializer function object, used with mpl::for_each
         template <class StateType>
- void operator()(boost::msm::wrap<StateType> const& )
+ void operator()( ::boost::msm::wrap<StateType> const& )
         {
             typedef typename StateType::flag_list flags;
- typedef typename mpl::contains<flags,Flag >::type found;
+ typedef typename ::boost::mpl::contains<flags,Flag >::type found;
             typedef typename is_composite_state<StateType>::type composite;
             typedef typename create_stt<Derived>::type stt;
 
@@ -1151,7 +813,8 @@
 
         static flag_handler flags_entries[max_state];
         // build a state list
- mpl::for_each<state_list, boost::msm::wrap<mpl::placeholders::_1> >(init_flags<Flag>(flags_entries));
+ ::boost::mpl::for_each<state_list, boost::msm::wrap< ::boost::mpl::placeholders::_1> >
+ (init_flags<Flag>(flags_entries));
         return flags_entries;
     }
 
@@ -1159,7 +822,7 @@
     template <class State, class Enable=void>
     struct create_state_helper
     {
- static void set_sm(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* ,pstate_base )
+ static void set_sm(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>* ,pBaseState )
         {
                 // state doesn't need its sm
         }
@@ -1168,7 +831,7 @@
     template <class State>
     struct create_state_helper<State,typename boost::enable_if<typename State::needs_sm >::type>
     {
- static void set_sm(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* sm,pstate_base new_state)
+ static void set_sm(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>* sm,pBaseState new_state)
         {
                 // create and set the fsm
                 static_cast<State*>(new_state.get())->set_sm_ptr(static_cast<Derived*>(sm));
@@ -1179,13 +842,13 @@
     template<class ContainingSM>
     struct add_state
     {
- add_state(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* self_,ContainingSM* sm)
+ add_state(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>* self_,ContainingSM* sm)
                 : self(self_),containing_sm(sm){}
 
         // State is a sub fsm with exit pseudo states and gets a pointer to this fsm, so it can build a callback
         template <class StateType>
- typename boost::enable_if<
- typename has_exit_pseudo_states<StateType>::type,state_base* >::type
+ typename ::boost::enable_if<
+ typename has_exit_pseudo_states<StateType>::type,BaseState* >::type
         new_state_helper(boost::msm::dummy<0> = 0) const
         {
             return new StateType(containing_sm);
@@ -1193,44 +856,77 @@
         // State is a sub fsm without exit pseudo states and does not get a callback to this fsm
                 // or state is a normal state and needs nothing except creation
         template <class StateType>
- typename boost::enable_if<
- typename mpl::and_<typename mpl::not_<typename has_exit_pseudo_states<StateType>::type>::type,
- typename mpl::not_<typename is_pseudo_exit<StateType>::type>::type
- >::type,state_base*>::type
- new_state_helper(boost::msm::dummy<1> = 0) const
+ typename ::boost::enable_if<
+ typename ::boost::mpl::and_<typename ::boost::mpl::not_
+ <typename has_exit_pseudo_states<StateType>::type>::type,
+ typename ::boost::mpl::not_
+ <typename is_pseudo_exit<StateType>::type>::type
+ >::type,BaseState*>::type
+ new_state_helper( ::boost::msm::dummy<1> = 0) const
         {
             return new StateType;
         }
         // state is exit pseudo state and gets callback to target fsm
         template <class StateType>
- typename boost::enable_if<typename is_pseudo_exit<StateType>::type,state_base* >::type
- new_state_helper(boost::msm::dummy<2> = 0) const
+ typename ::boost::enable_if<typename is_pseudo_exit<StateType>::type,BaseState* >::type
+ new_state_helper( ::boost::msm::dummy<2> = 0) const
         {
- state_base* to_return = new StateType();
+ BaseState* to_return = new StateType();
             execute_return (ContainingSM::*pf) (typename StateType::event const& evt)=
                 &ContainingSM::process_event;
- boost::function<execute_return (typename StateType::event const&)> fct =
- boost::bind(pf,containing_sm,_1);
+ ::boost::function<execute_return (typename StateType::event const&)> fct =
+ ::boost::bind(pf,containing_sm,_1);
             static_cast<StateType*>(to_return)->set_forward_fct(fct);
             return to_return;
         }
         // for every defined state in the sm
         template <class State>
- void operator()(boost::msm::wrap<State> const&) const
+ void operator()( ::boost::msm::wrap<State> const&) const
         {
             //create a new state with the defined id and type
             typedef typename create_stt<Derived>::type stt;
             BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
 
- pstate_base new_state (this->new_state_helper<State>());
+ pBaseState new_state (this->new_state_helper<State>());
             self->m_state_list[state_id]= new_state;
             create_state_helper<State>::set_sm(self,new_state);
             // create a visitor callback
- self->insert(state_id,boost::bind(&State::accept,
- static_cast<State*>(new_state.get()),_1) );
+ visitor_helper<State>(state_id,new_state.get());
         }
     private:
- state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* self;
+ // support possible use of a visitor if accept_sig is defined
+ template <class StateType>
+ typename ::boost::enable_if<typename has_accept_sig<StateType>::type,void >::type
+ visitor_helper(int id,BaseState* astate,::boost::msm::dummy<0> = 0) const
+ {
+ visitor_args<StateType,StateType::accept_sig::args_number>::helper(self,id,astate);
+ }
+ template <class StateType>
+ typename ::boost::disable_if<typename has_accept_sig<StateType>::type,void >::type
+ visitor_helper(int id,BaseState* astate,::boost::msm::dummy<1> = 0) const
+ {
+ // nothing to do
+ }
+ // main unspecialized helper class
+ template <class StateType,int ARGS>
+ struct visitor_args;
+#define MSM_VISITOR_ARGS_SUB(z, n, unused) BOOST_PP_CAT(_,BOOST_PP_ADD(n,1))
+#define MSM_VISITOR_ARGS_EXECUTE(z, n, unused) \
+ template <class StateType> \
+ struct visitor_args<StateType,n> \
+ { \
+ static void helper (state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>* sm, \
+ int id,BaseState* astate) \
+ { \
+ sm->m_visitors.insert(id, boost::bind(&StateType::accept, \
+ static_cast<StateType*>(astate) BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, MSM_VISITOR_ARGS_SUB, ~) )); \
+ } \
+ };
+BOOST_PP_REPEAT(BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_ARGS_EXECUTE, ~)
+#undef MSM_VISITOR_ARGS_EXECUTE
+#undef MSM_VISITOR_ARGS_SUB
+
+ state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>* self;
         ContainingSM* containing_sm;
     };
 
@@ -1238,54 +934,78 @@
      struct copy_helper
      {
          copy_helper(pstate_base_list& to_fill,const pstate_base_list& rhs,
- state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* sm):
+ state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>* sm):
             m_tofill_states(to_fill),m_rhs(rhs),m_sm(sm){}
          template <class StateType>
- void operator()(boost::msm::wrap<StateType> const& )
+ void operator()( ::boost::msm::wrap<StateType> const& )
          {
             typedef typename create_stt<Derived>::type stt;
             BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,StateType>::type::value));
             if (m_rhs.empty())
                     return;
- pstate_base copiedState
+ pBaseState copiedState
                     (new StateType (*static_cast<StateType*> (m_rhs[state_id].get())));
             m_tofill_states[state_id] = copiedState;
+ // possibly also set the visitor
+ visitor_helper<StateType>(state_id,copiedState.get());
+
             // and for states that keep a pointer to the fsm, reset the pointer
             create_state_helper<StateType>::set_sm(m_sm,copiedState);
          }
+ template <class StateType>
+ typename ::boost::enable_if<typename has_accept_sig<StateType>::type,void >::type
+ visitor_helper(int id,BaseState* astate) const
+ {
+ m_sm->m_visitors.insert(id, ::boost::bind(&StateType::accept,
+ static_cast<StateType*>(astate),_1));
+ }
+ template <class StateType>
+ typename ::boost::disable_if<typename has_accept_sig<StateType>::type,void >::type
+ visitor_helper(int id,BaseState* astate) const
+ {
+ // nothing to do
+ }
+
          pstate_base_list& m_tofill_states;
          const pstate_base_list& m_rhs;
          state_machine<Derived,HistoryPolicy,
- VisitablePolicy,CopyPolicy>* m_sm;
+ BaseState,CopyPolicy>* m_sm;
      };
 
      // copy functions for shallow or deep copy (no need of a 3rd version for NoCopy as noncopyable handles it)
      template <class IsShallowCopy>
- typename boost::disable_if<typename IsShallowCopy::type,void >::type
- do_copy (state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy> const& rhs,
- boost::msm::dummy<0> = 0)
+ typename ::boost::disable_if<typename IsShallowCopy::type,void >::type
+ do_copy (state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy> const& rhs,
+ ::boost::msm::dummy<0> = 0)
      {
          // deep copy simply assigns the data
          m_states = rhs.m_states;
          m_events_queue = rhs.m_events_queue;
+ m_deferred_events_queue = rhs.m_deferred_events_queue;
          m_history = rhs.m_history;
+ m_event_processing = rhs.m_event_processing;
+ m_is_included = rhs.m_is_included;
          // except for the states themselves, which get duplicated
          typedef typename create_stt<Derived>::type Stt;
 
          typedef typename generate_state_set<Stt>::type state_list;
- mpl::for_each<state_list, boost::msm::wrap<mpl::placeholders::_1> >(copy_helper(m_state_list,rhs.m_state_list,this));
+ ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
+ (copy_helper(m_state_list,rhs.m_state_list,this));
      }
      template <class IsShallowCopy>
- typename boost::enable_if<typename IsShallowCopy::type,void >::type
- do_copy (state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy> const& rhs,
- boost::msm::dummy<1> = 0)
+ typename ::boost::enable_if<typename IsShallowCopy::type,void >::type
+ do_copy (state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy> const& rhs,
+ ::boost::msm::dummy<1> = 0)
      {
          // shallow copy simply assigns the data
          m_states = rhs.m_states;
          m_events_queue = rhs.m_events_queue;
+ m_deferred_events_queue = rhs.m_deferred_events_queue;
          m_history = rhs.m_history;
          m_state_list = rhs.m_state_list;
+ m_event_processing = rhs.m_event_processing;
          m_is_included = rhs.m_is_included;
+ m_visitors = rhs.m_visitors;
      }
 
      // helper used to call the correct entry/exit method
@@ -1293,11 +1013,11 @@
      template<class Event,bool is_entry>
      struct entry_exit_helper
      {
- entry_exit_helper(int id,Event const& e,pstate_base* states):state_id(id),evt(e),all_states(states){}
+ entry_exit_helper(int id,Event const& e,pBaseState* states):state_id(id),evt(e),all_states(states){}
          // helper for entry actions
          template <class IsEntry,class State>
- typename boost::enable_if<typename IsEntry::type,void >::type
- helper(boost::msm::dummy<0> = 0)
+ typename ::boost::enable_if<typename IsEntry::type,void >::type
+ helper( ::boost::msm::dummy<0> = 0)
          {
              typedef typename create_stt<Derived>::type stt;
              BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,State>::value));
@@ -1309,7 +1029,7 @@
          // helper for exit actions
          template <class IsEntry,class State>
          typename boost::disable_if<typename IsEntry::type,void >::type
- helper(boost::msm::dummy<1> = 0)
+ helper( ::boost::msm::dummy<1> = 0)
          {
              typedef typename create_stt<Derived>::type stt;
              BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,State>::value));
@@ -1320,14 +1040,14 @@
          }
          // iterates through all states to find the one to be activated
          template <class State>
- void operator()(boost::msm::wrap<State> const&)
+ void operator()( ::boost::msm::wrap<State> const&)
          {
- entry_exit_helper<Event,is_entry>::template helper<mpl::bool_<is_entry>,State >();
+ entry_exit_helper<Event,is_entry>::template helper< ::boost::mpl::bool_<is_entry>,State >();
          }
      private:
          int state_id;
          Event const& evt;
- pstate_base* all_states;
+ pBaseState* all_states;
      };
      // start for states machines which are themselves embedded in other state machines (composites)
          template <class Event>
@@ -1339,7 +1059,7 @@
          for (int i=0; i<nr_regions::value;++i)
          {
              //forward the event for handling by sub state machines
- mpl::for_each<state_list, boost::msm::wrap<mpl::placeholders::_1> >
+ ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
                  (entry_exit_helper<Event,true>(m_states[i],incomingEvent,&m_state_list[0]));
          }
      }
@@ -1347,11 +1067,11 @@
      // helper used to set the correct state as active state upon entry into a fsm
      struct direct_event_start_helper
      {
- direct_event_start_helper(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* self_):self(self_){}
+ direct_event_start_helper(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>* self_):self(self_){}
          // this variant is for the standard case, entry due to activation of the containing FSM
          template <class EventType>
- typename boost::disable_if<typename has_direct_entry<EventType>::type,void>::type
- operator()(EventType const& evt,boost::msm::dummy<0> = 0)
+ typename ::boost::disable_if<typename has_direct_entry<EventType>::type,void>::type
+ operator()(EventType const& evt, ::boost::msm::dummy<0> = 0)
          {
              (static_cast<Derived*>(self))->on_entry(evt);
              self->start(evt);
@@ -1359,14 +1079,16 @@
 
          // this variant is for the direct entry case (just one entry, not a sequence of entries)
          template <class EventType>
- typename boost::enable_if<
- typename mpl::and_<typename mpl::not_< typename is_pseudo_entry<typename EventType::active_state>::type >::type,
- typename mpl::and_<typename has_direct_entry<EventType>::type,
- typename mpl::not_<typename mpl::is_sequence
- <typename EventType::active_state>::type >::type
+ typename ::boost::enable_if<
+ typename ::boost::mpl::and_<
+ typename ::boost::mpl::not_< typename is_pseudo_entry<
+ typename EventType::active_state>::type >::type,
+ typename ::boost::mpl::and_<typename has_direct_entry<EventType>::type,
+ typename ::boost::mpl::not_<typename ::boost::mpl::is_sequence
+ <typename EventType::active_state>::type >::type
>::type>::type,void
>::type
- operator()(EventType const& evt,boost::msm::dummy<1> = 0)
+ operator()(EventType const& evt, ::boost::msm::dummy<1> = 0)
          {
              (static_cast<Derived*>(self))->on_entry(evt);
              typedef typename create_stt<Derived>::type stt;
@@ -1381,16 +1103,20 @@
 
          // this variant is for the fork entry case (a sequence on entries)
          template <class EventType>
- typename boost::enable_if<
- typename mpl::and_<typename mpl::not_< typename is_pseudo_entry<typename EventType::active_state>::type >::type,
- typename mpl::and_<typename has_direct_entry<EventType>::type,
- typename mpl::is_sequence<typename EventType::active_state>::type
- >::type>::type,void
+ typename ::boost::enable_if<
+ typename ::boost::mpl::and_<
+ typename ::boost::mpl::not_<
+ typename is_pseudo_entry<typename EventType::active_state>::type >::type,
+ typename ::boost::mpl::and_<typename has_direct_entry<EventType>::type,
+ typename ::boost::mpl::is_sequence<
+ typename EventType::active_state>::type
+ >::type>::type,void
>::type
- operator()(EventType const& evt,boost::msm::dummy<2> = 0)
+ operator()(EventType const& evt, ::boost::msm::dummy<2> = 0)
          {
              (static_cast<Derived*>(self))->on_entry(evt);
- mpl::for_each<typename EventType::active_state,boost::msm::wrap<mpl::placeholders::_1> >
+ ::boost::mpl::for_each<typename EventType::active_state,
+ ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
                                                         (fork_helper<EventType>(self,evt));
              // set the correct zones, the others (if any) will be default/history initialized
              self->start(evt.m_event);
@@ -1398,10 +1124,10 @@
 
          // this variant is for the pseudo state entry case
          template <class EventType>
- typename boost::enable_if<
+ typename ::boost::enable_if<
              typename is_pseudo_entry<typename EventType::active_state >::type,void
- >::type
- operator()(EventType const& evt,boost::msm::dummy<3> = 0)
+ >::type
+ operator()(EventType const& evt, ::boost::msm::dummy<3> = 0)
          {
              // entry on the FSM
              (static_cast<Derived*>(self))->on_entry(evt);
@@ -1416,25 +1142,25 @@
          }
      private:
          // helper for the fork case, does almost like the direct entry
- state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* self;
+ state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>* self;
          template <class EventType>
          struct fork_helper
          {
- fork_helper(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* self_,EventType const& evt_):
+ fork_helper(state_machine<Derived,HistoryPolicy,BaseState,CopyPolicy>* self_,EventType const& evt_):
                 helper_self(self_),helper_evt(evt_){}
              template <class StateType>
- void operator()(boost::msm::wrap<StateType> const& )
+ void operator()( ::boost::msm::wrap<StateType> const& )
              {
                  typedef typename create_stt<Derived>::type stt;
                  int state_id = get_state_id<stt,StateType>::value;
                  BOOST_STATIC_ASSERT(StateType::zone_index >= 0);
- BOOST_STATIC_ASSERT
- (StateType::zone_index <= get_number_of_regions<typename Derived::initial_state>::type::value);
+ BOOST_STATIC_ASSERT(StateType::zone_index <=
+ get_number_of_regions<typename Derived::initial_state>::type::value);
                  helper_self->m_states[StateType::zone_index] = state_id;
              }
          private:
              state_machine<Derived,HistoryPolicy,
- VisitablePolicy,CopyPolicy>* helper_self;
+ BaseState,CopyPolicy>* helper_self;
              EventType const& helper_evt;
          };
      };
@@ -1467,7 +1193,7 @@
         {
             // first recursively exit the sub machines
             // forward the event for handling by sub state machines
- mpl::for_each<state_list, boost::msm::wrap<mpl::placeholders::_1> >
+ ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
                 (entry_exit_helper<Event,false>(m_states[i],incomingEvent,&m_state_list[0]));
         }
         // then call our own exit
@@ -1478,17 +1204,17 @@
 
     // no transition for event.
     template <class Event>
- static std::pair<int,HandledEnum> call_no_transition(Derived& , int state, pstate_base* ,Event const& )
+ static std::pair<int,HandledEnum> call_no_transition(Derived& , int state, pBaseState* ,Event const& )
     {
         return std::make_pair(state,HANDLED_FALSE);
     }
     // called for deferred events. Address set in the dispatch_table at init
     template <class Event>
- static std::pair<int,HandledEnum> defer_transition(Derived& fsm, int state, pstate_base*,Event const& e)
+ static std::pair<int,HandledEnum> defer_transition(Derived& fsm, int state, pBaseState*,Event const& e)
     {
         execute_return (Derived::*pf) (Event const& evt)= &Derived::process_event;
         Event temp (e);
- boost::function<execute_return () > f= boost::bind(pf,&fsm,temp);
+ ::boost::function<execute_return () > f= ::boost::bind(pf,&fsm,temp);
         fsm.post_deferred_event(f);
         return std::make_pair(state,HANDLED_TRUE);
     }
@@ -1527,7 +1253,7 @@
     template <class StateType,class EventType>
     static
         typename boost::enable_if<typename is_composite_state<StateType>::type,void >::type
- execute_entry(state_base* astate,EventType const& evt,boost::msm::dummy<0> = 0)
+ execute_entry(BaseState* astate,EventType const& evt,boost::msm::dummy<0> = 0)
     {
         // calls on_entry on the fsm then handles direct entries, fork, entry pseudo state
         (static_cast<StateType*>(astate))->entry(evt);
@@ -1535,10 +1261,10 @@
     // variant for states
     template <class StateType,class EventType>
     static
- typename boost::disable_if<
- typename mpl::or_<typename is_composite_state<StateType>::type,
- typename is_pseudo_exit<StateType>::type >::type,void >::type
- execute_entry(state_base* astate,EventType const& evt,boost::msm::dummy<1> = 0)
+ typename ::boost::disable_if<
+ typename ::boost::mpl::or_<typename is_composite_state<StateType>::type,
+ typename is_pseudo_exit<StateType>::type >::type,void >::type
+ execute_entry(BaseState* astate,EventType const& evt, ::boost::msm::dummy<1> = 0)
     {
         // simple call to on_entry
         (static_cast<StateType*>(astate))->on_entry(evt);
@@ -1546,8 +1272,8 @@
     // variant for exit pseudo states
     template <class StateType,class EventType>
     static
- typename boost::enable_if<typename is_pseudo_exit<StateType>::type,void >::type
- execute_entry(state_base* astate,EventType const& evt,boost::msm::dummy<2> = 0)
+ typename ::boost::enable_if<typename is_pseudo_exit<StateType>::type,void >::type
+ execute_entry(BaseState* astate,EventType const& evt, ::boost::msm::dummy<2> = 0)
     {
         // calls on_entry on the state then forward the event to the transition which should be defined inside the
         // contained fsm
@@ -1556,15 +1282,15 @@
     }
     template <class StateType,class EventType>
     static
- typename boost::enable_if<typename is_composite_state<StateType>::type,void >::type
- execute_exit(state_base* astate,EventType const& evt,boost::msm::dummy<0> = 0)
+ typename ::boost::enable_if<typename is_composite_state<StateType>::type,void >::type
+ execute_exit(BaseState* astate,EventType const& evt, ::boost::msm::dummy<0> = 0)
     {
         (static_cast<StateType*>(astate))->exit(evt);
     }
     template <class StateType,class EventType>
     static
- typename boost::disable_if<typename is_composite_state<StateType>::type,void >::type
- execute_exit(state_base* astate,EventType const& evt,boost::msm::dummy<1> = 0)
+ typename ::boost::disable_if<typename is_composite_state<StateType>::type,void >::type
+ execute_exit(BaseState* astate,EventType const& evt, ::boost::msm::dummy<1> = 0)
     {
         // simple call to on_exit
         (static_cast<StateType*>(astate))->on_exit(evt);
@@ -1573,18 +1299,20 @@
     // helper allowing special handling of direct entries / fork
     template <class StateType,class TargetType,class EventType>
     static
- typename boost::disable_if<
- typename mpl::or_<typename has_explicit_entry_state<TargetType>::type,mpl::is_sequence<TargetType> >::type,void>::type
- convert_event_and_execute_entry(state_base* astate,EventType const& evt,boost::msm::dummy<1> = 0)
+ typename ::boost::disable_if<
+ typename ::boost::mpl::or_<typename has_explicit_entry_state<TargetType>::type,
+ ::boost::mpl::is_sequence<TargetType> >::type,void>::type
+ convert_event_and_execute_entry(BaseState* astate,EventType const& evt, ::boost::msm::dummy<1> = 0)
     {
         // if the target is a normal state, do the standard entry handling
         execute_entry<StateType>(astate,evt);
     }
     template <class StateType,class TargetType,class EventType>
     static
- typename boost::enable_if<
- typename mpl::or_<typename has_explicit_entry_state<TargetType>::type,mpl::is_sequence<TargetType> >::type,void >::type
- convert_event_and_execute_entry(state_base* astate,EventType const& evt,boost::msm::dummy<0> = 0)
+ typename ::boost::enable_if<
+ typename ::boost::mpl::or_<typename has_explicit_entry_state<TargetType>::type,
+ ::boost::mpl::is_sequence<TargetType> >::type,void >::type
+ convert_event_and_execute_entry(BaseState* astate,EventType const& evt, ::boost::msm::dummy<0> = 0)
     {
         // for the direct entry, pack the event in a wrapper so that we handle it differently during fsm entry
         execute_entry<StateType>(astate,direct_entry_event<TargetType,EventType>(evt));
@@ -1599,10 +1327,9 @@
         BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
         // allocate the place without reallocation
         m_state_list.resize(max_state);
- VisitablePolicy::fill_visitors(max_state);
- mpl::for_each<
- state_list,boost::msm::wrap<mpl::placeholders::_1>
- >(add_state<ContainingSM>(this,containing_sm));
+ m_visitors.fill_visitors(max_state);
+ ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
+ (add_state<ContainingSM>(this,containing_sm));
     }
 
     // Template used to form forwarding rows in the transition table for every row of a composite SM
@@ -1615,10 +1342,9 @@
         typedef T1 current_state_type;
         typedef T1 next_state_type;
         typedef Event event;
- typedef mpl::bool_<true> internal_event;
 
         // Take the transition action and return the next state.
- static std::pair<int,HandledEnum> execute(Derived& fsm, int state, pstate_base* ,Event const& evt)
+ static std::pair<int,HandledEnum> execute(Derived& fsm, int state, pBaseState* ,Event const& evt)
         {
                 execute_return res =
                 (static_cast<T1& > (*(fsm.m_state_list[state]))).process_event(evt);
@@ -1640,11 +1366,10 @@
         typedef typename recursive_get_transition_table<Composite>::type original_table;
         // and add for every event a forwarding row
         typedef typename generate_event_set<original_table>::type all_events;
- typedef typename mpl::fold<
- all_events, mpl::vector<>,
- mpl::push_back<mpl::placeholders::_1,
- /*typename mpl::apply<make_frow<mpl::placeholders::_,mpl::placeholders::_>,Composite,mpl::placeholders::_2 >::type*/
- frow<Composite,mpl::placeholders::_2> > >::type type;
+ typedef typename ::boost::mpl::fold<
+ all_events, ::boost::mpl::vector<>,
+ ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
+ frow<Composite, ::boost::mpl::placeholders::_2> > >::type type;
     };
 
     // extends the transition table with rows from composite states
@@ -1657,13 +1382,14 @@
                 typedef typename generate_state_set<stt>::type states;
         // for every state, add its transition table (if any)
         // transformed as frow
- typedef typename mpl::fold<states,stt,
- mpl::insert_range<mpl::placeholders::_1,mpl::end<mpl::placeholders::_1>,
- get_transition_table_as_frow<mpl::placeholders::_2> >
+ typedef typename ::boost::mpl::fold<states,stt,
+ ::boost::mpl::insert_range< ::boost::mpl::placeholders::_1,
+ ::boost::mpl::end< ::boost::mpl::placeholders::_1>,
+ get_transition_table_as_frow< ::boost::mpl::placeholders::_2> >
>::type type;
     };
 private:
- template <class Fsm, class History,class Visitable, class Copy,class Stt, class Event>
+ template <class Fsm, class History,class UserBaseState, class Copy,class Stt, class Event>
     friend struct dispatch_table;
     template <typename T1,class Event> friend struct frow;
 
@@ -1675,7 +1401,9 @@
     pstate_base_list m_state_list;
     bool m_event_processing;
     bool m_is_included;
+ visitor_fct_helper<BaseState>
+ m_visitors;
 };
 
 } } // boost::msm
-#endif //STATEMACHINE_H
+#endif //BOOST_MSM_STATEMACHINE_H

Added: sandbox/msm/boost/msm/states.hpp
==============================================================================
--- (empty file)
+++ sandbox/msm/boost/msm/states.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,218 @@
+// Copyright 2008 Christophe Henry
+// henry UNDERSCORE christophe AT hotmail DOT com
+// This is an extended version of the state machine available in the boost::mpl library
+// Distributed under the same license as the original.
+// Copyright for the original version:
+// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
+// under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MSM_STATES_H
+#define BOOST_MSM_STATES_H
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/function.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/msm/common_types.hpp>
+
+
+// traits used for entry/exit states
+BOOST_MPL_HAS_XXX_TRAIT_DEF(no_automatic_create)
+BOOST_MPL_HAS_XXX_TRAIT_DEF(direct_entry)
+BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_entry_state)
+
+namespace boost { namespace msm
+{
+// default base: non-polymorphic, not visitable
+struct default_base_state
+{
+ ~default_base_state(){}
+};
+// default polymorphic base state. Derive all states from it to get polymorphic behavior
+struct polymorphic_state
+{
+ virtual ~polymorphic_state() {}
+};
+
+// the interface for all states. Defines entry and exit functions. Overwrite to implement for any state needing it.
+template<class USERBASE>
+struct state_base : USERBASE
+{
+ typedef USERBASE user_state_base;
+
+ // empty implementation for the states not wishing to define an entry condition
+ // will not be called polymorphic way
+ template <class Event>
+ void on_entry(Event const& ){}
+ template <class Event>
+ void on_exit(Event const& ){}
+};
+
+struct NoSMPtr
+{
+ // tags
+ typedef ::boost::mpl::bool_<false> needs_sm;
+};
+struct SMPtr
+{
+ // tags
+ typedef ::boost::mpl::bool_<true> needs_sm;
+};
+
+// provides the typedefs and interface. Concrete states derive from it.
+// template argument: pointer-to-fsm policy
+template<class BASE = default_base_state,class SMPtrPolicy = NoSMPtr>
+struct state : public state_base<BASE>, SMPtrPolicy
+{
+ // tags
+ // default: no flag
+ typedef ::boost::mpl::vector<> flag_list;
+ //default: no deferred events
+ typedef ::boost::mpl::vector<> deferred_events;
+};
+
+// flags used internally to handle terminate / interrupt states
+struct TerminateFlag {};
+struct InterruptedFlag {};
+template <class EndEvent>
+struct EndInterruptFlag {};
+
+// terminate state simply defines the TerminateFlag flag
+// template argument: pointer-to-fsm policy
+template<class BASE = default_base_state,class SMPtrPolicy = NoSMPtr>
+struct terminate_state : public state_base<BASE>, SMPtrPolicy
+{
+ // tags
+ typedef ::boost::mpl::vector<boost::msm::TerminateFlag> flag_list;
+ //default: no deferred events
+ typedef ::boost::mpl::vector<> deferred_events;
+};
+
+// terminate state simply defines the InterruptedFlag and EndInterruptFlag<EndInterruptEvent> flags
+// template argument: event which ends the interrupt
+// template argument: pointer-to-fsm policy
+template <class EndInterruptEvent,class BASE = default_base_state,class SMPtrPolicy = NoSMPtr>
+struct interrupt_state : public state_base<BASE>, SMPtrPolicy
+{
+ // tags
+ typedef ::boost::mpl::vector<boost::msm::InterruptedFlag,
+ boost::msm::EndInterruptFlag<EndInterruptEvent> >
+ flag_list;
+ //default: no deferred events
+ typedef ::boost::mpl::vector<> deferred_events;
+};
+
+// not a state but a bunch of extra typedefs to handle direct entry into a composite state. To be derived from
+// template argument: containing composite
+// template argument: zone index of this state
+template <class Composite,int ZoneIndex=-1>
+struct explicit_entry
+{
+ typedef int no_automatic_create;
+ typedef int explicit_entry_state;
+ typedef Composite owner;
+ enum {zone_index=ZoneIndex};
+ template <class ToTest>
+ // metafunction helping determine who needs to create this state
+ struct is_owning_composite
+ {
+ typedef typename ::boost::is_same<Composite,ToTest>::type type;
+ };
+};
+
+// to be derived from. Makes a type an entry (pseudo) state. Actually an almost full-fledged state
+// template argument: containing composite
+// template argument: zone index of this state
+// template argument: pointer-to-fsm policy
+template<class Composite,int ZoneIndex=-1,class BASE = default_base_state,class SMPtrPolicy = NoSMPtr>
+struct entry_pseudo_state
+ : public state_base<BASE>, explicit_entry<Composite,ZoneIndex> ,SMPtrPolicy
+{
+ // tags
+ typedef int pseudo_entry;
+ // default: no flag
+ typedef ::boost::mpl::vector<> flag_list;
+ //default: no deferred events
+ typedef ::boost::mpl::vector<> deferred_events;
+};
+
+// to be derived from. Makes a state an exit (pseudo) state. Actually an almost full-fledged state
+// template argument: containing composite
+// template argument: event to forward
+// template argument: pointer-to-fsm policy
+template<class Composite,class Event,class BASE = default_base_state,class SMPtrPolicy = NoSMPtr>
+struct exit_pseudo_state : public state_base<BASE> , SMPtrPolicy
+{
+ // tags
+ typedef int pseudo_exit;
+ typedef int no_automatic_create;
+ typedef Composite owner;
+ typedef Event event;
+
+ // metafunction helping determine who needs to create this state
+ template <class ToTest>
+ struct is_owning_composite
+ {
+ typedef typename boost::is_same<Composite,ToTest>::type type;
+ };
+ // default: no flag
+ typedef ::boost::mpl::vector< > flag_list;
+ //default: no deferred events
+ typedef ::boost::mpl::vector<> deferred_events;
+
+ // forward event to the higher-level FSM
+ template <class ForwardEvent>
+ void forward_event(ForwardEvent const& incomingEvent)
+ {
+ // use helper to forward or not
+ helper(incomingEvent);
+ }
+ void set_forward_fct(::boost::function<execute_return (Event const&)> fct)
+ {
+ m_forward = fct;
+ }
+ exit_pseudo_state():m_forward(){}
+ // by assignments, we keep our forwarding functor unchanged as our containing SM did not change
+ exit_pseudo_state(exit_pseudo_state<Composite,Event,BASE,SMPtrPolicy>& rhs){}
+ exit_pseudo_state<Composite,Event,BASE,SMPtrPolicy>& operator= (const exit_pseudo_state<Composite,Event,BASE,SMPtrPolicy>& )
+ {
+ return *this;
+ }
+private:
+ ::boost::function<execute_return (Event const&)> m_forward;
+
+ // helper used to forward an event if it is the one we are supposed to
+ template <class ForwardEvent>
+ typename ::boost::enable_if<typename ::boost::is_convertible<ForwardEvent,Event>::type,void >::type
+ helper(ForwardEvent const& incomingEvent,boost::msm::dummy<0> = 0)
+ {
+ // call if handler set, if not, this state is simply a terminate state
+ if (m_forward)
+ m_forward(incomingEvent);
+ }
+ template <class ForwardEvent>
+ typename ::boost::disable_if<typename ::boost::is_convertible<ForwardEvent,Event>::type,void >::type
+ helper(ForwardEvent const& incomingEvent,boost::msm::dummy<1> = 0)
+ {
+ // Not our event, ignore
+ }
+};
+
+// event used internally for wrapping a direct entry
+template <class StateType,class Event>
+struct direct_entry_event
+{
+ typedef int direct_entry;
+ typedef StateType active_state;
+
+ direct_entry_event(Event const& evt):m_event(evt){}
+ Event const& m_event;
+};
+
+}}
+
+#endif //BOOST_MSM_STATES_H

Modified: sandbox/msm/boost/msm/tools.hpp
==============================================================================
--- sandbox/msm/boost/msm/tools.hpp (original)
+++ sandbox/msm/boost/msm/tools.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
@@ -1,6 +1,3 @@
-#ifndef TOOLS_H
-#define TOOLS_H
-
 // Copyright 2008 Christophe Henry
 // henry UNDERSCORE christophe AT hotmail DOT com
 // This is an extended version of the state machine available in the boost::mpl library
@@ -10,9 +7,14 @@
 // under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
-//
+
+#ifndef BOOST_MSM_TOOLS_H
+#define BOOST_MSM_TOOLS_H
+
+
 #include <string>
-#include "metafunctions.hpp"
+#include <iostream>
+#include <boost/msm/metafunctions.hpp>
 
 namespace boost { namespace msm
 {
@@ -62,4 +64,4 @@
 };
 
 } } //boost::msm
-#endif //TOOLS_H
\ No newline at end of file
+#endif //BOOST_MSM_TOOLS_H

Deleted: sandbox/msm/boost/msm/visitable_policies.hpp
==============================================================================
--- sandbox/msm/boost/msm/visitable_policies.hpp 2009-02-11 17:08:58 EST (Wed, 11 Feb 2009)
+++ (empty file)
@@ -1,71 +0,0 @@
-#ifndef VISITABLE_POLICIES_H
-#define VISITABLE_POLICIES_H
-// Copyright 2008 Christophe Henry
-// henry UNDERSCORE christophe AT hotmail DOT com
-// This is an extended version of the state machine available in the boost::mpl library
-// Distributed under the same license as the original.
-// Copyright for the original version:
-// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
-// under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <vector>
-#include <boost/function.hpp>
-
-
-namespace boost { namespace msm
-{
-// base class for states wanting to be visited
-struct VisitorBase
-{
- virtual ~VisitorBase(){}
-};
-
- // dummy policy when visitable states are not desired
- class NotVisitableStates
- {
- public:
- NotVisitableStates(){}
- protected:
- void fill_visitors(int number_of_states)
- {
- }
- template <class FCT>
- void insert(int index,FCT fct)
- {
- }
- void execute(int index,VisitorBase& vis)
- {
- }
- };
-
- // policy adding support of visitable states
- class VisitableStates
- {
- public:
- VisitableStates():m_state_visitors(){}
- protected:
- void fill_visitors(int number_of_states)
- {
- m_state_visitors.resize(number_of_states);
- }
- template <class FCT>
- void insert(int index,FCT fct)
- {
- m_state_visitors[index]=fct;
- }
- void execute(int index,VisitorBase& vis)
- {
- m_state_visitors[index](vis);
- }
- private:
- typedef boost::function<void (VisitorBase&)> visitor_fct;
- typedef std::vector<visitor_fct> visitors;
- visitors m_state_visitors;
- };
-} } //boost::msm
-
-
-#endif //VISITABLE_POLICIES_H


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk