STT_impl_gen.hpp 3.5 KB

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