Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r65817 - in trunk/boost/msm: . back front/euml
From: christophe.j.henry_at_[hidden]
Date: 2010-10-07 16:49:31


Author: chenry
Date: 2010-10-07 16:49:29 EDT (Thu, 07 Oct 2010)
New Revision: 65817
URL: http://svn.boost.org/trac/boost/changeset/65817

Log:
Added construction of a fsm passing a proto expression containing concrete states.
Added:
   trunk/boost/msm/back/fold_to_list.hpp (contents, props changed)
   trunk/boost/msm/proto_config.hpp (contents, props changed)
Text files modified:
   trunk/boost/msm/back/state_machine.hpp | 73 ++++++++++++++++++++++++++++++++++++++-
   trunk/boost/msm/front/euml/common.hpp | 17 --------
   2 files changed, 71 insertions(+), 19 deletions(-)

Added: trunk/boost/msm/back/fold_to_list.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/msm/back/fold_to_list.hpp 2010-10-07 16:49:29 EDT (Thu, 07 Oct 2010)
@@ -0,0 +1,56 @@
+// Copyright 2008 Christophe Henry
+// henry UNDERSCORE christophe AT hotmail DOT com
+// This is taken from Boost.Proto's documentation
+// Copyright for the original version:
+// Copyright 2008 Eric Niebler. 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_BACK_FOLD_TO_LIST_H
+#define BOOST_MSM_BACK_FOLD_TO_LIST_H
+
+#include <boost/msm/proto_config.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
+#include <boost/fusion/container/list/cons.hpp>
+
+namespace boost { namespace msm { namespace back
+{
+ struct state_copy_tag
+ {
+ };
+ ::boost::proto::terminal<state_copy_tag>::type const states_={{}};
+ struct FoldToList
+ : ::boost::proto::or_<
+ // Don't add the states_ terminal to the list
+ ::boost::proto::when<
+ ::boost::proto::terminal< state_copy_tag >
+ , ::boost::proto::_state
+ >
+ // Put all other terminals at the head of the
+ // list that we're building in the "state" parameter
+ , ::boost::proto::when<
+ ::boost::proto::terminal< ::boost::proto::_>
+ , boost::fusion::cons< ::boost::proto::_value, ::boost::proto::_state>(
+ ::boost::proto::_value, ::boost::proto::_state
+ )
+ >
+ // For left-shift operations, first fold the right
+ // child to a list using the current state. Use
+ // the result as the state parameter when folding
+ // the left child to a list.
+ , ::boost::proto::when<
+ ::boost::proto::shift_left<FoldToList, FoldToList>
+ , FoldToList(
+ ::boost::proto::_left
+ , ::boost::proto::call<FoldToList( ::boost::proto::_right, ::boost::proto::_state )>
+ )
+ >
+ >
+ {};
+
+}}}
+
+#endif //BOOST_MSM_BACK_FOLD_TO_LIST_H
+

Modified: trunk/boost/msm/back/state_machine.hpp
==============================================================================
--- trunk/boost/msm/back/state_machine.hpp (original)
+++ trunk/boost/msm/back/state_machine.hpp 2010-10-07 16:49:29 EDT (Thu, 07 Oct 2010)
@@ -31,7 +31,6 @@
 #include <boost/fusion/include/at_key.hpp>
 #include <boost/fusion/algorithm/iteration/for_each.hpp>
 #include <boost/fusion/include/for_each.hpp>
-#include <boost/fusion/include/for_each.hpp>
 
 #include <boost/assert.hpp>
 #include <boost/ref.hpp>
@@ -49,6 +48,7 @@
 #include <boost/serialization/base_object.hpp>
 
 #include <boost/msm/row_tags.hpp>
+#include <boost/msm/back/fold_to_list.hpp>
 #include <boost/msm/back/metafunctions.hpp>
 #include <boost/msm/back/history_policies.hpp>
 #include <boost/msm/back/bind_helpers.hpp>
@@ -86,6 +86,7 @@
 const boost::msm::back::dispatch_table<Fsm,Stt, Event,CompilePolicy>
 dispatch_table<Fsm,Stt, Event,CompilePolicy>::instance;
 
+
 // library-containing class for state machines. Pass the actual FSM class as
 // the Concrete parameter.
 template<class Derived,class HistoryPolicy=NoHistory,class CompilePolicy=favor_runtime_speed>
@@ -1190,7 +1191,24 @@
          int* const m_initial_states;
          int m_index;
      };
- public:
+ public:
+ struct update_state
+ {
+ update_state(substate_list& to_overwrite_):to_overwrite(&to_overwrite_){}
+ template<typename StateType>
+ void operator()(StateType const& astate) const
+ {
+ ::boost::fusion::at_key<StateType>(*to_overwrite)=astate;
+ }
+ substate_list* to_overwrite;
+ };
+ template <class Expr>
+ void set_states(Expr const& expr)
+ {
+ ::boost::fusion::for_each(
+ ::boost::fusion::as_vector(FoldToList()(expr, boost::fusion::nil())),update_state(this->m_substate_list));
+ }
+
      // Construct with the default initial states
      state_machine<Derived,HistoryPolicy,CompilePolicy >()
          :Derived()
@@ -1209,13 +1227,56 @@
          // create states
          fill_states(this);
      }
+ template <class Expr>
+ state_machine<Derived,HistoryPolicy,CompilePolicy >
+ (Expr const& expr,typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type* dummy=0)
+ :Derived()
+ ,m_events_queue()
+ ,m_deferred_events_queue()
+ ,m_history()
+ ,m_event_processing(false)
+ ,m_is_included(false)
+ ,m_visitors()
+ ,m_substate_list()
+ {
+ BOOST_MPL_ASSERT_MSG(
+ ( ::boost::proto::matches<Expr, FoldToList>::value),
+ THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR,
+ (FoldToList));
 
+ // initialize our list of states with the ones defined in Derived::initial_state
+ ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
+ (init_states(m_states));
+ m_history.set_initial_states(m_states);
+ // create states
+ fill_states(this);
+ set_states(expr);
+ }
      // Construct with the default initial states and some default argument(s)
 #define MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB(z, n, unused) ARG ## n t ## n
 #define MSM_CONSTRUCTOR_HELPER_EXECUTE(z, n, unused) \
         template <BOOST_PP_ENUM_PARAMS(n, class ARG)> \
         state_machine<Derived,HistoryPolicy,CompilePolicy \
- >(BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ) ) \
+ >(BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ), \
+ typename ::boost::disable_if<typename ::boost::proto::is_expr<ARG0>::type >::type* dummy=0 ) \
+ :Derived(BOOST_PP_ENUM_PARAMS(n,t)) \
+ ,m_events_queue() \
+ ,m_deferred_events_queue() \
+ ,m_history() \
+ ,m_event_processing(false) \
+ ,m_is_included(false) \
+ ,m_visitors() \
+ ,m_substate_list() \
+ { \
+ ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> > \
+ (init_states(m_states)); \
+ m_history.set_initial_states(m_states); \
+ fill_states(this); \
+ } \
+ template <class Expr,BOOST_PP_ENUM_PARAMS(n, class ARG)> \
+ state_machine<Derived,HistoryPolicy,CompilePolicy \
+ >(Expr const& expr,BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ), \
+ typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type* dummy=0 ) \
         :Derived(BOOST_PP_ENUM_PARAMS(n,t)) \
          ,m_events_queue() \
          ,m_deferred_events_queue() \
@@ -1225,11 +1286,17 @@
          ,m_visitors() \
          ,m_substate_list() \
      { \
+ BOOST_MPL_ASSERT_MSG( \
+ ( ::boost::proto::matches<Expr, FoldToList>::value), \
+ THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR, \
+ (FoldToList)); \
          ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> > \
                         (init_states(m_states)); \
          m_history.set_initial_states(m_states); \
          fill_states(this); \
+ set_states(expr); \
      }
+
      BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_CONSTRUCTOR_ARG_SIZE,1), MSM_CONSTRUCTOR_HELPER_EXECUTE, ~)
 #undef MSM_CONSTRUCTOR_HELPER_EXECUTE
 #undef MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB

Modified: trunk/boost/msm/front/euml/common.hpp
==============================================================================
--- trunk/boost/msm/front/euml/common.hpp (original)
+++ trunk/boost/msm/front/euml/common.hpp 2010-10-07 16:49:29 EDT (Thu, 07 Oct 2010)
@@ -12,27 +12,12 @@
 #define BOOST_MSM_FRONT_EUML_COMMON_H
 
 #include <boost/config.hpp>
-
-#ifdef BOOST_MPL_LIMIT_METAFUNCTION_ARITY
-#undef BOOST_MPL_LIMIT_METAFUNCTION_ARITY
-#endif
-
-#ifdef BOOST_PROTO_MAX_ARITY
-#undef BOOST_PROTO_MAX_ARITY
-#endif
+#include <boost/msm/proto_config.hpp>
 
 #ifndef BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
 #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
 #endif
 
-#ifdef BOOST_MSVC
-#define BOOST_MPL_LIMIT_METAFUNCTION_ARITY 7
-#define BOOST_PROTO_MAX_ARITY 7
-#else
-#define BOOST_MPL_LIMIT_METAFUNCTION_ARITY 6
-#define BOOST_PROTO_MAX_ARITY 6
-#endif
-
 #include <iterator>
 #include <utility>
 

Added: trunk/boost/msm/proto_config.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/msm/proto_config.hpp 2010-10-07 16:49:29 EDT (Thu, 07 Oct 2010)
@@ -0,0 +1,32 @@
+// 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_PROTO_CONFIG_H
+#define BOOST_MSM_PROTO_CONFIG_H
+
+#ifdef BOOST_MSVC
+ #if BOOST_PROTO_MAX_ARITY <= 7
+ #ifdef BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+ #undef BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+ #endif
+ #define BOOST_MPL_LIMIT_METAFUNCTION_ARITY 7
+ #define BOOST_PROTO_MAX_ARITY 7
+ #endif
+#else
+ #if BOOST_PROTO_MAX_ARITY <= 6
+ #ifdef BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+ #undef BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+ #endif
+ #define BOOST_MPL_LIMIT_METAFUNCTION_ARITY 6
+ #define BOOST_PROTO_MAX_ARITY 6
+ #endif
+#endif
+
+#endif //BOOST_MSM_PROTO_CONFIG_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