1 2 #ifndef BOOST_FSM_HANDLER_INCLUDED 3 #define BOOST_FSM_HANDLER_INCLUDED 4 5 // Copyright Aleksey Gurtovoy 2002-2004 6 // 7 // Distributed under the Boost Software License, Version 1.0. 8 // (See accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 // 11 // See http://www.boost.org/libs/mpl for documentation. 12 13 // $Id$ 14 // $Date$ 15 // $Revision$ 16 17 #include <boost/mpl/if.hpp> 18 #include <boost/mpl/fold.hpp> 19 #include <boost/mpl/front.hpp> 20 #include <boost/type_traits/is_same.hpp> 21 22 #include <typeinfo> 23 #include <cassert> 24 25 namespace fsm { namespace aux { 26 27 namespace mpl = boost::mpl; 28 using namespace mpl::placeholders; 29 30 template< typename Transition > 31 struct STT_void_row_impl 32 { 33 typedef typename Transition::from_state_t state_t; 34 typedef typename Transition::fsm_t fsm_t; 35 typedef typename Transition::base_event_t base_event_t; 36 do_process_eventfsm::aux::STT_void_row_impl37 static long do_process_event(fsm_t&, long state, base_event_t const&) 38 { 39 assert(false); 40 return state; 41 } 42 do_transitionfsm::aux::STT_void_row_impl43 static long do_transition(fsm_t&, long state, base_event_t const&) 44 { 45 assert(false); 46 return state; 47 } 48 }; 49 50 51 template< 52 typename PrevRowImpl 53 , typename Transition 54 > 55 struct STT_event_row_impl 56 : PrevRowImpl 57 { 58 typedef typename Transition::from_state_t state_t; 59 typedef typename Transition::fsm_t fsm_t; 60 typedef typename Transition::base_event_t base_event_t; 61 do_process_eventfsm::aux::STT_event_row_impl62 static long do_process_event(fsm_t& fsm, long state, base_event_t const& evt) 63 { 64 if (typeid(typename Transition::event_t) == typeid(evt)) 65 { 66 // typedefs are here to make GCC happy 67 typedef typename Transition::to_state_t to_state_; 68 typedef typename Transition::from_state_t from_state_; 69 70 return Transition::do_transition(fsm, evt) 71 ? to_state_::do_check_invariant(fsm) 72 : from_state_::do_check_invariant(fsm) 73 ; 74 } 75 76 return PrevRowImpl::do_process_event(fsm, state, evt); 77 } 78 }; 79 80 template< 81 typename PrevRowImpl 82 , typename StateType 83 > 84 struct STT_state_row_impl 85 : PrevRowImpl 86 { 87 typedef typename PrevRowImpl::fsm_t fsm_t; 88 typedef typename PrevRowImpl::base_event_t base_event_t; 89 do_transitionfsm::aux::STT_state_row_impl90 static long do_transition(fsm_t& fsm, long state, base_event_t const& evt) 91 { 92 return state == StateType::value 93 ? PrevRowImpl::do_process_event(fsm, state, evt) 94 : PrevRowImpl::do_transition(fsm, state, evt) 95 ; 96 } 97 do_process_eventfsm::aux::STT_state_row_impl98 static long do_process_event(fsm_t&, long state, base_event_t const&) 99 { 100 assert(false); 101 return state; 102 } 103 }; 104 105 template< 106 typename PrevRowImpl 107 , typename Transition 108 > 109 struct STT_row_impl 110 { 111 typedef typename mpl::if_< 112 boost::is_same< 113 typename PrevRowImpl::state_t 114 , typename Transition::from_state_t 115 > 116 , STT_event_row_impl< PrevRowImpl,Transition > 117 , STT_event_row_impl< 118 STT_state_row_impl< PrevRowImpl,typename PrevRowImpl::state_t > 119 , Transition 120 > 121 >::type type; 122 }; 123 124 125 template< typename Transitions > 126 struct STT_impl_gen 127 { 128 private: 129 typedef typename mpl::front<Transitions>::type first_; 130 typedef typename mpl::fold< 131 Transitions 132 , STT_void_row_impl<first_> 133 , STT_row_impl<_,_> 134 >::type STT_impl_; 135 136 public: 137 typedef STT_state_row_impl< 138 STT_impl_ 139 , typename STT_impl_::state_t 140 > type; 141 }; 142 143 }} 144 145 #endif // BOOST_FSM_HANDLER_INCLUDED 146