|
|
||
| << | 2006/05 | >> | ||||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 | |||
| サイト本体 | 昔の更新履歴兼雑記 | タイトル一覧 |
分類は アーカイブ任せにした方がいいのかも。
gdc の ABI が違ったのでその対応とか入れてみました。 Linux の DMD-0.159 と gdc-0.18 、 WINE の DMD-0.159 で確認。
import std.stdio;
template mem_fun(T) {
T (*mem_fun(T (*f)()))(Object) {
return cast(T (*)(Object))f;
}
}
version (GNU) {
template mem_fun(T, U) {
T (*mem_fun(T (*f)(U)))(Object, U) {
return cast(T (*)(Object, U))f;
}
}
} else {
class mem_fun_t(T, U) {
T (*fp)(U, Object);
this(T (*f)(U, Object)) {
fp = f;
}
T opCall(Object o, U u) {
return fp(u, o);
}
}
template mem_fun(T, U) {
mem_fun_t!(T, U) mem_fun(T (*f)(U)) {
return new mem_fun_t!(T, U)(cast(T (*)(U, Object))f);
}
}
}
class C {
int val_;
this(int val) { val_ = val; }
int func() {
return val_;
}
int func2(int x) {
return val_+x;
}
}
int main() {
auto mf = mem_fun(&C.func);
auto mf2 = mem_fun(&C.func2);
C c1 = new C(1);
C c2 = new C(2);
writefln(mf(c1)); // 1
writefln(mf(c2)); // 2
writefln(mf2(c1, 3)); // 4
writefln(mf2(c2, 4)); // 6
return 0;
}
何してるかって要はキャストしてるだけなのでインチキ。関数なんて呼べりゃいいんです。
0引数mem_funは本当にキャストしてるだけです。関数ポインタ取って関数ポインタ返す関数なのでシグネチャがややこしいですが。
1引数mem_funは引数順をmem_fun_tでひっくり返してます。thisはレジスタ渡しなので普通の関数の最終引数と同じ扱いぽいです。 gdc の場合はひっくり返す必要無し。
http://www.dsource.org/projects/bcd
via http://pc8.2ch.net/test/read.cgi/tech/1146656260/160
tccparser でやろうかと思ってたことがやられてました。マクロとかは動かんのかなと思うんですが、 GCCXML の方が DWARF2 よりはベターですかね。
T function (Object o) mem_fun(T function() f) {
return cast(T function(Object o))f;
}
}
と function に置き換えてシグねーちゃんを理解しました。
しかし、引数なしの関数を引数1個の関数に cast するとは思いつかないですねぇ。コンパイル通るか不安な以前に浮かばない。さすがですねぇ。