Tuple恐るべし

Ver-0.174 がリリースされた。

それに伴い、11/11 のコードで

	writefln(TA.length);
	writefln(typeid(TA));
	writefln(typeid(TA[0]));
	writefln(typeid(TA[1]));
	writefln(typeid(TA[2]));
...
3
TypeInfo
TypeInfo[0]
TypeInfo[1]
TypeInfo[2]

だったのが、

3
(int,double,char[3])
int
double
char[3]

と表示されるようになった。

今回の更新はすごい。

TypeTuple が超強力である。
これのおかげで過去に書いていた TypeArray が不要になった。
TypeTuple が TypeArray そのものである。

	alias TypeTuple!(int, double, char[]) Types3;
	writefln(typeid(Types3));
	writefln(Types3.length);
	writefln(typeid(Types3[0]));
	writefln(typeid(Types3[1]));
	writefln(typeid(Types3[2]));
...
(int,double,char[])
3
int
double
char[]

しかもこれ、ネストさせることによって連結もできる。

	alias TypeTuple!(int, double, char[]) IDS;
	alias TypeTuple!(short, float, creal) SFC;
	alias TypeTuple!(IDS, SFC) Many;
	writefln(typeid(Many));
	writefln(Many.length);
	writefln(typeid(Many[0]));
	writefln(typeid(Many[1]));
	writefln(typeid(Many[2]));
	writefln(typeid(Many[3]));
	writefln(typeid(Many[4]));
	writefln(typeid(Many[5]));
...
(int,double,char[],short,float,creal)
6
int
double
char[]
short
float
creal

おまけにスライシングさえ使える。

	writefln(typeid(Many[0..3]));
	writefln(typeid(Many[3..6]));
...
(int,double,char[])
(short,float,creal)

型汎用の functor はたったこれだけですんでしまう。

interface Functor(R, Args...) {
	alias R ReturnType;
	alias Args ArgsType;
	ReturnType opCall(ArgsType args);
}

これだけで、全ての functor の派生元を定義している。
引数の個数を1個または2個に限定している STL など目ではない。

std.typetuple には、TypeTuple に対するさまざまなユーティリティが定義されているが、Erase があるのに、EraseAt がない。
が、スライシング構文を使えばなんとかなった。

template EraseAt(int n, TList...) {
	alias TypeTuple!(TList[0..n], TList[n+1..length]) EraseAt;
}

	alias EraseAt!(2, Many) Few;
	writefln(typeid(Few));
...
(int,double,short,float,creal)

型タプルの表現力には目を見張るものがある。
DTL はかなりの部分が書き換えられるだろう。

bind1st でも bind2nd でもない bindNthも実装できそうである。

しかもまぁ、std.traits は追加されるは、クラスと構造体に tupleof プロパティが追加されるはで、汎用プログラミングパラダイスの状況である。(しかし、typename キーワードが欲しい……)