Skip to content

Instantly share code, notes, and snippets.

@murphybytes
Created February 21, 2012 19:59
Show Gist options
  • Select an option

  • Save murphybytes/1878522 to your computer and use it in GitHub Desktop.

Select an option

Save murphybytes/1878522 to your computer and use it in GitHub Desktop.
Handy templated state machine for C++
#include <boost/test/minimal.hpp>
#include "state_machine.hpp"
#include <vector>
// define states
enum states_t {
init,
state_one,
state_two,
state_three,
term
};
// define state machine
typedef ucp::state_machine< states_t, init, term > state_machine_t;
vector< states_t > states;
struct init_handler {
states_t operator()() { states.push_back( init ); return state_one; }
};
struct state_one_handler {
states_t operator() () { states.push_back( state_one ); return state_three; }
};
struct state_three_handler {
states_t operator() () { states.push_back( state_three ); return term; }
};
int main( int argc, char* argv[] ) {
state_machine_t state_machine;
state_machine.add_operations()
( init, init_handler() )
( state_one, state_one_handler() )
( state_three, state_three_handler() )
;
state_machine.run() ;
BOOST_CHECK( states[0] == init );
BOOST_CHECK( states[1] == state_one );
BOOST_CHECK( states[2] == state_three );
return 0;
}
#include <boost/functional.hpp>
#include <map>
namespace ucp {
template< typename state_enum_t, state_enum_t initial_state, state_enum_t terminal_state >
class state_machine {
typedef std::map< state_enum_t, boost::function< state_enum_t ( ) > > state_map_t;
state_map_t state_map_;
public:
state_machine( ) {}
~state_machine() {}
state_machine< state_enum_t, initial_state, terminal_state >& add_operations() {
return *this;
}
state_machine< state_enum_t, initial_state, terminal_state >& operator()( state_enum_t state, boost::function< state_enum_t () > operation ) {
state_map_[state] = operation;
return *this;
}
void run( ) {
state_enum_t state = initial_state;
while( state != terminal_state ) {
state = state_map_[ state ]() ;
}
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment