Boost.Contextでambを実装してみた

継続について勉強中。
非決定性計算に使われるambオペレータをBoost.Contextで実装してみました。
AMB_BLOCKの中で生成したamberのオブジェクトは、それらの組み合わせを扱うことができます。

#include <iostream>
#include "amb.hpp"

void amb1_f(amber& cont)
{
    cont.suspend(1);
    cont.suspend(2);
    cont.suspend_break(3);
}

void amb2_f(amber& cont)
{
    cont.suspend(4);
    cont.suspend_break(5);
}

void amb3_f(amber& cont)
{
    cont.suspend(6);
    cont.suspend(7);
    cont.suspend_break(8);
}

int main()
{
    AMB_BLOCK(ctx) {
        amber& x = amb(ctx, 0, amb1_f);
        amber& y = amb(ctx, 1, amb2_f);
        amber& z = amb(ctx, 2, amb3_f);

        std::cout << x.get() << ", " << y.get() << ", " << z.get() << std::endl;
    };
}
1, 4, 6
1, 4, 7
1, 4, 8
1, 5, 6
1, 5, 7
1, 5, 8
2, 4, 6
2, 4, 7
2, 4, 8
2, 5, 6
2, 5, 7
2, 5, 8
3, 4, 6
3, 4, 7
3, 4, 8
3, 5, 6
3, 5, 7
3, 5, 8

ambの実装は、私のGitHubに置いてあります:
amb.hpp - Keizoku


AMB_BLOCKは参照キャプチャのラムダ式なので、いちおう外部の変数に結果を返すことはできます。ただし、ラムダ式なのでbreakはできません。気持ち悪いかもしれませんが、breakしたい場合はreturnしてください。
それと、amb関数の第2引数が邪魔なのでそのうち消したいところです…。今のところ上から順番に連番を指定する必要があります。


参照:
天使のオペレータ amb
shfit/resetによるambのミニマム実装