I'm writing a finite state machine based on a transition table in C++ 14. My code so far looks like:
#include <array>
#include <functional>
template < typename _State, typename _Event >
class FSM {
static constexpr size_t state_count = static_cast<size_t>(_Event::_);
static constexpr size_t event_count = static_cast<size_t>(_State::_);
using _FuncPtr = typename std::function<_State(_State)>;
using _Table = typename std::array< std::array< _FuncPtr, state_count >, event_count >;
_State _current;
_Table _transitions;
public:
FSM(_State initial, _Table transitions) : _current(initial), _transitions(transitions) {};
void operator()(const _Event& event) {
_current = _transitions[static_cast<size_t>(event)][static_cast<size_t>(_current)](_current);
}
_State state() const { return _current; }
};
The usage looks like:
/* States & Events */
enum class State : char { Locked, Unlocked, _ };
enum class Event : char { Pass, Coin, _ };
/* Transitions */
State alarm(State current) {
cout << "Alarm" << endl;
return current;
}
State unlock(State current) {
cout << "Unlock" << endl;
return State::Unlocked;
}
State lock(State current) {
cout << "Lock" << endl;
return State::Locked;
}
State thankyou(State current) {
cout << "Thankyou" << endl;
return current;
}
void main() {
auto fsm = FSM< State, Event >(State::Locked, {{
// Locked Unlocked
{ alarm, lock }, // Pass
{ unlock, thankyou } // Coin
}});
// To switch states
fsm(Event::Coin);
fsm(Event::Pass);
}
Is there some way I can further simplify it?
operator()
\$\endgroup\$