コルーチンのお話
以前、こんなネタを書いていました
C++でコルーチンを使う、というものです
http://blogs.wankuma.com/izmktr/archive/2010/04/28/188507.aspx
わんくまはよく落ちるので、上の記事にあるソースを転載しておきます
#include "coroutine.h" class Test:public Coroutine{ int i; public: bool Foo(){ CoroutineBegin(); for (i = 1; i <= 20; i++){ printf("%d ", i); yield; if ((i % 3) == 0){ printf("fizz "); yield; } if ((i % 5) == 0){ printf("buzz "); yield; } } CoroutineEnd(); return true; } }; int _tmain(int argc, _TCHAR* argv[]) { Test test; for (;;){ bool finish = test.Foo(); if (finish) break; printf("---\n"); } return 0; }
これを動かすと、test.Foo()ってのが、あたかもコルーチンっぽく動くのです
うまく隠蔽しているので一見すごい!と思ってしまうのですが、
その隠蔽していたヘッダファイルが以下になります
#ifndef CoroutineHeader #define CoroutineHeader class Coroutine{ protected: int state; public: Coroutine():state(0){} virtual ~Coroutine(){} }; #define CoroutineBegin() switch(state){case 0: #define CoroutineEnd() default: break;} #define yield {state = __LINE__; return false; case __LINE__:;} #endif
関数に見えたCoroutineBegin(), CoroutineEnd()はマクロで、
中身はただのswitch文です
つまり、returnする直前にreturnの次の行のジャンプポイントをstateに保存しておき、
次回関数が呼ばれた時にswitch文でreturnの次の行にジャンプするわけです
書いた当時は「ちょwwおまwww」というコメントを期待してたのですが無反応だし、
更にネタを投下したのにやっぱり無反応で寂しい思いをしてたのですが、
まさか、1年以上経って真面目に欲しいということで復刻するとは思いませんでしたね…