#include <iostream>

using namespace std;

//inheritance
template <typename T>
struct BASE{
    void EXEC () 
    {
        static_cast<T*>(this)->EXEC();
    }
};

struct NODE : BASE<NODE>{
    static inline void EXEC()
    {
        cout << "osti\n";
    }
};

//loop
template <int _N>
struct LOOP{
    static inline void EXEC ()
    {
        cout << "colisse\n";
        LOOP<_N-1>::EXEC();
    }
};

template <>
struct LOOP<0>{
    static inline void EXEC ()
    {
        cout << "barnak\n";
    }
};

//switch
template <int _CASE>
struct SWITCH{
    static inline void EXEC ()
    {
        cout << "default\n";
    }
};

template <>
struct SWITCH<1>{
    static inline void EXEC ()
    {
        cout << "un\n";
    }
};

template <>
struct SWITCH<2>{
    static inline void EXEC ()
    {
        cout << "deux\n";
    }
};

//if
//template <bool _CONDITION>
//struct IF{
//    static inline void EXEC ()
//    {
//        cout << "true\n";
//    }
//};

//template <>
//struct IF<false>{
//    static inline void EXEC ()
//    {
//        cout << "false\n";
//    }
//};


template< bool _COND, typename _THEN, typename _ELSE > 
struct IF
{
    //typedef _THEN RETURN;
    static inline void EXEC(){
        _THEN::EXEC();
    }
};

template<typename _THEN, typename _ELSE>
struct IF<false, _THEN, _ELSE>{
    //typedef _ELSE RETURN;
    static inline void EXEC(){
        _ELSE::EXEC();
    }
};

struct THEN
{
    static inline void EXEC() 
    {
        cout << "THEN\n";
    }
};

struct ELSE
{
    static inline void EXEC() 
    {
        cout << "ELSE\n";
    }
};

//list
struct NIL{
};

template <char C, typename _BACK>
struct P{
    static inline void EXEC() 
    {
        cout << C << " \n";
        _BACK::EXEC();
    }
};

template <char C>
struct P<C, NIL>{
    static inline void EXEC() 
    {
        cout << C << "\n";
    }
};

//stack

template <char C, typename BACK>
struct PUSH{
    static const int N = BACK::N;
    static inline void EXEC(const int n=0) 
    {
        if (n != N)
            BACK::EXEC(n-1);
        else
            cout << C << "\n";
    }
};

template <char C>
struct PUSH<C,NIL>{
    static const int N = 0;
    static inline void EXEC(const int n=0) 
    {
        cout << C << "\n";
    }
};

template <typename BACK>
struct POP{
    static const int N = BACK::N+1;
    static inline void EXEC(const int n=0) 
    {
        if (n)
            BACK::EXEC(n);
        else
            BACK::EXEC(N);
    }
};

//test

const int num = 5+2;

int main()
{
//    NODE test;
//    test.EXEC();

//    LOOP<5> test5;
//    test5.EXEC();

//    SWITCH<2>test2;
//    test2.EXEC();

//    //IF<true,THEN, ELSE>::RETURN::EXEC();
//    IF<false, THEN, ELSE>::EXEC();

//    typedef P<'a',NIL> a;
//    typedef P<'b',a> b;
//    typedef P<'c',b> c;
//    c::EXEC();

    typedef PUSH<'a',NIL> un;
    un::EXEC();
    typedef PUSH<'b',un> deux;
    deux::EXEC();
    typedef PUSH<'c',deux> trois;
    trois::EXEC();
    typedef POP<trois> quatre;
    quatre::EXEC();
    typedef POP<quatre> cinq;
    cinq::EXEC();
    typedef POP<cinq> six;
    six::EXEC();

    return 0;
}
