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 キーワードが欲しい……)