Boost.bind の D 版を作ってみました。めんどいだけであまり実装とか面白くもなかったというか、メソッドテンプレートが無いので opCall(...) を実行時に解決するというダサい解になっています。一応型チェックはそれなりにしてあるはず。
http://shinh.skr.jp/d/bind.tgz
ユニットテスト節から適当に使用例を引用。
int func(int i, int j) { return i*2 + j; } auto f = bind(&func, _1, _2); static assert(is(f.calltype == Tuple!(int, int))); assert(f(1, 2) == 4); auto f2 = bind(&func, _2, _1); static assert(is(f2.calltype == Tuple!(int, int))); assert(f2(1, 2) == 5); auto f3 = bind(&func, _1, _1); static assert(is(f3.calltype == Tuple!(int))); assert(f3(1) == 3); char func2(int i, char[] msg) { return msg[i]; } auto f4 = bind(&func2, _2, _1); static assert(is(f4.calltype == Tuple!(char[], int))); assert(f4("abc", 1) == 'b'); char[] abcdef = "abcdef"; auto f5 = bind(&func2, _1, abcdef); static assert(is(f5.calltype == Tuple!(int))); assert(f5(1) == 'b'); auto f6 = bind(&func2, 1, _1); static assert(is(f6.calltype == Tuple!(char[]))); assert(f6("abcd") == 'b'); char[] func3(int i, int j, char[] msg) { return msg[i..j]; } auto f7 = bind(&func3, _2, _1, abcdef); static assert(is(f7.calltype == Tuple!(int, int))); assert(f7(2, 1) == "b"); void func_types(int i, float f, char c, bool b, char[] s) { assert(i == 1); assert(f == 2.0); assert(c == 'a'); assert(b); assert(s == "hoge"); } char[] hoge = "hoge"; auto ft0 = bind(&func_types, 1, 2.0, _1, true, hoge); static assert(is(ft0.calltype == Tuple!(char))); ft0('a'); /* auto ft1 = bind(&func_types, _4, _3, _2, true, _1); static assert(is(ft1.calltype == Tuple!(char[], char, float, int))); ft1("hoge", 'a', 2.0, 1); auto ft2 = bind(&func_types, _2, _3, 'a', true, _1); static assert(is(ft2.calltype == Tuple!(char[], int, float))); ft2("hoge", 1, 2.0); */ version(Windows) { auto ft3 = bind(&func_types, _1, 2.0, 'a', true, _2); static assert(is(ft3.calltype == Tuple!(int, char[]))); ft3(1, "hoge"); }
コメントアウトしてある部分はなぜか assert で落ちるのでコメントアウトしました。 Linux だとコンパイラが落ちるのでコンパイラのバグかなーと思いますがよくわかりません。同じく version(Windows) 内も Linux ではコンパイラが落ちます。
あとシンボルの長さが1000文字程度で怒られるようなので、 30引数まで対応してあるものの、実際のところは 10引数程度が限度かもしれません。
あと opCall(...) なので bind を bind できないという問題もあります。まぁ色々やる気が失せてきたのでこんなもんで。
あと Linux でリンク時に謎 warning が出るのもよくわからない。
そういえば実装しようと思ったのは
http://d.hatena.ne.jp/niha/20060612#1150120289
の curry とか見て、なのですが、なんというか関数型言語の flip って気持ち悪くないですか、という話が。