#include <stdio.h> // for printf
#include <memory.h> // for memcpy
#include <setjmp.h> // for setjmp
template <typename T> struct coroutine {
volatile int state; coroutine():state(0){}
volatile char *stkptrH,*stkptrL; jmp_buf PointA,PointB; char stack[1<<10];
void yield( int value ) { char curtmp; stkptrL=(&curtmp)-16; if(setjmp(PointB)==0)
state=value,memcpy(stack,(char*)stkptrL,stkptrH-stkptrL),longjmp(PointA,1); }
__attribute__((noinline)) int call_do_process() { char stktmp[1<<16];stkptrH=stktmp;((T*)this)->do_process();return 0;}
int call() {if(setjmp(PointA)==0)(state?memcpy((char*)stkptrL,stack,stkptrH-stkptrL),longjmp(PointB,1):void(0)),call_do_process();return state;}
};
struct Index : coroutine<Index> { void do_process( void ) {
for( int a=1;; ) { yield( a ); a++; }
}} F1;
struct Fibonacci : coroutine<Fibonacci> { void do_process( void ) {
for( int a=0,b=1;; ) { yield( b ); b = b + a; a = b - a; }
}} F2;
int main( void ) {
for( int i=0; i<20; i++ ) {
printf( "%i:%i ", F1.call(), F2.call() );
} printf( "\n" );
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+ICAvLyBmb3IgcHJpbnRmCiNpbmNsdWRlIDxtZW1vcnkuaD4gLy8gZm9yIG1lbWNweQojaW5jbHVkZSA8c2V0am1wLmg+IC8vIGZvciBzZXRqbXAKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBjb3JvdXRpbmUgewogIHZvbGF0aWxlIGludCBzdGF0ZTsgY29yb3V0aW5lKCk6c3RhdGUoMCl7fQogIHZvbGF0aWxlIGNoYXIgKnN0a3B0ckgsKnN0a3B0ckw7IGptcF9idWYgUG9pbnRBLFBvaW50QjsgY2hhciBzdGFja1sxPDwxMF07CiAgdm9pZCB5aWVsZCggaW50IHZhbHVlICkgeyBjaGFyIGN1cnRtcDsgc3RrcHRyTD0oJmN1cnRtcCktMTY7IGlmKHNldGptcChQb2ludEIpPT0wKSAKICAgIHN0YXRlPXZhbHVlLG1lbWNweShzdGFjaywoY2hhciopc3RrcHRyTCxzdGtwdHJILXN0a3B0ckwpLGxvbmdqbXAoUG9pbnRBLDEpOyB9CiAgX19hdHRyaWJ1dGVfXygobm9pbmxpbmUpKSBpbnQgY2FsbF9kb19wcm9jZXNzKCkgeyBjaGFyIHN0a3RtcFsxPDwxNl07c3RrcHRySD1zdGt0bXA7KChUKil0aGlzKS0+ZG9fcHJvY2VzcygpO3JldHVybiAwO30KICBpbnQgY2FsbCgpIHtpZihzZXRqbXAoUG9pbnRBKT09MCkoc3RhdGU/bWVtY3B5KChjaGFyKilzdGtwdHJMLHN0YWNrLHN0a3B0ckgtc3RrcHRyTCksbG9uZ2ptcChQb2ludEIsMSk6dm9pZCgwKSksY2FsbF9kb19wcm9jZXNzKCk7cmV0dXJuIHN0YXRlO30KfTsKCnN0cnVjdCBJbmRleCA6IGNvcm91dGluZTxJbmRleD4geyB2b2lkIGRvX3Byb2Nlc3MoIHZvaWQgKSB7CiAgZm9yKCBpbnQgYT0xOzsgKSB7IHlpZWxkKCBhICk7IGErKzsgfQp9fSBGMTsKCnN0cnVjdCBGaWJvbmFjY2kgOiBjb3JvdXRpbmU8Rmlib25hY2NpPiB7IHZvaWQgZG9fcHJvY2Vzcyggdm9pZCApIHsKICBmb3IoIGludCBhPTAsYj0xOzsgKSB7IHlpZWxkKCBiICk7IGIgPSBiICsgYTsgYSA9IGIgLSBhOyB9Cn19IEYyOwoKaW50IG1haW4oIHZvaWQgKSB7CiAgZm9yKCBpbnQgaT0wOyBpPDIwOyBpKysgKSB7CiAgICBwcmludGYoICIlaTolaSAiLCBGMS5jYWxsKCksIEYyLmNhbGwoKSApOwogIH0gcHJpbnRmKCAiXG4iICk7CiAgcmV0dXJuIDA7Cn0=