File: TransitionSkipping.cpp

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (151 lines) | stat: -rw-r--r-- 6,030 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright 2010 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <iostream>

#ifndef BOOST_MSM_NONSTANDALONE_TEST
#define BOOST_TEST_MODULE transition_skipping_test
#endif
#include <boost/test/unit_test.hpp>
#include <boost/core/demangle.hpp>
#include "BackCommon.hpp"

// front-end
#include <boost/fusion/include/insert_range.hpp>
#include <boost/msm/front/euml/operator.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/state_machine_def.hpp>


template <typename ...T>
using msm_flags = boost::mpl::vector<T...>;
template <typename ...T>
using msm_transition_table = boost::mpl::vector<T...>;



namespace msmf = boost::msm::front;
namespace euml = boost::msm::front::euml;

struct evt1 {};
struct evt2 {};
struct evt3 {};

struct top_ : public msmf::state_machine_def<top_> {
    int count_guard_false = 0;
    int count_guard_true = 0;


    struct nested : public msmf::state<> {
        template <class Event, class FSM>
        void on_entry(Event const&, FSM&) { ++entry_counter; }
        template <class Event, class FSM>
        void on_exit(Event const&, FSM&) { ++exit_counter; }
        int entry_counter=0;
        int exit_counter=0;
    };

    struct other1 : public msmf::state<> {
        template <class Event, class FSM>
        void on_entry(Event const&, FSM&) { ++entry_counter; }
        template <class Event, class FSM>
        void on_exit(Event const&, FSM&) { ++exit_counter; }
        int entry_counter = 0;
        int exit_counter = 0;
    };

    struct other2 : public msmf::state<> {
        template <class Event, class FSM>
        void on_entry(Event const&, FSM&) { ++entry_counter; }
        template <class Event, class FSM>
        void on_exit(Event const&, FSM&) { ++exit_counter; }
        int entry_counter = 0;
        int exit_counter = 0;
    };

    struct other3 : public msmf::state<> {
        template <class Event, class FSM>
        void on_entry(Event const&, FSM&) { ++entry_counter; }
        template <class Event, class FSM>
        void on_exit(Event const&, FSM&) { ++exit_counter; }
        int entry_counter = 0;
        int exit_counter = 0;
    };

    struct other4 : public msmf::state<> {
        template <class Event, class FSM>
        void on_entry(Event const&, FSM&) { ++entry_counter; }
        template <class Event, class FSM>
        void on_exit(Event const&, FSM&) { ++exit_counter; }
        int entry_counter = 0;
        int exit_counter = 0;
    };
    struct other5 : public msmf::state<> {
        template <class Event, class FSM>
        void on_entry(Event const&, FSM&) { ++entry_counter; }
        template <class Event, class FSM>
        void on_exit(Event const&, FSM&) { ++exit_counter; }
        int entry_counter = 0;
        int exit_counter = 0;
    };

    struct guard_true {
        template <class EVT, class FSM, class SourceState, class TargetState>
        bool operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) const {
            ++fsm.count_guard_true;
            return true;
        }
    };

    struct guard_false {
        template <class EVT, class FSM, class SourceState, class TargetState>
        bool operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) const {
            ++fsm.count_guard_false;
            return false;
        }
    };


    typedef nested initial_state;

    using transition_table = msm_transition_table<
        //          Start        Event     Next         Action      Guard
        //--------+------------+---------+------------+-----------+--------------
        msmf::Row < nested, msmf::none, other1, msmf::none, guard_false>,
        msmf::Row < nested, msmf::none, other2, msmf::none, guard_true >,  // <- this transition is not executed with back11
        msmf::Row < nested, msmf::none, other3, msmf::none, guard_false>,
        msmf::Row < nested, msmf::none, other4, msmf::none, guard_false>,
        msmf::Row < other1, evt3, nested, msmf::none, msmf::none       >
    >;
};

using tops = get_test_machines<top_>;
   

BOOST_AUTO_TEST_CASE_TEMPLATE(transition_skipping_test, top, tops)
{
    top msm;
    msm.start();
    BOOST_CHECK_MESSAGE(msm.count_guard_true == 1, "guard_true should be called once");
    BOOST_CHECK_MESSAGE(msm.count_guard_false == 2, "guard_false should be called once");

    BOOST_CHECK_MESSAGE(msm.template get_state<top_::nested&>().exit_counter == 1, "nested exit not called correctly");
    BOOST_CHECK_MESSAGE(msm.template get_state<top_::nested&>().entry_counter == 1, "nested entry not called correctly");
    BOOST_CHECK_MESSAGE(msm.template get_state<top_::other2&>().exit_counter == 0, "other2 exit not called correctly");
    BOOST_CHECK_MESSAGE(msm.template get_state<top_::other2&>().entry_counter == 1, "other2 entry not called correctly");
    BOOST_CHECK_MESSAGE(msm.template get_state<top_::other1&>().exit_counter == 0, "other1 exit not called correctly");
    BOOST_CHECK_MESSAGE(msm.template get_state<top_::other1&>().entry_counter == 0, "other1 entry not called correctly");
    BOOST_CHECK_MESSAGE(msm.template get_state<top_::other3&>().exit_counter == 0, "other3 exit not called correctly");
    BOOST_CHECK_MESSAGE(msm.template get_state<top_::other3&>().entry_counter == 0, "other3 entry not called correctly");
    BOOST_CHECK_MESSAGE(msm.template get_state<top_::other4&>().exit_counter == 0, "other4 exit not called correctly");
    BOOST_CHECK_MESSAGE(msm.template get_state<top_::other4&>().entry_counter == 0, "other4 entry not called correctly");
    BOOST_CHECK_MESSAGE(msm.current_state()[0] == 2, "other2 should be active"); //Open

}