21#ifndef G_STATE_MACHINE_H
22#define G_STATE_MACHINE_H
31G_EXCEPTION_CLASS( StateMachine_Error ,
"invalid state machine transition" ) ;
107template <
typename T,
typename State,
typename Event,
typename Arg>
111 using Action = void (T::*)(
Arg,
bool &) ;
112 using Error = StateMachine_Error ;
114 StateMachine( State s_start , State s_end , State s_same , State s_any ) ;
117 void operator()( Event event , State from , State to , Action action ) ;
121 void operator()( Event event , State from , State to , Action action , State alt ) ;
155 Transition(State s1,State s2,Action a,State s3) :
156 from(s1) , to(s2) , alt(s3) , action(a) {}
158 using Map = std::multimap<Event,Transition> ;
159 using Map_value_type =
typename Map::value_type ;
167template <
typename T,
typename State,
typename Event,
typename Arg>
176template <
typename T,
typename State,
typename Event,
typename Arg>
179 operator()( event , from , to , action , to ) ;
182template <
typename T,
typename State,
typename Event,
typename Arg>
185 if( to == m_any || alt == m_any )
186 throw Error(
"\"to any\" is invalid" ) ;
189 throw Error(
"\"from same\" is invalid" ) ;
191 if( to == m_end && alt != to )
192 throw Error(
"predicates on end-state transitions are invalid" ) ;
194 if( alt == m_end && to != m_end )
195 throw Error(
"false predicates cannot take you to the end state" ) ;
197 m_map.insert( Map_value_type( event , Transition(from,to,action,alt) ) ) ;
200template <
typename T,
typename State,
typename Event,
typename Arg>
203 State old_state = m_state ;
204 m_state = new_state ;
208template <
typename T,
typename State,
typename Event,
typename Arg>
214template <
typename T,
typename State,
typename Event,
typename Arg>
217 State state = m_state ;
218 auto p = m_map.find( event ) ;
219 for( ; p != m_map.end() && (*p).first == event ; ++p )
221 if( (*p).second.from == m_any || (*p).second.from == m_state )
223 State old_state = m_state ;
224 if( (*p).second.to != m_same )
225 state = m_state = (*p).second.to ;
229 bool predicate = true ;
230 (t.*((*p).second.action))( arg , predicate ) ;
232 if( state != end && !predicate )
234 State alt_state = (*p).second.alt ;
235 state = m_state = alt_state == m_same ? old_state : alt_state ;
A class which holds a represention of the argc/argv command line array, and supports simple command-l...
A finite state machine class template.
void operator()(Event event, State from, State to, Action action)
Adds a transition.
State reset(State new_state)
Sets the current state. Returns the old state.
StateMachine(State s_start, State s_end, State s_same, State s_any)
Constructor.
void operator()(Event event, State from, State to, Action action, State alt)
An overload which adds a transition with predicate support.
State apply(T &t, Event event, Arg arg)
Applies an event.
State state() const
Returns the current state.