Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 08:20:51

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