1 | // Copyright 2024 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 <iostream> |
12 | |
13 | #ifdef __APPLE__ |
14 | #pragma clang diagnostic push |
15 | #pragma clang diagnostic ignored "-Wunused-variable" |
16 | #endif |
17 | #include <boost/msm/back/state_machine.hpp> |
18 | #include <boost/msm/front/euml/common.hpp> |
19 | #include <boost/msm/front/functor_row.hpp> |
20 | #include <boost/msm/front/state_machine_def.hpp> |
21 | #ifdef __APPLE__ |
22 | #pragma clang diagnostic pop |
23 | #endif |
24 | |
25 | #ifndef BOOST_MSM_NONSTANDALONE_TEST |
26 | #define BOOST_TEST_MODULE back11_anonymous_and_guard_test |
27 | #endif |
28 | #include <boost/test/unit_test.hpp> |
29 | |
30 | |
31 | namespace bmf = boost::msm::front; |
32 | |
33 | // events |
34 | struct success { |
35 | success(size_t value) : value(value) {} |
36 | size_t value; |
37 | }; |
38 | struct failure { |
39 | }; |
40 | |
41 | // frontend |
42 | struct Bug : public bmf::state_machine_def<Bug> { |
43 | // list of FSM states |
44 | struct Init : public bmf::state<> { |
45 | }; |
46 | struct Idle : public bmf::state<> { |
47 | }; |
48 | struct Completed : public bmf::terminate_state<> { |
49 | }; |
50 | |
51 | // defines an orthogonal region |
52 | struct Running : public bmf::state<> { |
53 | }; |
54 | |
55 | // actions |
56 | struct log_action { |
57 | template<class Event, class FSM, class SourceState, class TargetState> |
58 | void operator()(const Event&, FSM&, SourceState&, TargetState&) |
59 | { |
60 | } |
61 | }; |
62 | |
63 | // guards |
64 | struct validate { |
65 | template<class Event, class FSM, class SourceState, class TargetState> |
66 | bool operator()(const Event& e, FSM&, SourceState&, TargetState&) |
67 | { |
68 | return e.value > 0; |
69 | } |
70 | }; |
71 | |
72 | // state machine properties |
73 | typedef boost::mpl::vector2<Running, Init> initial_state; |
74 | |
75 | // Transition table for traceroute |
76 | struct transition_table : boost::mpl::vector< |
77 | // Start Event Next Action Guard |
78 | // +----------+---------------+-----------+------------------------+--------------------+ |
79 | bmf::Row< Running, success, bmf::none, log_action, validate >, |
80 | // +---------+-------------+---------+---------------------------+----------------------+ |
81 | bmf::Row< Init, success, Idle, log_action, bmf::none >, |
82 | bmf::Row< Init, failure, Idle, log_action, bmf::none >, |
83 | bmf::Row< Idle, bmf::none, Completed, log_action, bmf::none > |
84 | // +---------+-------------+---------+---------------------------+----------------------+ |
85 | > {}; |
86 | }; |
87 | |
88 | // backend |
89 | typedef boost::msm::back::state_machine<Bug> MyStateMachine; |
90 | |
91 | BOOST_AUTO_TEST_CASE(back11_anonymous_and_guard_test1) |
92 | { |
93 | MyStateMachine sm; |
94 | sm.start(); |
95 | sm.process_event(evt: success(0)); |
96 | BOOST_CHECK_MESSAGE(sm.current_state()[0] == 0, "Running should be active" ); |
97 | BOOST_CHECK_MESSAGE(sm.current_state()[1] == 3, "Completed should be active" ); |
98 | } |
99 | |
100 | BOOST_AUTO_TEST_CASE(back11_anonymous_and_guard_test2) |
101 | { |
102 | MyStateMachine sm; |
103 | sm.start(); |
104 | sm.process_event(evt: success(1)); |
105 | BOOST_CHECK_MESSAGE(sm.current_state()[0] == 0, "Running should be active" ); |
106 | BOOST_CHECK_MESSAGE(sm.current_state()[1] == 3, "Completed should be active" ); |
107 | } |
108 | |