型コンテナ(ナサケナVersion)

Loki の Typelist をD言語にポートし、可変個型引数を実装できないかな〜と思った。
だがやってみると難しく、Length と TypeAt すら実装できずに挫折した。
(誰かやった人はいないのかしら?)


で、代わりに作ったのが以下のような羅列型のテンプレート。

module doki.typearray;

class NullType {}

template TypeArray (
    T0,
    T1 = NullType,
    T2 = NullType,
    T3 = NullType,
    T4 = NullType,
    T5 = NullType,
    T6 = NullType,
    T7 = NullType,
    T8 = NullType,
    T9 = NullType
) {
    class TypeArray {
        const length = (
            !is (T9 == NullType) ? 10 :
            !is (T8 == NullType) ? 9 :
            !is (T7 == NullType) ? 8 :
            !is (T6 == NullType) ? 7 :
            !is (T5 == NullType) ? 6 :
            !is (T4 == NullType) ? 5 :
            !is (T3 == NullType) ? 4 :
            !is (T2 == NullType) ? 3 :
            !is (T1 == NullType) ? 2 :
            1
        );
        template typeAt(int n    ) {                  }
        template typeAt(int n : 0) { alias T0 typeAt; }
        template typeAt(int n : 1) { alias T1 typeAt; }
        template typeAt(int n : 2) { alias T2 typeAt; }
        template typeAt(int n : 3) { alias T3 typeAt; }
        template typeAt(int n : 4) { alias T4 typeAt; }
        template typeAt(int n : 5) { alias T5 typeAt; }
        template typeAt(int n : 6) { alias T6 typeAt; }
        template typeAt(int n : 7) { alias T7 typeAt; }
        template typeAt(int n : 8) { alias T8 typeAt; }
        template typeAt(int n : 9) { alias T9 typeAt; }
    }
}

汎用プログラミングは再起を使うのが一般的なんですけどね〜。
まぁ、動かしてみよう。

debug(typearray) {
    import std.stdio;

    void main() {
        alias TypeArray!(int, char, double) Types3;
        writefln(typeid(Types3));
        writefln(Types3.length);
        writefln(typeid(Types3.typeAt!(0)));
        writefln(typeid(Types3.typeAt!(1)));
        writefln(typeid(Types3.typeAt!(2)));
    //  writefln(typeid(Types3.typeAt!(3)));
    //  writefln(typeid(Types3.typeAt!(9)));
    }
}
...
C:\d\doki>dmd -debug=typearray -run typearray
TypeArray
3
int
char
double

ンマー、動いてますな。
でもこれで例えば可変個型引数の汎用ファンクタを実装しようとしてもできないんだな〜。