1//////////////////////////////////////////////////////////////////////////////
2// Copyright 2005-2006 Andreas Huber Doenni
3// Distributed under the Boost Software License, Version 1.0. (See accompany-
4// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5//////////////////////////////////////////////////////////////////////////////
6
7
8
9#include <boost/statechart/state_machine.hpp>
10#include <boost/statechart/event.hpp>
11#include <boost/statechart/simple_state.hpp>
12#include <boost/statechart/state.hpp>
13#include <boost/statechart/transition.hpp>
14#include <boost/statechart/custom_reaction.hpp>
15
16#include <boost/mpl/list.hpp>
17#include <boost/intrusive_ptr.hpp>
18
19#include <boost/test/test_tools.hpp>
20
21
22
23namespace sc = boost::statechart;
24namespace mpl = boost::mpl;
25
26
27
28struct EvToB : sc::event< EvToB > {};
29struct EvToF : sc::event< EvToF > {};
30struct EvCheck : sc::event< EvCheck > {};
31
32struct A;
33struct StateCastTest : sc::state_machine< StateCastTest, A >
34{
35 template< class State >
36 void AssertInState()
37 {
38 BOOST_REQUIRE( state_downcast< const State * >() != 0 );
39 BOOST_REQUIRE_NO_THROW( state_downcast< const State & >() );
40 BOOST_REQUIRE( state_cast< const State * >() != 0 );
41 BOOST_REQUIRE_NO_THROW( state_cast< const State & >() );
42 }
43
44 template< class State >
45 void AssertNotInState()
46 {
47 BOOST_REQUIRE( state_downcast< const State * >() == 0 );
48 BOOST_REQUIRE_THROW( state_downcast< const State & >(), std::bad_cast );
49 BOOST_REQUIRE( state_cast< const State * >() == 0 );
50 BOOST_REQUIRE_THROW( state_cast< const State & >(), std::bad_cast );
51 }
52};
53
54template< class State, class FromState >
55void AssertInState( const FromState & theState )
56{
57 BOOST_REQUIRE( theState.template state_downcast< const State * >() != 0 );
58 BOOST_REQUIRE_NO_THROW( theState.template state_downcast< const State & >() );
59 BOOST_REQUIRE( theState.template state_cast< const State * >() != 0 );
60 BOOST_REQUIRE_NO_THROW( theState.template state_cast< const State & >() );
61}
62
63template< class State, class FromState >
64void AssertNotInState( const FromState & theState )
65{
66 BOOST_REQUIRE( theState.template state_downcast< const State * >() == 0 );
67 BOOST_REQUIRE_THROW( theState.template state_downcast< const State & >(), std::bad_cast );
68 BOOST_REQUIRE( theState.template state_cast< const State * >() == 0 );
69 BOOST_REQUIRE_THROW( theState.template state_cast< const State & >(), std::bad_cast );
70}
71
72struct B;
73struct C;
74struct D;
75struct A : sc::simple_state< A, StateCastTest, mpl::list< C, D > >
76{
77 typedef sc::transition< EvToB, B > reactions;
78};
79
80 struct E;
81 struct C : sc::simple_state< C, A::orthogonal< 0 >, E > {};
82
83 struct E : sc::state< E, C >
84 {
85 typedef sc::custom_reaction< EvCheck > reactions;
86
87 E( my_context ctx ) : my_base( ctx )
88 {
89 post_event( pEvent: boost::intrusive_ptr< EvCheck >( new EvCheck() ) );
90 }
91
92 sc::result react( const EvCheck & );
93 };
94
95 struct F : sc::state< F, C >
96 {
97 typedef sc::custom_reaction< EvCheck > reactions;
98
99 F( my_context ctx ) : my_base( ctx )
100 {
101 post_event( pEvent: boost::intrusive_ptr< EvCheck >( new EvCheck() ) );
102 }
103
104 sc::result react( const EvCheck & );
105 };
106
107 struct G;
108 struct D : sc::simple_state< D, A::orthogonal< 1 >, G > {};
109
110 struct G : sc::simple_state< G, D > {};
111 struct H : sc::simple_state< H, D > {};
112
113struct B : sc::simple_state< B, StateCastTest >
114{
115 typedef sc::transition< EvToF, F > reactions;
116};
117
118sc::result E::react( const EvCheck & )
119{
120 AssertInState< A >( theState: *this );
121 AssertNotInState< B >( theState: *this );
122 AssertInState< C >( theState: *this );
123 AssertInState< D >( theState: *this );
124 AssertInState< E >( theState: *this );
125 AssertNotInState< F >( theState: *this );
126 AssertInState< G >( theState: *this );
127 AssertNotInState< H >( theState: *this );
128 return discard_event();
129}
130
131sc::result F::react( const EvCheck & )
132{
133 AssertInState< A >( theState: *this );
134 AssertNotInState< B >( theState: *this );
135 AssertInState< C >( theState: *this );
136 AssertInState< D >( theState: *this );
137 AssertNotInState< E >( theState: *this );
138 AssertInState< F >( theState: *this );
139 AssertInState< G >( theState: *this );
140 AssertNotInState< H >( theState: *this );
141 return discard_event();
142}
143
144
145int test_main( int, char* [] )
146{
147 StateCastTest machine;
148
149 machine.AssertNotInState< A >();
150 machine.AssertNotInState< B >();
151 machine.AssertNotInState< C >();
152 machine.AssertNotInState< D >();
153 machine.AssertNotInState< E >();
154 machine.AssertNotInState< F >();
155 machine.AssertNotInState< G >();
156 machine.AssertNotInState< H >();
157
158 machine.initiate();
159
160 machine.AssertInState< A >();
161 machine.AssertNotInState< B >();
162 machine.AssertInState< C >();
163 machine.AssertInState< D >();
164 machine.AssertInState< E >();
165 machine.AssertNotInState< F >();
166 machine.AssertInState< G >();
167 machine.AssertNotInState< H >();
168
169 machine.process_event( evt: EvToB() );
170
171 machine.AssertNotInState< A >();
172 machine.AssertInState< B >();
173 machine.AssertNotInState< C >();
174 machine.AssertNotInState< D >();
175 machine.AssertNotInState< E >();
176 machine.AssertNotInState< F >();
177 machine.AssertNotInState< G >();
178 machine.AssertNotInState< H >();
179
180 machine.process_event( evt: EvToF() );
181
182 machine.AssertInState< A >();
183 machine.AssertNotInState< B >();
184 machine.AssertInState< C >();
185 machine.AssertInState< D >();
186 machine.AssertNotInState< E >();
187 machine.AssertInState< F >();
188 machine.AssertInState< G >();
189 machine.AssertNotInState< H >();
190
191 machine.terminate();
192
193 machine.AssertNotInState< A >();
194 machine.AssertNotInState< B >();
195 machine.AssertNotInState< C >();
196 machine.AssertNotInState< D >();
197 machine.AssertNotInState< E >();
198 machine.AssertNotInState< F >();
199 machine.AssertNotInState< G >();
200 machine.AssertNotInState< H >();
201
202 return 0;
203}
204

source code of boost/libs/statechart/test/StateCastTest.cpp