Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <cstdlib>
- template<typename... Args> struct List;
- template<typename H, typename... T> struct List<H, T...> {
- typedef H Head;
- typedef List<T...> Tail;
- };
- template<> struct List<> {
- };
- template<typename N, typename... P> struct PushFront;
- template<typename N, typename... P> struct PushFront<N, List<P...>> {
- typedef List<N, P...> type;
- };
- template<typename Op, typename Next, typename Prog, typename Log> struct Calculation;
- template<typename> struct Return;
- template<size_t> struct Label;
- template<typename> struct Goto;
- template<typename, typename> struct If;
- template<size_t> struct _Var {};
- template<size_t> struct _Label;
- template<typename, typename> struct Assign;
- template<typename T, int v> struct _Assign {
- typedef T type;
- static const int value = v;
- };
- template<typename, typename> struct Sum;
- template<typename, typename> struct Mod;
- template<typename, typename> struct Less;
- template<int N> struct Int {
- const static int value = N;
- };
- template<typename Var, typename Log> struct ValueOf {
- const static int value = ValueOf<Var, typename Log::Tail>::value;
- };
- template<typename Var, int val, typename... Args> struct ValueOf<Var, List<_Assign<Var, val>, Args...>> {
- const static int value = val;
- };
- template<typename Var> struct ValueOf<Var, List<>> {
- const static int value = 0;
- };
- template<typename Expression, typename Log> struct Eval;
- template<typename First, typename Second, typename Log> struct Eval<Sum<First, Second>, Log> {
- const static int value = Eval<First, Log>::value + Eval<Second, Log>::value;
- };
- template<typename First, typename Second, typename Log> struct Eval<Mod<First, Second>, Log> {
- const static int value = Eval<First, Log>::value % Eval<Second, Log>::value;
- };
- template<typename First, typename Second, typename Log> struct Eval<Less<First, Second>, Log> {
- const static int value = Eval<First, Log>::value < Eval<Second, Log>::value;
- };
- template<int N, typename Log> struct Eval<Int<N>, Log> {
- const static int value = N;
- };
- template<typename Var, typename Log> struct Eval {
- const static int value = ValueOf<Var, Log>::value;
- };
- template<typename Expression, typename Next, typename Prog, typename Log> struct Calculation<Return<Expression>, Next, Prog, Log> {
- const static int value = Eval<Expression, Log>::value;
- };
- template<typename A, typename B, typename Next, typename Prog, typename Log> struct Calculation<Assign<A, B>, Next, Prog, Log> {
- const static int value = Calculation<typename Next::Head, typename Next::Tail, Prog, typename PushFront<_Assign<A, Eval<B, Log>::value>, Log>::type>::value;
- };
- template<size_t N, typename Next, typename Prog, typename Log> struct Calculation<Label<N>, Next, Prog, Log> {
- const static int value = Calculation<typename Next::Head, typename Next::Tail, Prog, Log>::value;
- };
- template<typename T, typename View, typename Prog, typename Log> struct CalculationGoto {
- const static int value = CalculationGoto<T, typename View::Tail, Prog, Log>::value;
- };
- template<typename T, typename... ViewTail, typename Prog, typename Log> struct CalculationGoto<T, List<T, ViewTail...>, Prog, Log> {
- const static int value = Calculation<typename List<ViewTail...>::Head, typename List<ViewTail...>::Tail, Prog, Log>::value;
- };
- template<typename T, typename Next, typename Prog, typename Log> struct Calculation<Goto<T>, Next, Prog, Log> {
- const static int value = CalculationGoto<T, Prog, Prog, Log>::value;
- };
- template<int val, typename Op, typename Next, typename Prog, typename Log> struct CalculationIf {
- const static int value = Calculation<Op, Next, Prog, Log>::value;
- };
- template<typename Op, typename Next, typename Prog, typename Log> struct CalculationIf<0, Op, Next, Prog, Log> {
- const static int value = Calculation<typename Next::Head, typename Next::Tail, Prog, Log>::value;
- };
- template<typename T1, typename T2, typename Next, typename Prog, typename Log> struct Calculation<If<T1, T2>, Next, Prog, Log> {
- const static int value = CalculationIf<Eval<T1, Log>::value, T2, Next, Prog, Log>::value;
- };
- template<typename... Args> struct Prog {
- const static int value = Calculation<typename List<Args...>::Head, typename List<Args...>::Tail, List<Args...>, List<>>::value;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement