■
可変引数続き。
http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/4557
ナゼこれはTemplateで実装しているんだろうか。
import std.stdarg; class Arguments { private: TypeInfo typeinfos; void* pointers; int len; public: this(TypeInfo[] inf, void* argptr) { typeinfos = inf; pointers.length = inf.length; len = inf.length; pointers[0] = argptr; for (int i = 1; i < len; i++) { pointers[i] = pointers[i-1] + inf[i-1].tsize; } } int length() { return len; } TypeInfo type(int i) { return typeinfos[i]; } void* value(int i) { return pointers[i]; } /// foreachに対応させるためのもの int opApply(int delegate(inout TypeInfo, inout void*) dg) { int result = 0; for (int i = 0; i < len; i++) { result = dg(typeinfos[i], pointers[i]); if (result) break; } return result; } int opApply(int delegate(inout int, inout TypeInfo, inout void*) dg) { int result = 0; for (int i = 0; i < len; i++) { result = dg(i, typeinfos[i], pointers[i]); if (result) break; } return result; } } void test(...) { Arguments arg = new Arguments(_arguments, _argptr); printf("length: %d\n",arg.length); for (int i = 0; i < arg.length; i++) { if (arg.type(i) == typeid(int)) { printf("%d: %d\n", i, *cast(int*)arg.value(i)); } } foreach (TypeInfo ti, void* value; arg) { if (ti == typeid(int)) { printf("%d\n", *cast(int*)value); } } foreach (int i, TypeInfo ti, void* value; arg) { if (ti == typeid(int)) { printf("%d: %d\n", i, va_arg!(int)(value)); } } } void main() { test(1, 2, 4, 5); }
Y4Dからパクった onApply 付き。だが for より長くなる罠。意味無い。foreach を使えるところは、for より foreach を使ってD言語っぽさを出したい人用。俺とか。
キャストは std.stdarg を import して、 var_arg!(型)(argptr) とするのがD言語流。タブン。
追記:
var_arg は inout で argptr を書き換えているので、こんな使い方が出来るらしい。ただ、_arguments があるんだから、引数の数はいらないんじゃないかと思った。それと int 以外を渡されると破綻するので
import std.stdarg; void printint(...) { printf("arguments : %d\n", _arguments.length); foreach (int i, TypeInfo ti; _arguments) { if (ti == typeid(int)) { /* int型としてtemplate va_argをインスタンス化し、 同名の関数va_argの引数に_argptrを指定して呼び出す */ int value = va_arg!(int)(_argptr); printf(" %d : %d\n", i + 1, value); } else { _argptr += ti.tsize; } } } int main() { printint(0,1,2,3); printint(100); return 0; }
とか。