#include <iostream>

namespace live_without_statements
{

    template <typename Action> void exec(Action action)
    {
        action();
    }

    template <typename Action> void skip(Action action) {
        (void)action;
    }

    template <typename Then>
    void if_op(bool cond, Then thenAction)
    {
        void (*fns[])(Then) = {&skip, &exec};
        fns[cond](thenAction);
    }

    template <typename Then, typename Else>
    void if_op(bool cond, Then t, Else e)
    {
        if_op(cond, t);
        if_op(!cond, e);
    }

    template <typename Cond, typename Body, size_t level>
    struct looper
    {
        static bool loop(Cond cond, Body body)
        {
            bool c = looper<Cond, Body, level-1>::loop(cond, body);
            if_op(c, [&c, &cond, &body](){c = looper<Cond, Body, level-1>::loop(cond, body);});
            return c;
        }
    };

    template <typename Cond, typename Body>
    struct looper<Cond, Body, 0>
    {
        static bool loop(Cond cond, Body body)
        {
            bool c = cond();
            if_op(c, body);
            return c;
        }
    };

    // don't worry, thermal death of the universe will happen earlier...
    const int level_limit = 128; 

    template <typename Cond, typename Body>
    void while_op(Cond cond, Body body)
    {
        looper<Cond, Body, level_limit>::loop(cond, body);
    }
}

int main()
{
    using namespace live_without_statements;

    int a[] {1, 7, 3, 2, 8, 4, 2, 5, 9, 0};

    size_t len = sizeof(a) / sizeof(a[0]);

    size_t i = 0;
    while_op([&](){return i < len - 1;}, [&](){
        size_t j = 0;
        while_op([&](){return j < len - i - 1;}, [&](){
            if_op(a[j] > a[j+1], [&](){std::swap(a[j], a[j+1]);});
            ++j;
        });
        ++i;
    });

    i = 0;
    while_op([&](){return i < 10;}, [&](){
        std::cout << "a[" << i << "] = " << a[i] << std::endl;
        ++i;
    });

    return 0;
}