21#ifndef G_STATE_MACHINE_H
22#define G_STATE_MACHINE_H
30 template <
typename T,
typename State,
typename Event,
typename Argument>
class StateMachine ;
31 class StateMachineImp ;
108template <
typename T,
typename State,
typename Event,
typename Argument>
112 using Action = void (T::*)(Argument,
bool &) ;
114 StateMachine( State s_start , State s_end , State s_same , State s_any ) ;
152 static void throwError() ;
161 Transition(State s1,State s2,Action a,State s3) :
162 from(s1) , to(s2) , alt(s3) , action(a) {}
164 using Map = std::multimap<Event,Transition> ;
165 using Map_value_type =
typename Map::value_type ;
177class G::StateMachineImp
180 G_EXCEPTION( Error ,
tx(
"invalid state transition") )
181 static
void throwError() ;
182 StateMachineImp() = delete ;
185template <typename T, typename State, typename Event, typename Argument>
194template <
typename T,
typename State,
typename Event,
typename Argument>
197 operator()( event , from , to , action , to ) ;
200template <
typename T,
typename State,
typename Event,
typename Argument>
203 if( to == m_any || alt == m_any || from == m_same ||
204 ( to == m_end && alt != to ) ||
205 ( alt == m_end && to != m_end ) )
206 StateMachineImp::throwError() ;
208 m_map.insert( Map_value_type( event , Transition(from,to,action,alt) ) ) ;
211template <
typename T,
typename State,
typename Event,
typename Argument>
214 State old_state = m_state ;
215 m_state = new_state ;
219template <
typename T,
typename State,
typename Event,
typename Argument>
225template <
typename T,
typename State,
typename Event,
typename Argument>
229 State state = m_state ;
230 auto p = m_map.find( event ) ;
231 for( ; p != m_map.end() && (*p).first == event ; ++p )
233 if( (*p).second.from == m_any || (*p).second.from == m_state )
235 State old_state = m_state ;
236 if( (*p).second.to != m_same )
237 state = m_state = (*p).second.to ;
241 bool predicate = true ;
242 (t.*((*p).second.action))( arg , predicate ) ;
244 if( state != end && !predicate )
246 State alt_state = (*p).second.alt ;
247 state = m_state = alt_state == m_same ? old_state : alt_state ;
255template <
typename T,
typename State,
typename Event,
typename Argument>
A finite state machine class template.
State state() const
Returns the current state.
void operator()(Event event, State from, State to, Action action, State alt)
An overload which adds a transition with predicate support.
Event event() const
Returns the last-apply()d event.
State apply(T &t, Event event, Argument arg)
Applies an event.
State reset(State new_state)
Sets the current state. Returns the old state.
void operator()(Event event, State from, State to, Action action)
Adds a transition.
StateMachine(State s_start, State s_end, State s_same, State s_any)
Constructor.
constexpr const char * tx(const char *p) noexcept
A briefer alternative to G::gettext_noop().