Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78785 - in trunk/boost/msm: . back front/euml
From: christophe.j.henry_at_[hidden]
Date: 2012-05-31 17:11:58


Author: chenry
Date: 2012-05-31 17:11:57 EDT (Thu, 31 May 2012)
New Revision: 78785
URL: http://svn.boost.org/trac/boost/changeset/78785

Log:
added support for boost::any or kleene as acceptable events.
Added:
   trunk/boost/msm/event_traits.hpp (contents, props changed)
Text files modified:
   trunk/boost/msm/back/dispatch_table.hpp | 52 +++++++++++++++++++++++++++++++++++----
   trunk/boost/msm/front/euml/common.hpp | 19 ++++++++++++++
   2 files changed, 65 insertions(+), 6 deletions(-)

Modified: trunk/boost/msm/back/dispatch_table.hpp
==============================================================================
--- trunk/boost/msm/back/dispatch_table.hpp (original)
+++ trunk/boost/msm/back/dispatch_table.hpp 2012-05-31 17:11:57 EDT (Thu, 31 May 2012)
@@ -21,7 +21,9 @@
 #include <boost/mpl/advance.hpp>
 
 #include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/is_same.hpp>
 
+#include <boost/msm/event_traits.hpp>
 #include <boost/msm/back/metafunctions.hpp>
 #include <boost/msm/back/common_types.hpp>
 
@@ -146,6 +148,16 @@
     typedef typename generate_state_set<Stt>::type state_list;
     BOOST_STATIC_CONSTANT(int, max_state = ( ::boost::mpl::size<state_list>::value));
 
+ template <class Transition>
+ struct convert_event_and_forward
+ {
+ static HandledEnum execute(Fsm& fsm, int region_index, int state, Event const& evt)
+ {
+ typename Transition::transition_event forwarded(evt);
+ return Transition::execute(fsm,region_index,state,forwarded);
+ }
+ };
+
     // A function object for use with mpl::for_each that stuffs
     // transitions into cells.
     struct init_cell
@@ -159,7 +171,7 @@
         typename ::boost::disable_if<
             typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
         ,void>::type
- init_event_base_case(Transition const&, ::boost::mpl::true_ const &) const
+ init_event_base_case(Transition const&, ::boost::mpl::true_ const &, ::boost::mpl::false_ const &) const
         {
             typedef typename create_stt<Fsm>::type stt;
             BOOST_STATIC_CONSTANT(int, state_id =
@@ -170,18 +182,40 @@
         typename ::boost::enable_if<
             typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
         ,void>::type
- init_event_base_case(Transition const&, ::boost::mpl::true_ const &) const
+ init_event_base_case(Transition const&, ::boost::mpl::true_ const &, ::boost::mpl::false_ const &) const
         {
             self->entries[0] = reinterpret_cast<cell>(&Transition::execute);
         }
 
+ // version for transition event is boost::any
+ // first for all transitions, then for internal ones of a fsm
+ template <class Transition>
+ typename ::boost::disable_if<
+ typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
+ ,void>::type
+ init_event_base_case(Transition const&, ::boost::mpl::false_ const &, ::boost::mpl::true_ 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+1] = &convert_event_and_forward<Transition>::execute;
+ }
+ template <class Transition>
+ typename ::boost::enable_if<
+ typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
+ ,void>::type
+ init_event_base_case(Transition const&, ::boost::mpl::false_ const &, ::boost::mpl::true_ const &) const
+ {
+ self->entries[0] = &convert_event_and_forward<Transition>::execute;
+ }
+
         // version for transition event base of our event
         // first for all transitions, then for internal ones of a fsm
         template <class Transition>
         typename ::boost::disable_if<
             typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
         ,void>::type
- init_event_base_case(Transition const&, ::boost::mpl::false_ const &) const
+ init_event_base_case(Transition const&, ::boost::mpl::false_ const &, ::boost::mpl::false_ const &) const
         {
             typedef typename create_stt<Fsm>::type stt;
             BOOST_STATIC_CONSTANT(int, state_id =
@@ -192,7 +226,7 @@
         typename ::boost::enable_if<
             typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
         ,void>::type
- init_event_base_case(Transition const&, ::boost::mpl::false_ const &) const
+ init_event_base_case(Transition const&, ::boost::mpl::false_ const &, ::boost::mpl::false_ const &) const
         {
             self->entries[0] = &Transition::execute;
         }
@@ -210,7 +244,9 @@
             //only if the transition event is a base of our event is the reinterpret_case safe
             init_event_base_case(tr,
                 ::boost::mpl::bool_<
- ::boost::is_base_of<typename Transition::transition_event,Event>::type::value>() );
+ ::boost::is_base_of<typename Transition::transition_event,Event>::type::value>(),
+ ::boost::mpl::bool_<
+ ::boost::msm::is_kleene_event<typename Transition::transition_event>::type::value>());
         }
     
         dispatch_table* self;
@@ -305,7 +341,11 @@
         typedef typename ::boost::mpl::reverse_fold<
                         // filter on event
                         ::boost::mpl::filter_view
- <Stt, ::boost::is_base_of<transition_event< ::boost::mpl::placeholders::_>, Event> >,
+ <Stt, boost::mpl::or_<
+ ::boost::is_base_of<transition_event< ::boost::mpl::placeholders::_>, Event>,
+ ::boost::msm::is_kleene_event<transition_event< ::boost::mpl::placeholders::_> >
+ >
+ >,
                         // build a map
                         ::boost::mpl::map<>,
                         ::boost::mpl::if_<

Added: trunk/boost/msm/event_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/msm/event_traits.hpp 2012-05-31 17:11:57 EDT (Thu, 31 May 2012)
@@ -0,0 +1,36 @@
+// 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_EVENT_TRAITS_H
+#define BOOST_MSM_EVENT_TRAITS_H
+
+#include <boost/any.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace msm
+{
+
+template< typename Event >
+struct is_kleene_event
+{
+ // default: no event is a kleene event (kleene: matches any event in a transitions)
+ typedef ::boost::mpl::false_ type;
+};
+
+// add this way in this namespace specializations for events which you want to use as kleene
+// requirement: a copy-constructor matching the events which will be converted to this kleene
+template<>
+struct is_kleene_event< boost::any >
+{
+ typedef ::boost::mpl::true_ type;
+};
+
+} } // boost::msm
+#endif //BOOST_MSM_EVENT_TRAITS_H

Modified: trunk/boost/msm/front/euml/common.hpp
==============================================================================
--- trunk/boost/msm/front/euml/common.hpp (original)
+++ trunk/boost/msm/front/euml/common.hpp 2012-05-31 17:11:57 EDT (Thu, 31 May 2012)
@@ -59,6 +59,7 @@
 
 #include <boost/msm/msm_grammar.hpp>
 #include <boost/msm/active_state_switching_policies.hpp>
+#include <boost/msm/event_traits.hpp>
 #include <boost/msm/front/functor_row.hpp>
 
 namespace proto = boost::proto;
@@ -199,6 +200,7 @@
         typedef EVT type;
     };
 };
+
 template <class STATE>
 struct euml_state_intern: proto::extends<typename proto::terminal< boost::msm::state_tag>::type, STATE, boost::msm::state_domain>
 {
@@ -2475,6 +2477,15 @@
     instance_name ## _helper const& operator()() const {return *this;} }; \
     static instance_name ## _helper instance_name;
 
+// an event matching any event
+struct kleene_ : msm::front::euml::euml_event<kleene_>, public boost::any
+{
+ kleene_() : boost::any(){}
+ template<typename ValueType>
+ kleene_(const ValueType & v) : boost::any(v){}
+};
+static kleene_ kleene;
+
 #define BOOST_MSM_EUML_DECLARE_EVENT(instance_name) \
     struct instance_name : msm::front::euml::euml_event<instance_name >{ \
     instance_name(){} \
@@ -2660,4 +2671,12 @@
 
 }}}} // boost::msm::front::euml
 
+namespace boost { namespace msm{
+ template<>
+ struct is_kleene_event< boost::msm::front::euml::kleene_ >
+ {
+ typedef ::boost::mpl::true_ type;
+ };
+}}
+
 #endif // BOOST_MSM_FRONT_EUML_COMMON_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