しるふぃずむ

どうもプログラマです。好きなものはC#とジンギスカンです。嫌いなものはJava。プログラムおもちろいね。

Boost.Coroutine

色々終わったので1.53.0で追加されたライブラリをいじってみる。
とりあえずCoroutineから。Pythonなんかのyield文のようなものが簡単に作れる、と理解しました。
サンプルコピペで動作確認からやってみます。

  • lboost_contextを付け忘れてしばらく悩みました。

依存しているBoost.Contextのリンクが必要ということで。

#include <iostream>

#include <boost/coroutine/all.hpp>
#include <boost/bind.hpp>

typedef boost::coroutines::coroutine< void() > coro_t;

// void fn( boost::coroutines::coroutine< void() > & ca, int j)
void fn( coro_t::caller_type & ca, int j)
{
    for( int i = 0; i < j; ++i)
    {
        std::cout << "fn(): local variable i == " << i << std::endl;

        // save current coroutine
        // value of local variable is preserved
        // transfer execution control back to main()
        ca();

        // coroutine<>::operator()() was called
        // execution control transferred back from main()
    }
}

int main( int argc, char * argv[])
{
    // bind parameter '7' to coroutine-fn
    coro_t c( boost::bind( fn, _1, 7) );

    std::cout << "main() starts coroutine c" << std::endl;

    while ( c)
    {
        std::cout << "main() calls coroutine c" << std::endl;
        // execution control is transferred to c
        c();
    }

    std::cout << "Done" << std::endl;

    // return EXIT_SUCCESS;
    return 0;
}

output(clang3.3)

Segmentation fault (コアダンプ)

…あれ。
gccで同じソースをコンパイルしなおし。
concept_check周りでものすごい警告(-Wunused-local-typedefs)。
output(gcc4.8)

fn(): local variable i == 0
main() starts coroutine c
main() calls coroutine c
fn(): local variable i == 1
main() calls coroutine c
fn(): local variable i == 2
main() calls coroutine c
fn(): local variable i == 3
main() calls coroutine c
fn(): local variable i == 4
main() calls coroutine c
fn(): local variable i == 5
main() calls coroutine c
fn(): local variable i == 6
main() calls coroutine c
Done

どうやら正常に動いた様子。
うーん。

できればclangで色々試したいですね。
trunk入れなおしたりしてみましょうか。