$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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