Skip to content

Instantly share code, notes, and snippets.

@TABETA
Created March 27, 2016 11:26
Show Gist options
  • Save TABETA/f9151b5f8235f860598f to your computer and use it in GitHub Desktop.
Save TABETA/f9151b5f8235f860598f to your computer and use it in GitHub Desktop.
整数値をキーとしたstateパターンをtemplateで実現 ref: http://qiita.com/abedominal/items/73e2a9448330837ea6d6
#include <iostream>
#include <iomanip>
#include <cstdint>
using namespace std;
template <typename T>
class Singleton
{
protected:
Singleton(){}
Singleton(Singleton const&);
~Singleton(){}
Singleton& operator=(Singleton const&);
public:
static T* getInstance()
{
static T i;
return &i;
}
};
class IState
{
public:
IState(){}
virtual ~IState(){}
virtual void action() = 0;
virtual uint8_t getNextState() = 0;
};
template<uint8_t N> class State;
template<>
class State<0> :public IState, public Singleton<State<0> >
{
public:
void action(){ cout << "State0" << endl; }
uint8_t getNextState()
{
return 1;
}
};
template<>
class State<1> :public IState, public Singleton<State<1> >
{
public:
void action(){ cout << "State1" << endl; }
uint8_t getNextState()
{
return 0;
}
};
template<uint8_t N>
static void initialize(IState* s[])
{
s[N - 1] = State<N - 1>::getInstance();
initialize<N-1>(s);
}
template<>
static void initialize<0>(IState* s[])
{
s[0] = State<0>::getInstance();
}
class StateMachine
{
public:
static const int N = 2;
StateMachine():cur_()
{
initialize<N>(states_);
}
void transit()
{
states_[cur_]->action();
cur_ = states_[cur_]->getNextState();
}
private:
IState* states_[N];
uint8_t cur_;
};
int main(int argv, char* argc[])
{
StateMachine state;
state.transit();
state.transit();
state.transit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment