]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/HTML/examples/iPodSearch.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / msm / doc / HTML / examples / iPodSearch.cpp
1 // Copyright 2010 Christophe Henry
2 // henry UNDERSCORE christophe AT hotmail DOT com
3 // This is an extended version of the state machine available in the boost::mpl library
4 // Distributed under the same license as the original.
5 // Copyright for the original version:
6 // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
7 // under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10
11 #include <set>
12 #include <string>
13 #include <iostream>
14 #include <boost/msm/back/state_machine.hpp>
15 #include <boost/msm/front/state_machine_def.hpp>
16
17 using namespace std;
18 namespace msm = boost::msm;
19
20 namespace // Concrete FSM implementation
21 {
22 // events
23 struct OneSong
24 {
25 OneSong(string const& asong):m_Song(asong){}
26 const string& get_data() const {return m_Song;}
27 private:
28 string m_Song;
29 };
30 template <class DATA>
31 struct NotFound
32 {
33 DATA get_data() const {return m_Data;}
34 DATA m_Data;
35 };
36 template <class DATA>
37 struct Found
38 {
39 DATA get_data() const {return m_Data;}
40 DATA m_Data;
41 };
42 struct Done {};
43
44 template <class Container,class BASE_TYPE,class FSMType>
45 struct Insert : public boost::msm::front::state<BASE_TYPE,boost::msm::front::sm_ptr>
46 {
47 template <class Event,class FSM>
48 void on_entry(Event const& evt,FSM& )
49 {
50 //TODO other containers
51 if (m_Cont)
52 {
53 m_Cont->insert(evt.get_data());
54 }
55 m_fsm->process_event(Done());
56 }
57 void set_sm_ptr(FSMType* fsm){m_fsm=fsm;}
58 void set_container(Container* cont){m_Cont=cont;}
59 Container* m_Cont;
60
61 private:
62 FSMType* m_fsm;
63 };
64 template <class BASE_TYPE,class FSMType>
65 struct StringFind : public boost::msm::front::state<BASE_TYPE,boost::msm::front::sm_ptr>
66 {
67 template <class Event,class FSM>
68 void on_entry(Event const& evt,FSM& )
69 {
70 //TODO other containers
71 // if the element in the event is found
72 if (evt.get_data().find(m_Cont) != std::string::npos )
73 {
74 Found<std::string> res;
75 res.m_Data = evt.get_data();
76 m_fsm->process_event(res);
77 }
78 // data not found
79 else
80 {
81 NotFound<std::string> res;
82 res.m_Data = evt.get_data();
83 m_fsm->process_event(res);
84 }
85 }
86 void set_sm_ptr(FSMType* fsm){m_fsm=fsm;}
87 void set_container(const char* cont){m_Cont=cont;}
88 private:
89 std::string m_Cont;
90 FSMType* m_fsm;
91 };
92 template <class EventType,class Container,class BASE_TYPE,class FSMType>
93 struct Foreach : public boost::msm::front::state<BASE_TYPE,boost::msm::front::sm_ptr>
94 {
95 template <class Event,class FSM>
96 void on_entry(Event const& evt,FSM& )
97 {
98 //TODO other containers
99 if (!m_Cont.empty())
100 {
101 typename Container::value_type next_event = *m_Cont.begin();
102 m_Cont.erase(m_Cont.begin());
103 m_fsm->process_event(EventType(next_event));
104 }
105 }
106 void set_sm_ptr(FSMType* fsm){m_fsm=fsm;}
107 void set_container(Container* cont){m_Cont=*cont;}
108
109 private:
110 Container m_Cont;
111 FSMType* m_fsm;
112 };
113
114
115 // Concrete FSM implementation
116 struct iPodSearch_ : public msm::front::state_machine_def<iPodSearch_>
117 {
118 typedef msm::back::state_machine<iPodSearch_> iPodSearch;
119 // The list of FSM states
120 typedef std::set<std::string> Songset;
121 typedef Insert<Songset,boost::msm::front::default_base_state,iPodSearch> MyInsert;
122 typedef StringFind<boost::msm::front::default_base_state,iPodSearch> MyFind;
123 typedef Foreach<OneSong,Songset,boost::msm::front::default_base_state,iPodSearch> MyForeach;
124
125 // the initial state of the player SM. Must be defined
126 typedef MyForeach initial_state;
127
128 // transition actions
129
130 // guard conditions
131
132 typedef iPodSearch_ fsm; // makes transition table cleaner
133
134 // Transition table for player
135 struct transition_table : mpl::vector4<
136 // Start Event Next Action Guard
137 // +-----------+------------------+------------+---------------------+----------------------+
138 _row < MyForeach , OneSong , MyFind >,
139 _row < MyFind , NotFound<string> , MyForeach >,
140 _row < MyFind , Found<string> , MyInsert >,
141 _row < MyInsert , Done , MyForeach >
142 // +-----------+------------------+------------+---------------------+----------------------+
143 > {};
144 iPodSearch_():m_AllSongs(),m_ResultSearch()
145 {
146 // add a few songs for testing
147 m_AllSongs.insert("Let it be");
148 m_AllSongs.insert("Yellow submarine");
149 m_AllSongs.insert("Twist and Shout");
150 m_AllSongs.insert("She Loves You");
151 }
152 template <class Event,class FSM>
153 void on_entry(Event const&,FSM& fsm)
154 {
155 fsm.template get_state<MyForeach&>().set_container(&m_AllSongs);
156 fsm.template get_state<MyInsert&>().set_container(&m_ResultSearch);
157 }
158 const Songset& get_result(){return m_ResultSearch;}
159 void reset_search(){m_ResultSearch.clear();}
160
161 // Replaces the default no-transition response.
162 template <class FSM,class Event>
163 void no_transition(Event const& e, FSM&,int state)
164 {
165 std::cout << "no transition from state " << state
166 << " on event " << typeid(e).name() << std::endl;
167 }
168
169 private:
170 Songset m_AllSongs;
171 Songset m_ResultSearch;
172 };
173 typedef msm::back::state_machine<iPodSearch_> iPodSearch;
174
175
176 void test()
177 {
178 iPodSearch search;
179 // look for "She Loves You" using the first letters
180 search.get_state<iPodSearch::MyFind*>()->set_container("Sh");// will find 2 songs
181
182 // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
183 search.start();
184 // display all the songs
185 const iPodSearch::Songset& res = search.get_result();
186 for (iPodSearch::Songset::const_iterator it = res.begin();it != res.end();++it)
187 {
188 cout << "candidate song:" << *it << endl;
189 }
190 cout << "search using more letters" << endl;
191 // look for "She Loves You" using more letters
192 search.reset_search();
193 search.get_state<iPodSearch::MyFind*>()->set_container("She");// will find 1 song
194 search.start();
195 const iPodSearch::Songset& res2 = search.get_result();
196 for (iPodSearch::Songset::const_iterator it = res2.begin();it != res2.end();++it)
197 {
198 cout << "candidate song:" << *it << endl;
199 }
200
201 }
202 }
203
204 int main()
205 {
206 test();
207 return 0;
208 }