$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r66490 - in trunk/boost/msm: back front
From: christophe.j.henry_at_[hidden]
Date: 2010-11-10 16:59:28
Author: chenry
Date: 2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
New Revision: 66490
URL: http://svn.boost.org/trac/boost/changeset/66490
Log:
fixed stack overflow when using Defer
Text files modified: 
   trunk/boost/msm/back/state_machine.hpp      |    30 +++++++++++++++---------------          
   trunk/boost/msm/front/functor_row.hpp       |    39 +++++++++++++++++++++++++++++++++------ 
   trunk/boost/msm/front/internal_row.hpp      |     7 +++++--                                 
   trunk/boost/msm/front/row2.hpp              |    13 +++++++++----                           
   trunk/boost/msm/front/state_machine_def.hpp |    13 +++++++++----                           
   5 files changed, 71 insertions(+), 31 deletions(-)
Modified: trunk/boost/msm/back/state_machine.hpp
==============================================================================
--- trunk/boost/msm/back/state_machine.hpp	(original)
+++ trunk/boost/msm/back/state_machine.hpp	2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
@@ -351,7 +351,7 @@
                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
 
             // then call the action method
-            ROW::action_call(fsm,evt,
+            HandledEnum res = ROW::action_call(fsm,evt,
                              ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
                              ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
                              fsm.m_substate_list);
@@ -360,7 +360,7 @@
             convert_event_and_execute_entry<next_state_type,T2>
                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
             fsm.m_states[region_index]=next_state;
-            return HANDLED_TRUE;
+            return res;
         }
     };
 
@@ -483,7 +483,7 @@
                 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
 
             // then call the action method
-            ROW::action_call(fsm,evt,
+            HandledEnum res = ROW::action_call(fsm,evt,
                             ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
                             ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
                             fsm.m_substate_list);
@@ -493,7 +493,7 @@
                 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
 
             fsm.m_states[region_index]=next_state;
-            return HANDLED_TRUE;
+            return res;
         }
     };
 
@@ -587,11 +587,11 @@
             }
 
             // call the action method
-            ROW::action_call(fsm,evt,
+            HandledEnum res = ROW::action_call(fsm,evt,
                              ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
                              ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
                              fsm.m_substate_list);
-            return HANDLED_TRUE;
+            return res;
         }
     };
 
@@ -651,12 +651,12 @@
             BOOST_ASSERT(state == (current_state));
 
             // call the action method
-            ROW::action_call(fsm,evt,
+            HandledEnum res = ROW::action_call(fsm,evt,
                             ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
                             ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
                             fsm.m_substate_list);
 
-            return HANDLED_TRUE;
+            return res;
         }
     };
     // row simply ignoring the event
@@ -710,11 +710,11 @@
             }
 
             // then call the action method
-            ROW::action_call(fsm,evt,
+            HandledEnum res = ROW::action_call(fsm,evt,
                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
                 fsm.m_substate_list);
-            return HANDLED_TRUE;
+            return res;
         }
     };
     template<
@@ -728,14 +728,14 @@
         typedef typename ROW::Evt transition_event;
 
         // Take the transition action and return the next state.
-        static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
+        static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
         {
             // then call the action method
-            ROW::action_call(fsm,evt,
+            HandledEnum res = ROW::action_call(fsm,evt,
                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
                 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
                 fsm.m_substate_list);
-            return HANDLED_TRUE;
+            return res;
         }
     };
     template<
@@ -759,7 +759,7 @@
             return false;
         }
         // Take the transition action and return the next state.
-        static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
+        static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
         {
             if (!check_guard(fsm,evt))
             {
@@ -1882,7 +1882,7 @@
          }
          template <class StateType>
          typename ::boost::disable_if<typename has_accept_sig<StateType>::type,void >::type
-             visitor_helper(int id) const
+             visitor_helper(int) const
          {
              // nothing to do
          }
Modified: trunk/boost/msm/front/functor_row.hpp
==============================================================================
--- trunk/boost/msm/front/functor_row.hpp	(original)
+++ trunk/boost/msm/front/functor_row.hpp	2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
@@ -15,17 +15,36 @@
 
 #include <boost/mpl/set.hpp>
 #include <boost/mpl/for_each.hpp>
+#include <boost/mpl/has_xxx.hpp>
 
 #include <boost/typeof/typeof.hpp>
 
+#include <boost/msm/back/common_types.hpp>
 #include <boost/msm/row_tags.hpp>
 #include <boost/msm/common.hpp>
 #include <boost/msm/front/completion_event.hpp>
 
 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
 
+BOOST_MPL_HAS_XXX_TRAIT_DEF(deferring_action)
+
 namespace boost { namespace msm { namespace front
 {
+    template <class Func,class Enable=void>
+    struct get_functor_return_value 
+    {
+        static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_TRUE;
+    };
+    template <class Func>
+    struct get_functor_return_value<Func, 
+        typename ::boost::enable_if<
+            typename has_deferring_action<Func>::type 
+        >::type
+    > 
+    {
+        static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_DEFERRED;
+    };
+
     template <class SOURCE,class EVENT,class TARGET,class ACTION=none,class GUARD=none>
     struct Row
     {
@@ -37,10 +56,11 @@
         // action plus guard
         typedef row_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+            return get_functor_return_value<Action>::value;
         }
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt,AllStates&)
@@ -72,10 +92,11 @@
         // no guard
         typedef a_row_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+            return get_functor_return_value<Action>::value;
         }
     };
     template<class SOURCE,class EVENT,class TARGET,class GUARD>
@@ -107,10 +128,11 @@
         // no guard
         typedef a_irow_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+            return get_functor_return_value<Action>::value;
         }
     };
     template<class SOURCE,class EVENT,class GUARD>
@@ -141,10 +163,11 @@
         // action + guard
         typedef irow_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+            return get_functor_return_value<Action>::value;
         }
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
@@ -179,10 +202,11 @@
         // action plus guard
         typedef sm_i_row_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+            return get_functor_return_value<Action>::value;
         }
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
@@ -201,10 +225,11 @@
         // no guard
         typedef sm_a_i_row_tag row_type_tag;
         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
         {
             // create functor, call it
             Action()(evt,fsm,src,tgt);
+            return get_functor_return_value<Action>::value;
         }
     };
     template<class EVENT,class GUARD>
@@ -304,6 +329,8 @@
     // functor pre-defined for basic functionality
     struct Defer 
     {
+        // mark as deferring to avoid stack overflows in certain conditions
+        typedef int deferring_action;
         template <class EVT,class FSM,class SourceState,class TargetState>
         void operator()(EVT const& evt,FSM& fsm,SourceState& ,TargetState& ) const
         {
Modified: trunk/boost/msm/front/internal_row.hpp
==============================================================================
--- trunk/boost/msm/front/internal_row.hpp	(original)
+++ trunk/boost/msm/front/internal_row.hpp	2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
@@ -14,6 +14,7 @@
 #include <boost/type_traits/is_base_of.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/fusion/include/at_key.hpp>
+#include <boost/msm/back/common_types.hpp>
 #include <boost/msm/row_tags.hpp>
 #include <boost/msm/front/detail/row2_helper.hpp>
 
@@ -29,13 +30,14 @@
         typedef sm_a_i_row_tag row_type_tag;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+            return ::boost::msm::back::HANDLED_TRUE;
         }
     };
 
@@ -51,13 +53,14 @@
         typedef sm_i_row_tag row_type_tag;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+            return ::boost::msm::back::HANDLED_TRUE;
         }
         template <class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
Modified: trunk/boost/msm/front/row2.hpp
==============================================================================
--- trunk/boost/msm/front/row2.hpp	(original)
+++ trunk/boost/msm/front/row2.hpp	2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
@@ -14,6 +14,7 @@
 #include <boost/type_traits/is_base_of.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/fusion/include/at_key.hpp>
+#include <boost/msm/back/common_types.hpp>
 #include <boost/msm/row_tags.hpp>
 #include <boost/msm/front/detail/row2_helper.hpp>
 
@@ -46,13 +47,14 @@
         typedef T2 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::template call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+            return ::boost::msm::back::HANDLED_TRUE;
         }
     };
 
@@ -72,13 +74,14 @@
         typedef T2 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState, class AllStates>
-        static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+            return ::boost::msm::back::HANDLED_TRUE;
         }
         template <class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
@@ -127,13 +130,14 @@
         typedef T1 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+            return ::boost::msm::back::HANDLED_TRUE;
         }
     };
 
@@ -152,13 +156,14 @@
         typedef T1 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt, 
                                 AllStates& all_states)
         {
             // in this front-end, we don't need to know source and target states
             ::boost::msm::front::detail::row2_action_helper<CalledForAction,Event,action>::call_helper
                 (fsm,evt,src,tgt,all_states,
                 ::boost::mpl::bool_< ::boost::is_base_of<CalledForAction,FSM>::type::value>());
+            return ::boost::msm::back::HANDLED_TRUE;
         }
         template <class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,Event const& evt,SourceState& src,TargetState& tgt,
Modified: trunk/boost/msm/front/state_machine_def.hpp
==============================================================================
--- trunk/boost/msm/front/state_machine_def.hpp	(original)
+++ trunk/boost/msm/front/state_machine_def.hpp	2010-11-10 16:59:19 EST (Wed, 10 Nov 2010)
@@ -19,6 +19,7 @@
 #include <boost/mpl/vector.hpp>
 
 #include <boost/msm/row_tags.hpp>
+#include <boost/msm/back/common_types.hpp>
 #include <boost/msm/front/states.hpp>
 #include <boost/msm/front/completion_event.hpp>
 #include <boost/msm/front/common_states.hpp>
@@ -51,10 +52,11 @@
         typedef T2 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&, AllStates&)
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&, AllStates&)
         {
             // in this front-end, we don't need to know source and target states
             (fsm.*action)(evt);
+            return ::boost::msm::back::HANDLED_TRUE;
         }
     };
 
@@ -85,10 +87,11 @@
         typedef T2 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState, class AllStates>
-        static void action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
         {
             // in this front-end, we don't need to know source and target states
             (fsm.*action)(evt);
+            return ::boost::msm::back::HANDLED_TRUE;
         }
         template <class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
@@ -129,10 +132,11 @@
         typedef T1 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
         {
             // in this front-end, we don't need to know source and target states
             (fsm.*action)(evt);
+            return ::boost::msm::back::HANDLED_TRUE;
         }
     };
 
@@ -149,10 +153,11 @@
         typedef T1 Target;
         typedef Event Evt;
         template <class FSM,class SourceState,class TargetState,class AllStates>
-        static void action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
+        static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
         {
             // in this front-end, we don't need to know source and target states
             (fsm.*action)(evt);
+            return ::boost::msm::back::HANDLED_TRUE;
         }
         template <class FSM,class SourceState,class TargetState,class AllStates>
         static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)