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