]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/HTML/examples/CompilerStressTestEuml.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)
17 // we need more than the default 10 states
18 #define FUSION_MAX_VECTOR_SIZE 15
20 #include <boost/msm/back/state_machine.hpp>
21 #include <boost/msm/front/euml/euml.hpp>
22 #include <boost/msm/front/euml/stl.hpp>
25 using namespace boost::msm::front::euml
;
26 namespace msm
= boost::msm
;
28 // how long the timer will ring when countdown elapsed.
29 #define RINGING_TIME 5
31 namespace // Concrete FSM implementation
34 BOOST_MSM_EUML_FLAG(SomeFlag
)
36 // declares attributes with type and name. Can be used anywhere after
37 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string
,m_song
)
38 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int,m_song_id
)
40 // declare that a type inheriting from OneSongDef will get these 2 attributes
41 BOOST_MSM_EUML_ATTRIBUTES((attributes_
<< m_song
<< m_song_id
), OneSongDef
)
43 // this event is done "manually", not using any predefined macro
44 struct OneSong_impl
: euml_event
<OneSong_impl
>,OneSongDef
47 OneSong_impl(const string
& asong
)
49 get_attribute(m_song
)=asong
;
50 get_attribute(m_song_id
)=1;
52 OneSong_impl(const OneSong_impl
& asong
)
54 get_attribute(m_song
)=asong
.get_attribute(m_song
);
55 get_attribute(m_song_id
)=1;
57 const string
& get_data() const {return get_attribute(m_song
);}
59 // declare an instance for use in the transition table
60 OneSong_impl
const OneSong
;
62 struct SongComparator
: euml_action
<SongComparator
>
64 bool operator()(const OneSong_impl
& lhs
,const OneSong_impl
& rhs
)const
66 return lhs
.get_data() == rhs
.get_data();
69 struct SongLessComparator
: euml_action
<SongLessComparator
>
71 bool operator()(const OneSong_impl
& lhs
,const OneSong_impl
& rhs
)const
73 return lhs
.get_data() < rhs
.get_data();
79 bool operator()(const T
& lhs
,const T
& rhs
)const
86 bool operator()(const OneSong_impl
& lhs
)const
88 return (lhs
.get_attribute(m_song
).compare(std::string("She-Dummy. Remove this one"))==0 );
95 bool operator()(const T
& lhs
)const
104 bool operator()(const T
& lhs
)const
109 BOOST_MSM_EUML_ACTION(SongDeleter
)
111 bool operator()(const OneSong_impl
& lhs
)const
113 return lhs
.get_data() == "Twist and Shout";
118 int operator()()const
126 void operator()(const T
& lhs
)const
128 std::cout
<< "Song:" << lhs
.get_data() << endl
;
131 BOOST_MSM_EUML_ATTRIBUTES((attributes_
<< m_song
), NotFoundDef
)
132 // declare an event instance called NotFound with the defined attributes
133 // these attributes can then be referenced anywhere (stt, state behaviors)
134 BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(NotFound
,NotFoundDef
)
136 BOOST_MSM_EUML_ATTRIBUTES((attributes_
<< m_song
), FoundDef
)
137 struct Found_impl
: euml_event
<Found_impl
>,FoundDef
140 Found_impl (const string
& data
)
142 get_attribute(m_song
)=data
;
144 int foo()const {std::cout
<< "foo()" << std::endl
; return 0;}
145 int foo(int i
)const {std::cout
<< "foo(int):" << i
<< std::endl
; return 1;}
146 int foo(int i
,int j
)const {std::cout
<< "foo(int,int):" << i
<<"," << j
<< std::endl
; return 2;}
149 Found_impl
const Found
;
150 // some functions to call
151 // this macro creates a functor and an eUML function wrapper. Now, foo_ can be used anywhere
152 BOOST_MSM_EUML_METHOD(FoundFoo_
, foo
, foo_
, int , int )
155 int do_print(T
& t
) {std::cout
<< "print(T):" << typeid(T
).name() << std::endl
;return 1;}
156 BOOST_MSM_EUML_FUNCTION(PrintState_
, do_print
, print_
, int , int )
158 BOOST_MSM_EUML_EVENT(Done
)
160 // Concrete FSM implementation
163 int foobar()const {std::cout
<< "foobar()" << std::endl
; return 0;}
164 int foobar(int i
)const {std::cout
<< "foobar(int):" << i
<< std::endl
; return 1;}
165 int foobar(int i
,int j
)const {std::cout
<< "foobar(int,int):" << i
<<"," << j
<< std::endl
; return 2;}
167 // some functions to call
168 BOOST_MSM_EUML_METHOD(FooBar_
, foobar
, foobar_
, int , int )
171 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(vector
<OneSong_impl
>,m_src_container
)
172 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(list
<OneSong_impl
>,m_tgt_container
)
173 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(list
<int>,m_var2
)
174 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(list
<int>,m_var3
)
175 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(set
<int>,m_var4
)
176 typedef std::map
<int,int> int_int_map
;
177 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int_int_map
,m_var5
)
178 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string
,m_var6
)
179 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string
,m_var7
)
180 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(vector
<int>,m_var8
)
181 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(vector
<int>,m_var9
)
182 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int,m_var10
)
184 // The list of FSM states
185 BOOST_MSM_EUML_STATE(( ( insert_(fsm_(m_tgt_container
),end_(fsm_(m_tgt_container
)),
186 append_(event_(m_song
),fsm_(m_var7
)) ),//foo_(event_,Int_<0>()) ,
187 //foo_(event_,Int_<0>(),Int_<1>()),print_(state_),
188 process_(Done
/*,fsm_*/),if_then_(true_
,true_
) ),
192 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string
,m_letters
)
193 BOOST_MSM_EUML_STATE(( if_then_else_( (string_find_(event_(m_song
),state_(m_letters
),Size_t_
<0>()) != Npos_
<string
>()&&
194 string_find_(event_(m_song
),Char_
<'S'>(),Size_t_
<0>()) != Npos_
<string
>()&&
195 string_find_first_of_(event_(m_song
),Char_
<'S'>()) == Size_t_
<0>() &&
196 string_compare_(event_(m_song
),Int_
<0>(),size_(event_(m_song
)),event_(m_song
)) == Int_
<0>()
197 //&& is_flag_(SomeFlag(),fsm_())
198 //&& ( event_(m_song_id) == Int_<1>())
199 //&& string_find_(event_(m_song),String_<mpl::string<'Sh','e'> >())
200 // != Npos_<string>()
204 //string_insert_(event_(m_song),Size_t_<0>(),fsm_(m_var6)) ),
209 substr_(event_(m_song
),Size_t_
<1>()),
221 process2_(NotFound
,event_(m_song
),fsm_
) ) ,
223 attributes_
<< m_letters
,
224 configure_
<< SomeFlag
),StringFind
)
226 BOOST_MSM_EUML_DECLARE_ATTRIBUTE(vector
<OneSong_impl
>::iterator
,m_src_it
)
227 BOOST_MSM_EUML_STATE(( if_then_( (state_(m_src_it
) != end_(fsm_(m_src_container
)) &&
228 //associative_find_(fsm_(m_var4),Int_<9>()) != end_(fsm_(m_var4))&&
229 //associative_count_(fsm_(m_var4),Int_<9>()) == Size_t_<1>() &&
230 //*associative_upper_bound_(fsm_(m_var4),Int_<8>()) == Int_<9>()&&
231 //*associative_lower_bound_(fsm_(m_var4),Int_<9>()) == Int_<9>() &&
232 //second_(associative_equal_range_(fsm_(m_var4),Int_<8>())) == associative_upper_bound_(fsm_(m_var4),Int_<8>()) &&
233 //first_(associative_equal_range_(fsm_(m_var4),Int_<8>())) == associative_lower_bound_(fsm_(m_var4),Int_<8>())&&
234 //second_(*associative_lower_bound_(fsm_(m_var5),Int_<0>())) == Int_<0>() && //map => pair as return
235 //find_if_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Predicate_<LookFor<8> >()) != end_(fsm_(m_var4))&&
236 //*lower_bound_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Int_<9>(),Predicate_<std::less<int> >()) == Int_<9>()&&
237 //*upper_bound_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Int_<8>(),Predicate_<std::less<int> >()) == Int_<9>() &&
238 //second_(equal_range_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Int_<8>()))
239 // == upper_bound_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Int_<8>()) &&
240 //first_(equal_range_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Int_<9>(),Predicate_<std::less<int> >()))
241 // == lower_bound_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Int_<9>(),Predicate_<std::less<int> >())&&
242 //binary_search_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Int_<9>(),Predicate_<std::less<int> >())&&
243 //binary_search_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Int_<9>())&&
244 //count_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Int_<9>()) == Int_<1>()&&
245 //count_if_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Predicate_<LookFor<9> >()) == Int_<1>()&&
246 //distance_(begin_(fsm_(m_var4)),end_(fsm_(m_var4))) == Int_<2>()&&
247 //*min_element_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Predicate_<std::less<int> >()) == Int_<8>()&&
248 //*max_element_(begin_(fsm_(m_var4)),end_(fsm_(m_var4)),Predicate_<std::less<int> >()) == Int_<9>()&&
249 //adjacent_find_(begin_(fsm_(m_var4)),end_(fsm_(m_var4))) == end_(fsm_(m_var4))&&
250 //*find_end_(begin_(fsm_(m_var8)),end_(fsm_(m_var8)),begin_(fsm_(m_var9)),end_(fsm_(m_var9)))
252 //*find_first_of_(begin_(fsm_(m_var8)),end_(fsm_(m_var8)),begin_(fsm_(m_var9)),end_(fsm_(m_var9)))
254 //equal_(begin_(fsm_(m_var9)),end_(fsm_(m_var9)),begin_(fsm_(m_var8)))&&
255 //*search_(begin_(fsm_(m_var8)),end_(fsm_(m_var8)),begin_(fsm_(m_var9)),end_(fsm_(m_var9)))
257 //includes_(begin_(fsm_(m_var8)),end_(fsm_(m_var8)),begin_(fsm_(m_var9)),end_(fsm_(m_var9)))&&
258 //!lexicographical_compare_(begin_(fsm_(m_var8)),end_(fsm_(m_var8)),
259 // begin_(fsm_(m_var9)),end_(fsm_(m_var9)))&&
260 //first_(mismatch_(begin_(fsm_(m_var9)),end_(fsm_(m_var9)),begin_(fsm_(m_var8))))
261 // == end_(fsm_(m_var9)) &&
262 accumulate_(begin_(fsm_(m_var9
)),end_(fsm_(m_var9
)),Int_
<1>(),
263 Predicate_
<std::plus
<int> >()) == Int_
<1>()
265 (process2_(OneSong
,*(state_(m_src_it
)++))/*,foobar_(fsm_,Int_<0>())*/ ) ),
267 attributes_
<< m_src_it
268 , configure_
<< SomeFlag
),Foreach
)
271 // replaces the old transition table
272 BOOST_MSM_EUML_TRANSITION_TABLE((
273 StringFind
== Foreach
+ OneSong
[if_then_else_(true_
,true_
,true_
)],
274 Insert
== StringFind
+ Found
/ (if_then_(true_
,no_action
)),
275 Foreach
== StringFind
+ NotFound
,
276 Foreach
== Insert
+ Done
277 // +------------------------------------------------------------------------------+
280 BOOST_MSM_EUML_ACTION(Log_No_Transition
)
282 template <class FSM
,class Event
>
283 void operator()(Event
const& e
,FSM
&,int state
)
285 std::cout
<< "no transition from state " << state
286 << " on event " << typeid(e
).name() << std::endl
;
289 // create a state machine "on the fly"
290 BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table
, //STT
291 init_
<< Foreach
, // Init
292 //insert_(state_(m_var4),begin_(state_(m_var2)),end_(state_(m_var2))),
293 (insert_(state_(m_var4
),Int_
<5>()),insert_(state_(m_var4
),Int_
<6>()),insert_(state_(m_var4
),Int_
<7>()),
294 insert_(state_(m_var4
),Int_
<8>()),insert_(state_(m_var4
),Int_
<9>()),
295 associative_erase_(state_(m_var4
),Int_
<6>()),associative_erase_(state_(m_var4
),begin_(state_(m_var4
))),
296 associative_erase_(state_(m_var4
),begin_(state_(m_var4
)),++begin_(state_(m_var4
))),
297 insert_(state_(m_var2
),begin_(state_(m_var2
)),begin_(state_(m_var3
)),end_(state_(m_var3
))),
298 state_(m_var5
)[Int_
<0>()]=Int_
<0>(),state_(m_var5
)[Int_
<1>()]=Int_
<1>()
299 ,attribute_(substate_(Foreach
,fsm_
),m_src_it
)
300 = begin_(fsm_(m_src_container
))
301 //,fill_(begin_(state_(m_var9)),end_(state_(m_var9)),Int_<0>())
302 //,fill_n_(begin_(state_(m_var9)),Size_t_<2>(),Int_<0>())
303 //,transform_(begin_(state_(m_var4)),end_(state_(m_var4)),begin_(state_(m_var2)),begin_(state_(m_var4)),
304 // Predicate_<std::plus<int> >())
305 //,process_(Done,fsm_(),fsm_)
306 //,process_(Done,fsm_)
308 //,foobar_(state_,Int_<0>(),Int_<1>())
309 //,nth_element_(begin_(state_(m_var9)),++begin_(state_(m_var9)),end_(state_(m_var9)),Predicate_<std::less<int> >())
310 //,partial_sort_(begin_(state_(m_var9)),end_(state_(m_var9)),end_(state_(m_var9)),Predicate_<std::less<int> >())
311 //,partial_sort_copy_(begin_(state_(m_var9)),end_(state_(m_var9)),begin_(state_(m_var9)),end_(state_(m_var9)),Predicate_<std::less<int> >())
312 //,list_sort_(state_(m_var2))
313 //,sort_(begin_(state_(m_var9)),end_(state_(m_var9)),Predicate_<std::less<int> >())
314 //,inner_product_(begin_(state_(m_var9)),end_(state_(m_var9)),begin_(state_(m_var9)),Int_<1>())
315 //,replace_copy_(begin_(state_(m_var4)),end_(state_(m_var4)),begin_(state_(m_var4)),Int_<8>(),Int_<7>())
316 //,replace_copy_if_(begin_(state_(m_var4)),end_(state_(m_var4)),begin_(state_(m_var4)),Predicate_<LookFor<9> >(),Int_<8>())
317 //,replace_(begin_(state_(m_var4)),end_(state_(m_var4)),Int_<8>(),Int_<7>())
318 //,replace_if_(begin_(state_(m_var4)),end_(state_(m_var4)),Predicate_<LookFor<9> >(),Int_<8>())
319 //,adjacent_difference_(begin_(state_(m_var9)),end_(state_(m_var9)),begin_(state_(m_var9)))
320 //,partial_sum_(begin_(state_(m_var9)),end_(state_(m_var9)),begin_(state_(m_var9)))
321 //,inner_product_(begin_(state_(m_var9)),end_(state_(m_var9)),begin_(state_(m_var9)),Int_<1>())
322 //,next_permutation_(begin_(state_(m_var9)),end_(state_(m_var9)),Predicate_<std::less<int> >())
323 //,prev_permutation_(begin_(state_(m_var9)),end_(state_(m_var9)),Predicate_<std::less<int> >())
324 //,set_union_(begin_(state_(m_var9)),end_(state_(m_var9)),begin_(state_(m_var9)),end_(state_(m_var9)),begin_(state_(m_var9)))
325 //,inplace_merge_(begin_(state_(m_var9)),end_(state_(m_var9)),end_(state_(m_var9)),Predicate_<std::less<int> >())
326 //,merge_(begin_(state_(m_var9)),end_(state_(m_var9)),begin_(state_(m_var9)),end_(state_(m_var9))
327 // ,begin_(state_(m_var9)),Predicate_<std::less<int> >())
328 //,stable_sort_(begin_(state_(m_var9)),end_(state_(m_var9)),Predicate_<std::less<int> >())
329 //,partition_(begin_(state_(m_var2)),end_(state_(m_var2)),Predicate_<LessThan<3> >())
330 //,stable_partition_(begin_(state_(m_var2)),end_(state_(m_var2)),Predicate_<LessThan<3> >())
331 //,rotate_copy_(begin_(state_(m_var2)),++begin_(state_(m_var2)),end_(state_(m_var2)),begin_(state_(m_var2)))
332 //,rotate_(begin_(state_(m_var2)),++begin_(state_(m_var2)),end_(state_(m_var2)))
333 //,unique_(begin_(state_(m_var2)),end_(state_(m_var2)))
334 //,unique_copy_(begin_(state_(m_var2)),end_(state_(m_var2)),begin_(state_(m_var2)))
335 //,random_shuffle_(begin_(state_(m_var9)),end_(state_(m_var9)))
336 //,generate_(begin_(state_(m_var9)),end_(state_(m_var9)),Predicate_<Generator>())
337 //,generate_n_(begin_(state_(m_var9)),Int_<2>(),Predicate_<Generator>())
338 //,reverse_copy_(begin_(state_(m_var2)),end_(state_(m_var2)),begin_(state_(m_var2)))
339 //erase_(state_(m_src_container),
340 // remove_if_(begin_(state_(m_src_container)),end_(state_(m_src_container)),
341 // Predicate_<RemoveDummy>()),
342 // end_(state_(m_src_container))),
343 //list_remove_(state_(m_var2),Int_<3>()),
344 //remove_copy_if_(begin_(state_(m_var9)),end_(state_(m_var9)),back_inserter_(state_(m_var2)),
345 // Predicate_<LookFor<2> >() )
346 //for_each_(begin_(state_(m_src_container)),end_(state_m_src_container()),
347 // Predicate_<Print>() ),
348 //copy_(begin_(state_(m_var9)),end_(state_(m_var9)),inserter_(state_(m_var2),end_(state_(m_var2)))),
349 //reverse_(begin_(state_(m_var2)),end_(state_(m_var2)))
351 //no_action, // Entry
352 //splice_(state_(m_var2),begin_(state_(m_var2)),state_(m_var3),begin_(state_(m_var3)),end_(state_(m_var3))),
353 //(list_remove_(state_(m_var2),Int_<3>()),list_merge_(state_(m_var2),state_(m_var3),Comparator())),//no_action, // Entry
355 attributes_
<< m_src_container
// song list
356 << m_tgt_container
// result
366 configure_
<< no_configure_
,
370 struct iPodSearch_
: public iPodSearch_helper
, public some_base
375 // choice of back-end
376 typedef msm::back::state_machine
<iPodSearch_
> iPodSearch
;
381 // fill our song list
382 //search.get_attribute<m_src_container>().push_back(OneSong("She-Dummy. Remove this one"));
383 search
.get_attribute(m_src_container
).push_back(OneSong_impl("Let it be"));
384 search
.get_attribute(m_src_container
).push_back(OneSong_impl("Yellow submarine"));
385 search
.get_attribute(m_src_container
).push_back(OneSong_impl("Twist and Shout"));
386 search
.get_attribute(m_src_container
).push_back(OneSong_impl("She Loves You"));
388 search
.get_attribute(m_var2
).push_back(1);
389 search
.get_attribute(m_var2
).push_back(3);
390 search
.get_attribute(m_var2
).push_back(4);
392 search
.get_attribute(m_var3
).push_back(2);
393 search
.get_attribute(m_var3
).push_back(4);
395 search
.get_attribute(m_var6
) = "S";
396 search
.get_attribute(m_var7
) = "- Some text";
398 search
.get_attribute(m_var8
).push_back(1);
399 search
.get_attribute(m_var8
).push_back(2);
400 search
.get_attribute(m_var8
).push_back(3);
401 search
.get_attribute(m_var8
).push_back(4);
403 search
.get_attribute(m_var9
).push_back(1);
404 search
.get_attribute(m_var9
).push_back(2);
407 // look for "She Loves You" using the first letters
408 // BOOST_MSM_EUML_STATE_NAME returns the name of the event type of which StringFind is an instance
409 search
.get_state
<BOOST_MSM_EUML_STATE_NAME(StringFind
)&>().get_attribute(m_letters
)="Sh";
410 // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
412 // display all the songs
413 for (list
<OneSong_impl
>::const_iterator it
= search
.get_attribute(m_tgt_container
).begin();
414 it
!= search
.get_attribute(m_tgt_container
).end();++it
)
416 cout
<< "candidate song:" << (*it
).get_data() << endl
;
418 for (list
<int>::const_iterator iti
= search
.get_attribute(m_var2
).begin();
419 iti
!= search
.get_attribute(m_var2
).end();++iti
)
421 cout
<< "int in attribute m_var2:" << (*iti
) << endl
;
423 for (set
<int>::const_iterator its
= search
.get_attribute(m_var4
).begin();
424 its
!= search
.get_attribute(m_var4
).end();++its
)
426 cout
<< "int in attribute m_var4:" << (*its
) << endl
;
428 cout
<< "search using more letters" << endl
;
429 // look for "She Loves You" using more letters
430 search
.get_state
<BOOST_MSM_EUML_STATE_NAME(StringFind
)&>().get_attribute(m_letters
)="She";
431 search
.get_attribute(m_tgt_container
).clear();
433 // display all the songs
434 for (list
<OneSong_impl
>::const_iterator it
= search
.get_attribute(m_tgt_container
).begin();
435 it
!= search
.get_attribute(m_tgt_container
).end();++it
)
437 cout
<< "candidate song:" << (*it
).get_data() << endl
;