Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <type_traits>
- #include <iostream>
- template<int ToSearch, class ... List>
- struct ValueSearcher
- {
- using type = void;
- };
- template<int ToSearch, class First, class...Rest>
- struct ValueSearcher<ToSearch, First, Rest...> : ValueSearcher<ToSearch, Rest...>
- {
- using next = ValueSearcher<ToSearch, Rest...>;
- using type = std::conditional_t<ToSearch == First::value, First, typename next::type>;
- };
- template<int ToSearch, class Last>
- struct ValueSearcher<ToSearch, Last>
- {
- using type = std::conditional_t<ToSearch == Last::value, Last, void>;
- };
- template<int ToSearch, class...List>
- using ValueSearcherT = typename ValueSearcher<ToSearch, List...>::type;
- template<int Event, int State>
- struct Move
- {
- constexpr static const int value = Event;
- constexpr static const int state = State;
- };
- template<int State, class ... Moves>
- struct MoveList
- {
- template<int ToSearch>
- using get_move = ValueSearcherT<ToSearch, Moves...>;
- constexpr static const int value = State;
- };
- template<int State, class ... MoveLists>
- struct FSM
- {
- constexpr inline static int state = State;
- template<int Event>
- using make_move = FSM<ValueSearcherT<State, MoveLists...>::template get_move<Event>::state, MoveLists...>;
- template<int First, int...Rest>
- static typename make_move<First>::template apply_moves<Rest...> apply_moves_f();
- template<int First>
- static make_move<First> apply_moves_f();
- template<int...Events>
- using apply_moves = decltype(apply_moves_f<Events...>());
- };
- enum States
- {
- A, B, C
- };
- enum Events
- {
- a, b, c, d
- };
- void print_state(int state)
- {
- std::cout << char ('A' + state) << '\n';
- }
- int main() {
- using list_0 = MoveList<A, Move<a, B>, Move<c, B>, Move<d, C>>;
- using list_1 = MoveList<B, Move<a, A>, Move<b, C>>;
- using list_2 = MoveList<C>;
- using fsm = FSM<0, list_0, list_1, list_2>;
- using result_fms = fsm::apply_moves<a, a, c, b>; // (A) --a--> (B) --a--> (A) --c--> (B) --b--> (C);
- print_state(result_fms::state);
- }
Add Comment
Please, Sign In to add comment