Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:48:14

0001 // Copyright 2008 Christophe Henry
0002 // henry UNDERSCORE christophe AT hotmail DOT com
0003 // This is an extended version of the state machine available in the boost::mpl library
0004 // Distributed under the same license as the original.
0005 // Copyright for the original version:
0006 // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
0007 // under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at
0009 // http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 #ifndef BOOST_MSM_FRONT_FUNCTOR_ROW_H
0012 #define BOOST_MSM_FRONT_FUNCTOR_ROW_H
0013 
0014 #include <boost/mpl/set.hpp>
0015 #include <boost/mpl/for_each.hpp>
0016 #include <boost/mpl/has_xxx.hpp>
0017 #include <boost/mpl/count_if.hpp>
0018 
0019 #include <boost/typeof/typeof.hpp>
0020 
0021 #include <boost/msm/back/common_types.hpp>
0022 #include <boost/msm/row_tags.hpp>
0023 #include <boost/msm/common.hpp>
0024 #include <boost/msm/front/completion_event.hpp>
0025 
0026 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
0027 
0028 BOOST_MPL_HAS_XXX_TRAIT_DEF(deferring_action)
0029 BOOST_MPL_HAS_XXX_TRAIT_DEF(some_deferring_actions)
0030     
0031 namespace boost { namespace msm { namespace front
0032 {
0033     template <class Func,class Enable=void>
0034     struct get_functor_return_value 
0035     {
0036         static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_TRUE;
0037     };
0038     template <class Func>
0039     struct get_functor_return_value<Func, 
0040         typename ::boost::enable_if<
0041             typename has_deferring_action<Func>::type 
0042         >::type
0043     > 
0044     {
0045         static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_DEFERRED;
0046     };
0047     // for sequences
0048     template <class Func>
0049     struct get_functor_return_value<Func, 
0050         typename ::boost::enable_if<
0051                 typename has_some_deferring_actions<Func>::type
0052         >::type
0053     > 
0054     {
0055         static const ::boost::msm::back::HandledEnum value = 
0056             (Func::some_deferring_actions::value ? ::boost::msm::back::HANDLED_DEFERRED : ::boost::msm::back::HANDLED_TRUE );
0057     };
0058     template <class SOURCE,class EVENT,class TARGET,class ACTION=none,class GUARD=none>
0059     struct Row
0060     {
0061         typedef SOURCE  Source;
0062         typedef EVENT   Evt;
0063         typedef TARGET  Target;
0064         typedef ACTION  Action;
0065         typedef GUARD   Guard;
0066         // action plus guard
0067         typedef row_tag row_type_tag;
0068         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0069         static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0070         {
0071             // create functor, call it
0072             Action()(evt,fsm,src,tgt);
0073             return get_functor_return_value<Action>::value;
0074         }
0075         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0076         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt,AllStates&)
0077         {
0078             // create functor, call it
0079             return Guard()(evt,fsm,src,tgt);
0080         }
0081     };
0082 
0083     template<class SOURCE,class EVENT,class TARGET>
0084     struct Row<SOURCE,EVENT,TARGET,none,none>
0085     {
0086         typedef SOURCE  Source;
0087         typedef EVENT   Evt;
0088         typedef TARGET  Target;
0089         typedef none    Action;
0090         typedef none    Guard;
0091         // no action, no guard
0092         typedef _row_tag row_type_tag;
0093     };
0094     template<class SOURCE,class EVENT,class TARGET,class ACTION>
0095     struct Row<SOURCE,EVENT,TARGET,ACTION,none>
0096     {
0097         typedef SOURCE  Source;
0098         typedef EVENT   Evt;
0099         typedef TARGET  Target;
0100         typedef ACTION  Action;
0101         typedef none    Guard;
0102         // no guard
0103         typedef a_row_tag row_type_tag;
0104         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0105         static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0106         {
0107             // create functor, call it
0108             Action()(evt,fsm,src,tgt);
0109             return get_functor_return_value<Action>::value;
0110         }
0111     };
0112     template<class SOURCE,class EVENT,class TARGET,class GUARD>
0113     struct Row<SOURCE,EVENT,TARGET,none,GUARD>
0114     {
0115         typedef SOURCE  Source;
0116         typedef EVENT   Evt;
0117         typedef TARGET  Target;
0118         typedef none    Action;
0119         typedef GUARD   Guard;
0120         // no action
0121         typedef g_row_tag row_type_tag;
0122         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0123         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0124         {
0125             // create functor, call it
0126             return Guard()(evt,fsm,src,tgt);
0127         }
0128     };
0129     // internal transitions
0130     template<class SOURCE,class EVENT,class ACTION>
0131     struct Row<SOURCE,EVENT,none,ACTION,none>
0132     {
0133         typedef SOURCE  Source;
0134         typedef EVENT   Evt;
0135         typedef Source  Target;
0136         typedef ACTION  Action;
0137         typedef none    Guard;
0138         // no guard
0139         typedef a_irow_tag row_type_tag;
0140         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0141         static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0142         {
0143             // create functor, call it
0144             Action()(evt,fsm,src,tgt);
0145             return get_functor_return_value<Action>::value;
0146         }
0147     };
0148     template<class SOURCE,class EVENT,class GUARD>
0149     struct Row<SOURCE,EVENT,none,none,GUARD>
0150     {
0151         typedef SOURCE  Source;
0152         typedef EVENT   Evt;
0153         typedef Source  Target;
0154         typedef none    Action;
0155         typedef GUARD   Guard;
0156         // no action
0157         typedef g_irow_tag row_type_tag;
0158         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0159         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0160         {
0161             // create functor, call it
0162             return Guard()(evt,fsm,src,tgt);
0163         }
0164     };
0165     template<class SOURCE,class EVENT,class ACTION,class GUARD>
0166     struct Row<SOURCE,EVENT,none,ACTION,GUARD>
0167     {
0168         typedef SOURCE  Source;
0169         typedef EVENT   Evt;
0170         typedef Source  Target;
0171         typedef ACTION  Action;
0172         typedef GUARD   Guard;
0173         // action + guard
0174         typedef irow_tag row_type_tag;
0175         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0176         static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0177         {
0178             // create functor, call it
0179             Action()(evt,fsm,src,tgt);
0180             return get_functor_return_value<Action>::value;
0181         }
0182         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0183         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0184         {
0185             // create functor, call it
0186             return Guard()(evt,fsm,src,tgt);
0187         }
0188     };
0189     template<class SOURCE,class EVENT>
0190     struct Row<SOURCE,EVENT,none,none,none>
0191     {
0192         typedef SOURCE  Source;
0193         typedef EVENT   Evt;
0194         typedef Source  Target;
0195         typedef none    Action;
0196         typedef none    Guard;
0197         // no action, no guard
0198         typedef _irow_tag row_type_tag;
0199     };
0200     template<class TGT>
0201     struct get_row_target
0202     {
0203         typedef typename TGT::Target type;
0204     };
0205 
0206     template <class EVENT,class ACTION=none,class GUARD=none>
0207     struct Internal
0208     {
0209         typedef EVENT   Evt;
0210         typedef ACTION  Action;
0211         typedef GUARD   Guard;
0212         // action plus guard
0213         typedef sm_i_row_tag row_type_tag;
0214         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0215         static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0216         {
0217             // create functor, call it
0218             Action()(evt,fsm,src,tgt);
0219             return get_functor_return_value<Action>::value;
0220         }
0221         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0222         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0223         {
0224             // create functor, call it
0225             return Guard()(evt,fsm,src,tgt);
0226         }
0227     };
0228 
0229     template<class EVENT,class ACTION>
0230     struct Internal<EVENT,ACTION,none>
0231     {
0232         typedef EVENT   Evt;
0233         typedef ACTION  Action;
0234         typedef none    Guard;
0235         // no guard
0236         typedef sm_a_i_row_tag row_type_tag;
0237         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0238         static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0239         {
0240             // create functor, call it
0241             Action()(evt,fsm,src,tgt);
0242             return get_functor_return_value<Action>::value;
0243         }
0244     };
0245     template<class EVENT,class GUARD>
0246     struct Internal<EVENT,none,GUARD>
0247     {
0248         typedef EVENT   Evt;
0249         typedef none    Action;
0250         typedef GUARD   Guard;
0251         // no action
0252         typedef sm_g_i_row_tag row_type_tag;
0253         template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
0254         static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&)
0255         {
0256             // create functor, call it
0257             return Guard()(evt,fsm,src,tgt);
0258         }
0259     };
0260     template<class EVENT>
0261     struct Internal<EVENT,none,none>
0262     {
0263         typedef EVENT   Evt;
0264         typedef none    Action;
0265         typedef none    Guard;
0266         // no action, no guard
0267         typedef sm__i_row_tag row_type_tag;
0268     };
0269     struct event_tag{};
0270     struct action_tag{};
0271     struct state_action_tag{};
0272     struct flag_tag{};
0273     struct config_tag{};
0274     struct not_euml_tag{};
0275 
0276     template <class Sequence>
0277     struct ActionSequence_
0278     {
0279         typedef Sequence sequence;
0280         // if one functor of the sequence defers events, the complete sequence does
0281         typedef ::boost::mpl::bool_< 
0282             ::boost::mpl::count_if<sequence, 
0283                                    has_deferring_action< ::boost::mpl::placeholders::_1 > 
0284             >::value != 0> some_deferring_actions;
0285 
0286         template <class Event,class FSM,class STATE >
0287         struct state_action_result 
0288         {
0289             typedef void type;
0290         };
0291         template <class EVT,class FSM,class STATE>
0292         struct Call
0293         {
0294             Call(EVT const& evt,FSM& fsm,STATE& state):
0295         evt_(evt),fsm_(fsm),state_(state){}
0296         template <class FCT>
0297         void operator()(::boost::msm::wrap<FCT> const& )
0298         {
0299             FCT()(evt_,fsm_,state_);
0300         }
0301         private:
0302             EVT const&  evt_;
0303             FSM&        fsm_;
0304             STATE&      state_;
0305         };
0306         template <class EVT,class FSM,class SourceState,class TargetState>
0307         struct transition_action_result 
0308         {
0309             typedef void type;
0310         };
0311         template <class EVT,class FSM,class SourceState,class TargetState>
0312         struct Call2
0313         {
0314             Call2(EVT const& evt,FSM& fsm,SourceState& src,TargetState& tgt):
0315         evt_(evt),fsm_(fsm),src_(src),tgt_(tgt){}
0316         template <class FCT>
0317         void operator()(::boost::msm::wrap<FCT> const& )
0318         {
0319             FCT()(evt_,fsm_,src_,tgt_);
0320         }
0321         private:
0322             EVT const & evt_;
0323             FSM& fsm_;
0324             SourceState& src_;
0325             TargetState& tgt_;
0326         };
0327 
0328         typedef ::boost::mpl::set<state_action_tag,action_tag> tag_type;
0329 
0330         template <class EVT,class FSM,class STATE>
0331         void operator()(EVT const& evt,FSM& fsm,STATE& state)
0332         {
0333             mpl::for_each<Sequence,boost::msm::wrap< ::boost::mpl::placeholders::_1> >
0334                 (Call<EVT,FSM,STATE>(evt,fsm,state));
0335         }
0336         template <class EVT,class FSM,class SourceState,class TargetState>
0337         void operator()(EVT const& evt,FSM& fsm,SourceState& src,TargetState& tgt)
0338         {
0339             mpl::for_each<Sequence,boost::msm::wrap< ::boost::mpl::placeholders::_1> >
0340                 (Call2<EVT,FSM,SourceState,TargetState>(evt,fsm,src,tgt));
0341         }
0342     };
0343 
0344     // functor pre-defined for basic functionality
0345     struct Defer 
0346     {
0347         // mark as deferring to avoid stack overflows in certain conditions
0348         typedef int deferring_action;
0349         template <class EVT,class FSM,class SourceState,class TargetState>
0350         void operator()(EVT const& evt,FSM& fsm,SourceState& ,TargetState& ) const
0351         {
0352             fsm.defer_event(evt);
0353         }
0354     };
0355 }}}
0356 #endif //BOOST_MSM_FRONT_FUNCTOR_ROW_H