]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/mpl/example/fsm/state_machine.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / mpl / example / fsm / state_machine.hpp
1
2 #ifndef BOOST_FSM_STATE_MACHINE_INCLUDED
3 #define BOOST_FSM_STATE_MACHINE_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 "aux_/event.hpp"
18 #include "aux_/state.hpp"
19 #include "aux_/transition.hpp"
20 #include "aux_/STT_impl_gen.hpp"
21 #include <boost/shared_ptr.hpp>
22
23 #include <queue>
24 #include <memory>
25 #include <cassert>
26
27 namespace fsm {
28
29 template< typename Derived >
30 class state_machine
31 {
32 private:
33 typedef state_machine self_t;
34 typedef aux::base_event base_event_t;
35 typedef boost::shared_ptr<base_event_t const> base_event_ptr_t;
36
37 public:
38 typedef long state_t;
39 typedef void (Derived::* invariant_func_t)() const;
40
41 template< typename DerivedEvent >
42 struct event
43 : aux::event<DerivedEvent>
44 {
45 };
46
47 void process_event(base_event_t const& evt)
48 {
49 // all internal events should be handled at this point
50 assert(!m_events_queue.size());
51
52 // process the external event passed
53 do_transition(evt);
54
55 // if the previous transition generated any internal events,
56 // process those
57 while (m_events_queue.size())
58 {
59 do_transition(*m_events_queue.front());
60 m_events_queue.pop();
61 }
62 }
63
64 state_t current_state() const
65 {
66 return m_state;
67 }
68
69 protected:
70 // interface for the derived class
71
72 state_machine(state_t const& initial_state)
73 : m_state(initial_state)
74 {
75 }
76
77 state_machine()
78 : m_state(typename Derived::initial_state())
79 {
80 }
81
82 virtual ~state_machine()
83 {
84 }
85
86 void post_event(std::auto_ptr<base_event_t const> evt)
87 {
88 m_events_queue.push(base_event_ptr_t(evt.release()));
89 }
90
91 template<
92 long State
93 #if !defined(BOOST_INTEL_CXX_VERSION) && (!defined(__GNUC__) || __GNUC__ >= 3)
94 , invariant_func_t f = static_cast<invariant_func_t>(0)
95 #else
96 , invariant_func_t f = 0
97 #endif
98 >
99 struct state
100 : fsm::aux::state<Derived,State,f>
101 {
102 };
103
104 template<
105 typename From
106 , typename Event
107 , typename To
108 , bool (Derived::* transition_func)(Event const&)
109 >
110 struct transition
111 : aux::transition< Derived,From,Event,To,transition_func >
112 {
113 };
114
115 private:
116
117 void do_transition(base_event_t const& evt)
118 {
119 typedef typename Derived::transition_table STT_;
120 typedef typename aux::STT_impl_gen< STT_ >::type STT_impl_;
121
122 m_state = STT_impl_::do_transition(
123 static_cast<Derived&>(*this)
124 , m_state
125 , evt
126 );
127 }
128
129 state_t m_state;
130 std::queue< base_event_ptr_t > m_events_queue;
131 };
132
133 } // namespace fsm
134
135 #endif // BOOST_FSM_STATE_MACHINE_INCLUDED