$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [Boost-users] [MSM] How to access event-attributes through a"kleene"-event?
From: Deniz Bahadir (deniz.bahadir_at_[hidden])
Date: 2013-02-21 08:32:10
I had a small typo in the code section of my last message. I used the 
wrong macro names when creating the events. Of course, I should have 
used my new macro MY_BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES_AND_MEMBERS 
instead of the original macro BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES which 
only takes three arguments.
The entire code section should hence look as the following:
BOOST_TYPE_ERASURE_MEMBER((has_getNumber), getNumber, 0);
//type erasure event
typedef ::boost::mpl::vector<
     has_getNumber<int(), const boost::type_erasure::_self>,
     boost::type_erasure::relaxed_match,
     boost::type_erasure::copy_constructible<>,
     boost::type_erasure::typeid_<>
> any_number_event_concept;
struct any_number_event :
boost::type_erasure::any<any_number_event_concept>,
msm::front::euml::euml_event<any_number_event>
{
     template <class U>
     any_number_event(U const& u):
boost::type_erasure::any<any_number_event_concept> (u){}
     any_number_event():
boost::type_erasure::any<any_number_event_concept> (){}
};
namespace boost { namespace msm{
     template<>
     struct is_kleene_event< any_number_event >
     {
       typedef boost::mpl::true_ type;
     };
}}
// Macro which is identical to BOOST_MSM_EUML_EVENT but with
// additional parameter "members_list" which are all additional
// members surrounded by one pair of parentheses.
// The members from "members_list" will be inserted verbatim!
#define MY_BOOST_MSM_EUML_EVENT_WITH_MEMBERS(instance_name, \
                                               members_list)  \
    struct instance_name ## _helper :                         \
      msm::front::euml::euml_event<instance_name ## _helper>  \
    {                                                         \
      instance_name ## _helper(){}                            \
      BOOST_PP_EXPAND members_list                            \
      instance_name ## _helper const& operator()() const      \
        {return *this;}                                       \
    };                                                        \
    static instance_name ## _helper instance_name;
// Macro which is identical to
// BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES but with additional
// parameter "members_list" which are all additional members
// surrounded by one pair of parentheses.
// The members from "members_list" will be inserted verbatim!
#define                                                     \
MY_BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES_AND_MEMBERS(        \
          instance_name, attributes_name, members_list)       \
    struct instance_name ## _helper :                         \
      msm::front::euml::euml_event<instance_name ## _helper>, \
      public attributes_name                                  \
    {                                                         \
      template <class T,int checked_size> struct size_helper  \
      {                                                       \
        typedef typename ::boost::mpl::less_equal<            \
          typename ::boost::fusion::result_of::size<T>::type, \
          ::boost::mpl::int_<checked_size> >::type type;      \
      };                                                      \
      BOOST_PP_CAT(instance_name,_helper()) :                 \
        attributes_name(){}                                   \
      typedef attributes_name::attributes_type attribute_map; \
      typedef ::boost::fusion::result_of::                    \
        as_vector<attribute_map>::type attribute_vec;         \
      BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(                 \
        FUSION_MAX_MAP_SIZE ,1),                              \
        MSM_EUML_EVENT_HELPER_CONSTRUCTORS,                   \
       (instance_name,attributes_name))                       \
      BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(                 \
        FUSION_MAX_MAP_SIZE ,1),                              \
        MSM_EUML_EVENT_INSTANCE_HELPER_ATTRIBUTE_MAP, ~)      \
      BOOST_PP_CAT(instance_name,_helper) operator()(){       \
        return BOOST_PP_CAT(instance_name,_helper)();}        \
      BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(                 \
        FUSION_MAX_MAP_SIZE ,1),                              \
        MSM_EUML_EVENT_INSTANCE_HELPER_OPERATOR_IMPL,         \
        instance_name)                                        \
      BOOST_PP_EXPAND members_list                            \
    };                                                        \
    static instance_name ## _helper instance_name;
// Action that checks if event-number is "greater than" the
// number provided as template-argument.
template <int Val>
struct IsEventNumberGT_ : euml_action<IsEventNumberGT_<Val> >
{
      using euml_action<IsEventNumberGT_<Val> >::operator=;
      typedef ::boost::mpl::int_<Val> value_type;
      enum {value = Val};
      template <class EVT,class FSM,
                class SourceState,class TargetState>
      bool operator()(EVT const& evt, FSM&,
                      SourceState&, TargetState&)
      {
          return (evt.getNumber() > Val);
      }
      template <class Event,class FSM,class STATE>
      bool operator()(Event const& evt, FSM&, STATE& )
      {
          return (evt.getNumber() > Val);
      }
};
// Todo: Make similar actions for "greater or equal",
//       "lesser than", "lesser or equal" and "equal".
// An action which returns the event's number.
BOOST_MSM_EUML_ACTION(GetEventNumber_)
{
    template <class Fsm, class Evt,
             class SourceState, class TargetState>
    int operator()(Evt const& evt, Fsm&,
                  SourceState&, TargetState&)
    {
      return evt.getNumber();
    }
};
// The attribute:
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, EventNo)
BOOST_MSM_EUML_ATTRIBUTES((attributes_ << EventNo), EventNoAttr)
// All events that contain this attribute:
MY_BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES_AND_MEMBERS(event1,
    EventNoAttr,
    (int getEventNumber() const {
       return get_attribute(EventNumber);
     })                                     // <-- members_list
)
/* ... more events with same scheme ... */
// Creating an instance of the new "kleene"-event which has
// a "getNumber" member-function.
any_number_event number_event;
// The transitions table
BOOST_MSM_EUML_TRANSITION_TABLE((
    State1 + number_event
             [IsEventNumberGT_<7>()]                 == State2,
    State1 + event1
             / (fsm_(lastEventNo) = event_(EventNo)) == State3
    State2 + kleene
             / (fsm_(lastEventNo) = GetEventNumber_)) == State3
), stt)
Ciao,
Deniz