EeZotop

Compile time FSM

Aug 28th, 2020 (edited)
333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.06 KB | None | 0 0
  1. #include <type_traits>
  2. #include <iostream>
  3.  
  4. template<int ToSearch, class ... List>
  5. struct ValueSearcher
  6. {
  7.     using type = void;
  8. };
  9.  
  10. template<int ToSearch, class First, class...Rest>
  11. struct ValueSearcher<ToSearch, First, Rest...> : ValueSearcher<ToSearch, Rest...>
  12. {
  13.     using next = ValueSearcher<ToSearch, Rest...>;
  14.     using type = std::conditional_t<ToSearch == First::value, First, typename next::type>;
  15. };
  16.  
  17. template<int ToSearch, class Last>
  18. struct ValueSearcher<ToSearch, Last>
  19. {
  20.     using type = std::conditional_t<ToSearch == Last::value, Last, void>;
  21. };
  22.  
  23. template<int ToSearch, class...List>
  24. using ValueSearcherT = typename ValueSearcher<ToSearch, List...>::type;
  25.  
  26. template<int Event, int State>
  27. struct Move
  28. {
  29.     constexpr static const int value = Event;
  30.     constexpr static const int state = State;
  31. };
  32.  
  33. template<int State, class ... Moves>
  34. struct MoveList
  35. {
  36.     template<int ToSearch>
  37.     using get_move = ValueSearcherT<ToSearch, Moves...>;
  38.  
  39.     constexpr static const int value = State;
  40. };
  41.  
  42. template<int State, class ... MoveLists>
  43. struct FSM
  44. {
  45.     constexpr inline static int state = State;
  46.  
  47.     template<int Event>
  48.     using make_move = FSM<ValueSearcherT<State, MoveLists...>::template get_move<Event>::state, MoveLists...>;
  49.  
  50.     template<int First, int...Rest>
  51.     static typename make_move<First>::template apply_moves<Rest...> apply_moves_f();
  52.  
  53.     template<int First>
  54.     static make_move<First> apply_moves_f();
  55.  
  56.     template<int...Events>
  57.     using apply_moves = decltype(apply_moves_f<Events...>());
  58. };
  59.  
  60. enum States
  61. {
  62.     A, B, C
  63. };
  64.  
  65. enum Events
  66. {
  67.     a, b, c, d
  68. };
  69.  
  70. void print_state(int state)
  71. {
  72.     std::cout << char ('A' + state) << '\n';
  73. }
  74.  
  75. int main() {
  76.     using list_0 = MoveList<A, Move<a, B>, Move<c, B>, Move<d, C>>;
  77.     using list_1 = MoveList<B, Move<a, A>, Move<b, C>>;
  78.     using list_2 = MoveList<C>;
  79.     using fsm = FSM<0, list_0, list_1, list_2>;
  80.  
  81.     using result_fms = fsm::apply_moves<a, a, c, b>; // (A) --a--> (B) --a--> (A) --c--> (B) --b--> (C);
  82.     print_state(result_fms::state);
  83. }
  84.  
Add Comment
Please, Sign In to add comment