|
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