Advertisement
mihaild

imperative templates

Jul 2nd, 2014
300
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.28 KB | None | 0 0
  1. #pragma once
  2. #include <cstdlib>
  3.  
  4. template<typename... Args> struct List;
  5. template<typename H, typename... T> struct List<H, T...> {
  6.     typedef H Head;
  7.     typedef List<T...> Tail;
  8. };
  9. template<> struct List<> {
  10. };
  11.  
  12. template<typename N, typename... P> struct PushFront;
  13. template<typename N, typename... P> struct PushFront<N, List<P...>> {
  14.     typedef List<N, P...> type;
  15. };
  16.  
  17. template<typename Op, typename Next, typename Prog, typename Log> struct Calculation;
  18.  
  19. template<typename> struct Return;
  20. template<size_t> struct Label;
  21. template<typename> struct Goto;
  22. template<typename, typename> struct If;
  23.  
  24. template<size_t> struct _Var {};
  25. template<size_t> struct _Label;
  26. template<typename, typename> struct Assign;
  27. template<typename T, int v> struct _Assign {
  28.     typedef T type;
  29.     static const int value = v;
  30. };
  31.  
  32. template<typename, typename> struct Sum;
  33. template<typename, typename> struct Mod;
  34. template<typename, typename> struct Less;
  35. template<int N> struct Int {
  36.     const static int value = N;
  37. };
  38.  
  39. template<typename Var, typename Log> struct ValueOf {
  40.     const static int value = ValueOf<Var, typename Log::Tail>::value;
  41. };
  42. template<typename Var, int val, typename... Args> struct ValueOf<Var, List<_Assign<Var, val>, Args...>> {
  43.     const static int value = val;
  44. };
  45. template<typename Var> struct ValueOf<Var, List<>> {
  46.     const static int value = 0;
  47. };
  48.  
  49. template<typename Expression, typename Log> struct Eval;
  50. template<typename First, typename Second, typename Log> struct Eval<Sum<First, Second>, Log> {
  51.     const static int value = Eval<First, Log>::value + Eval<Second, Log>::value;
  52. };
  53. template<typename First, typename Second, typename Log> struct Eval<Mod<First, Second>, Log> {
  54.     const static int value = Eval<First, Log>::value % Eval<Second, Log>::value;
  55. };
  56. template<typename First, typename Second, typename Log> struct Eval<Less<First, Second>, Log> {
  57.     const static int value = Eval<First, Log>::value < Eval<Second, Log>::value;
  58. };
  59. template<int N, typename Log> struct Eval<Int<N>, Log> {
  60.     const static int value = N;
  61. };
  62. template<typename Var, typename Log> struct Eval {
  63.     const static int value = ValueOf<Var, Log>::value;
  64. };
  65.  
  66. template<typename Expression, typename Next, typename Prog, typename Log> struct Calculation<Return<Expression>, Next, Prog, Log> {
  67.     const static int value = Eval<Expression, Log>::value;
  68. };
  69. template<typename A, typename B, typename Next, typename Prog, typename Log> struct Calculation<Assign<A, B>, Next, Prog, Log> {
  70.     const static int value = Calculation<typename Next::Head, typename Next::Tail, Prog, typename PushFront<_Assign<A, Eval<B, Log>::value>, Log>::type>::value;
  71. };
  72. template<size_t N, typename Next, typename Prog, typename Log> struct Calculation<Label<N>, Next, Prog, Log> {
  73.     const static int value = Calculation<typename Next::Head, typename Next::Tail, Prog, Log>::value;
  74. };
  75. template<typename T, typename View, typename Prog, typename Log> struct CalculationGoto {
  76.     const static int value = CalculationGoto<T, typename View::Tail, Prog, Log>::value;
  77. };
  78. template<typename T, typename... ViewTail, typename Prog, typename Log> struct CalculationGoto<T, List<T, ViewTail...>, Prog, Log> {
  79.     const static int value = Calculation<typename List<ViewTail...>::Head, typename List<ViewTail...>::Tail, Prog, Log>::value;
  80. };
  81. template<typename T, typename Next, typename Prog, typename Log> struct Calculation<Goto<T>, Next, Prog, Log> {
  82.     const static int value = CalculationGoto<T, Prog, Prog, Log>::value;
  83. };
  84.  
  85. template<int val, typename Op, typename Next, typename Prog, typename Log> struct CalculationIf {
  86.     const static int value = Calculation<Op, Next, Prog, Log>::value;
  87. };
  88. template<typename Op, typename Next, typename Prog, typename Log> struct CalculationIf<0, Op, Next, Prog, Log> {
  89.     const static int value = Calculation<typename Next::Head, typename Next::Tail, Prog, Log>::value;
  90. };
  91. template<typename T1, typename T2, typename Next, typename Prog, typename Log> struct Calculation<If<T1, T2>, Next, Prog, Log> {
  92.     const static int value = CalculationIf<Eval<T1, Log>::value, T2, Next, Prog, Log>::value;
  93. };
  94.  
  95. template<typename... Args> struct Prog {
  96.     const static int value = Calculation<typename List<Args...>::Head, typename List<Args...>::Tail, List<Args...>, List<>>::value;
  97. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement