|
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