[MSM] How to access event-attributes through a "kleene"-event?

Hello everyone, I am trying to use Boost.MSM with the eUML front-end and I must say: That is a pretty cool thing! :-) However, I stumbled across some points that raised several questions, which I hoped someone of you could answer. One of these points is the usage of the "kleene" event (with eUML). The questions that came to mind are the following: 1. Is there a way to access an attribute of an (original) event if the transition-table uses the "kleene" event? 2. If there is a way, can I access it directly from the guard or actions-list in the transition-table? 3. If there is not a way, is it planned to be implemented (if possible) and when? For better understanding I insert here a simple example which explains what I am trying to do: In my special case, all my events have an attribute "EventNo" which is a unique number for each event(-type). Now, I need a transition for the events with "EventNo" greater than a special number (e.g. 7). So I thought, I could do something like this: // The attribute: BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, EventNo) BOOST_MSM_EUML_ATTRIBUTES((attributes_ << EventNo), EventNoAttr) // All events that contain this attribute: BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(event1, EventNoAttr) BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(event2, EventNoAttr) /* ... */ BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(eventN, EventNoAttr) // Entry-action of FSM which initializes these event-numbers: BOOST_MSM_EUML_ACTION(init_all_events) { template <class Evt, class Fsm, class State> void operator()(Evt const&, Fsm&, State&) { event1.get_attribute(EventNo) = 1; event2.get_attribute(EventNo) = 2; /* ... */ eventN.get_attribute(EventNo) = N; }; } // Some states: BOOST_MSM_EUML_STATE((), State1) BOOST_MSM_EUML_STATE((), State2) // The transition table which contains all the logic: BOOST_MSM_EUML_TRANSITION_TABLE(( State1 + kleene [event_(EventNo) > Int_<7>()] // <-- Not working! == State2, State1 + event1 == State3 /* event2 to event7 are ignored! */ ), stt) // The FSM front-end and back-end: BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( stt, init_ << init_all_events ), FsmFrontend; typedef msm::back::state_machine<FsmFrontend> Fsm; However, the expression "event_(EventNo)" in the transition-guard fails to compile with the following error: error: no match for call to ‘(boost::msm::front::euml::GetEvent_<EventNo_>) (const boost::msm::front::euml::kleene_&, boost::msm::back::state_machine< boost::msm::front::euml::func_state_machine<FsmFrontendtag, ...’ I read in the documentation of the Functor front-end that I should use boost::any::type() to access the original event in transition actions, but I do not really know how to go on with it. I am also not sure if this applies to the eUML front-end at all (especially in the transition-guard). I hope someone can help me and answer these questions!? Thanks in advance, Deniz Bahadir

Hi,
thanks :)
Yes. As the doc states, a kleene event is a boost::any. You can use what boost::any offers. type(), which is used as an example, is a member of boost::any. The restriction is that you need to ask boost::any for a concrete type to get it back.
2. If there is a way, can I access it directly from the guard or actions-list in the transition-table?
Sure. For example: BOOST_MSM_EUML_ACTION(pause_playback) { template <class FSM,class EVT,class SourceState,class TargetState> void operator()(EVT const& evt,FSM&,SourceState& ,TargetState& ) { cout << "player::pause_playback" << endl; std::cout << "event type: " << typeid(EVT).name() << std::endl; std::cout << "pause_playback with any event: " << evt.type().name() << std::endl; } }; The event is the EVT parameter, behind is hiding your kleene, and with it a boost::any. But I suspect it won't be enough for you, see below for more.
Ah this is already becoming more "fun" :) No, you don't have to use type(), it was just an example. With the known limitations of boost::any, all you can do is call any's any_cast on your event, check if it is one of your eventXXX, then you have the original event and you can call its members. It's not particularly beautiful but it's all what boost officially has to offer. Note that I insist on "officially". Let's suppose you'd have a look on the excellent, accepted but not in any boost release, type_erasure, now the situation looks better. Disclaimer: this was not documented because I hadn't tried it out yet. I just tried now quickly because I suspect you'll need it but there might be some bugs. This being said, please attach your seat belt, it might get bumpy :) You can define your type_erasure's any with extra members and use them in your guards and actions. 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_<>
All you still need to do is tell MSM about your own, brand new kleene event as explained here: http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s03.html#any-even... namespace boost { namespace msm{ template<> struct is_kleene_event< any_number_event > { typedef boost::mpl::true_ type; }; }} Now let's try and modify some standard example: We need an instance for the table and a transition: any_number_event number_event; Playing + number_event / pause_playback == Paused // replaces pause as event Ok, now let's make our events more powerful: struct play_impl : msm::front::euml::euml_event<play_impl> {int getNumber()const {return 0;}}; struct end_pause_impl : msm::front::euml::euml_event<end_pause_impl>{int getNumber()const {return 1;}}; struct stop_impl : msm::front::euml::euml_event<stop_impl>{int getNumber()const {return 2;}}; struct pause_impl : msm::front::euml::euml_event<pause_impl>{int getNumber()const {return 3;}}; struct open_close_impl : msm::front::euml::euml_event<open_close_impl>{int getNumber()const {return 4;}}; struct cd_detected_impl : msm::front::euml::euml_event<cd_detected_impl>{int getNumber()const {return 5;}}; An action becomes: BOOST_MSM_EUML_ACTION(pause_playback) { template <class FSM,class EVT,class SourceState,class TargetState> void operator()(EVT const& evt,FSM&,SourceState& ,TargetState& ) { cout << "player::pause_playback" << endl; std::cout << "event type: " << typeid(EVT).name() << std::endl; std::cout << "event's number: " << evt.getNumber() << std::endl; // we expect 3 here, as our event is a pause event } }; Calls to process_event stay unchanged. Granted, this is already quite advanced but AFAIK there is no other way. There is however a catch: I don't know if all this is possible with the full eUML as you use it. I'm afraid you'll have to do as in my example and go for the almost eUML (no event attributes, classical events). I also realize that a complete example cannot hurt, so I just added them in trunk (rev 83038) in doc/HTML/examples (SimpleTutorialWithEumlTableKleene.cpp and SimpleTutorialWithEumlTableTypeErasure.cpp) Have fun, Christophe

Hi Christophe, [snip]
You are right. That it is not exactly, what I had in mind. Especially, with my second question I meant, if it might be possible to access the event's attribute directly from the guard or action list without writing an extra action for it (as I showed in my example or) as in the following example: // The transitions with kleene-event failing. // Only the second transition works/compiles. BOOST_MSM_EUML_TRANSITION_TABLE(( State1 + kleene [event_(EventNo) > Int_<7>()] == State2, State1 + event1 / (fsm_(lastEventNo) = event_(EventNo)) == State3 State2 + kleene / (fsm_(lastEventNo) = event_(EventNo)) == State3 ), stt)
3. If there is not a way, is it planned to be implemented (if possible) and when?
[snip]
That is a funny coincidence. On the same evening after I wrote you my first email I heard a talk about Boost.TypeErasure. :-) Quite interesting library.
[snip]
You seem to be right. I tried a long time to get this to work with the any_event getting a method "get_attribute" (which "event_(attribute)" seems to call). However, the compiler complains about being unable to do proper type-deduction. But maybe, it is possible, but needs a more experiences meta-template-programmer than me. :-) However, I created some helper-Macros (almost identical to your "BOOST_MSM_EUML_EVENT" and "BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES" macros), and some helper actions (similar to your "Int_" action) which allow me to create and access the (event-number) attributes almost as I tried before. Here they are: // 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(); } }; Both macros are identical to the original pendants except for the additional parameter "members_list" and the line expanding this argument "BOOST_PP_EXPAND members_list". Now I am able to define and use events as in the following example: // The attribute: BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, EventNo) BOOST_MSM_EUML_ATTRIBUTES((attributes_ << EventNo), EventNoAttr) // All events that contain this attribute: BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(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) Now, all three transitions work, not only the second. Sadly it is not as elegant as I hoped, but maybe it helps you in improving this great library. :-) Now I hope, Boost.TypeErasure will be released soon, so that you could improve your library with Boost.TypeErasure functionality. Thanks again for this great library, Deniz

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_<>
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

OK, hopefully last fix. (I still had a typo in the new member-function "getEventNumber" when creating the events by calling macro MY_BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES_AND_MEMBERS): 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_<>
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(EventNo); }) // <-- 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

Hi again,
[snip]
Of course, I had some more typos. (I did not test, what I extracted from my code into the email... :-/) However, I realized, that for my case I do not really need the "IsEventNumberGT_<VAL>" action. I could as well have used the "GetEventNumber_" action in the transition table which is even clearer for a C++ developer: // The transitions table BOOST_MSM_EUML_TRANSITION_TABLE(( State1 + number_event [GetEventNumber_ > Int_<7>()] == State2, ), stt) Ciao, Deniz PS: I found a possible bug in MSM when accessing state-attributes from actions. But maybe I am doing something wrong. I'll open a new email-thread for that with subject "[MSM] Unable to retrieve correct value of attribute of a state from within actions. (Possible Bug?)". Maybe you could have a look at it.

Hi Deniz,
Ah I wrote this without thinking enough. Actually, if you have a look there/http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s04.html#d0e1528), you'll find a macro which will solve the problem. I think we could do this: // declare a memeber wrapper BOOST_MSM_EUML_METHOD(GetNumber_ , getNumber , getNumber_ , void , void ) Then in the table write: [getNumber_(event_) > Int<7>()] I'll also have a look at your macro, it's also an elegant way to solve this. Sorry for the delay :(
Thanks again :) If BOOST_MSM_EUML_METHOD doesn't do what you need, then yours could be an alternative.
Now I hope, Boost.TypeErasure will be released soon, so that you could improve your library with Boost.TypeErasure functionality.
Yes I see other possible uses, some really cool ones :) Cheers, Christophe
participants (2)
-
Christophe Henry
-
Deniz Bahadir