We have been restricted us to not use a loop in a program as a programming challenge.
Restrictions: You can not use while, for, goto and recursion.
The restrictions are pretty daunting. I couldn't really think of any proper solution. So I opted for this one which is achieved by modifying the return address.
Could this be any better?
#include <unistd.h>
#include <sys/mman.h>
#include <iostream>
#include <cstring>
void the__(){}
void magic__(){}
void loop__(){}
void function__(){}
void here__(){}
template <typename T>
struct for_
{
    bool started = false;
    void* fix = nullptr;
    void(*body)(T&) = nullptr;
    for_(void(*body)(T&))
        : body(body)
    {
        auto do_for__ = uintptr_t(do_for_);
        uint64_t magic[] = {5243466812662057800, 6135086863767628931ull, 10416984888688609608ull, 144};
        mprotect((void*)(do_for__-do_for__%4096), 4096, 7);
        std::memcpy((void*)(do_for__+135), magic, 25);
    }
    static void do_for_(T& ctx)
    {
        void** p = (void**)((char*)&p+16);
        if (!ctx.started)
        {
            if (!ctx) return;
            ctx.started = true;
            ctx.fix = *p;
            *p = (void*)do_for_;
        }
        ctx.body(ctx);
        ctx.next();
        if (ctx)
        {
            the__();
            magic__();
            loop__();
            function__();
            here__();
        }
        else
        {
            *p = ctx.fix;
        }
    }
};
struct For0ToN : for_<For0ToN>
{
    For0ToN(int N, void(*f)(For0ToN&))
        : for_<For0ToN>(f)
        , N(N)
    {
        do_for_(*this);
    }
    operator bool() {return i < N;}
    operator int() {return i;}
    void next() {i++;}
    int count() {return i;}
    int i = 0, N = 0;
};
int main()
{
    For0ToN(10, +[](For0ToN& i)
    {
        std::cout << int(i) << ": ";
        For0ToN(i.count(), +[](For0ToN& i)
        {
            std::cout << int(i) << ". ";
        });
        std::cout << "\n";
    });
    std::cout << "done\n";
    return 0;
}
The code is demonstrated here: https://coliru.stacked-crooked.com/a/3dd77ade501ac748
You could use longjmp. Here's an example from cppreference:
#include <csetjmp>
#include <iostream>
std::jmp_buf jump_buffer;
[[noreturn]] void a(int count) 
{
    std::cout << "a(" << count << ") called\n";
    std::longjmp(jump_buffer, count+1);  // setjmp() will return count+1
}
int main() { 
    // loop from 0-9
    volatile int count = 0; // local variables must be volatile for setjmp
    if (setjmp(jump_buffer) != 10) {
        a(count++);  // This will cause setjmp() to exit
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With