What about this?
No magic, but I don't know the performance impact.

```
import std.meta;
import std.conv;

template same(Types...)
{
    static if (Types.length >= 2)
    {
        static if (is(Types[0] == Types[$ - 1]))
        {
            const same = same!(Types[1 .. $]);
        }
        else
        {
            enum bool same = false;
        }
    }
    else
    {
        enum bool same = true;
    }
}

struct Tuple(Types...)
{

    static if (same!Types)
    {
        public Types[0][Types.length] elements;
        public this(Types[0][Types.length] elements...)
        {
            this.elements = elements;
        }
    }

    else
    {
        static foreach (int i, T; Types)
        {
mixin("public " ~ T.stringof ~ " " ~ "elem" ~ i.stringof ~ ";");
        }
        public this(Types elements)
        {
            static foreach (int i, T; Types)
            {
mixin("this.elem" ~ i.stringof ~ "=" ~ "elements[i]" ~ ";");
            }
        }
    }
}

int main()
{
    import std.stdio;

    auto homogenousTuple = Tuple!(int, int)(2, 3);
    writeln("homogenous tuple ", homogenousTuple.elements[0], ":",
typeid(homogenousTuple.elements[0]), ":", homogenousTuple.elements[1],
            ":", typeid(homogenousTuple.elements[1]));
    auto heterogenousTuple = Tuple!(int, float)(2, 3);
writeln("heterogenous tuple ", heterogenousTuple.elem0, ":", typeid(heterogenousTuple.elem0), ":", heterogenousTuple.elem1, ":", typeid(heterogenousTuple.elem1));
    return 0;
}
```

Problem is, the type arguments getn't inferred.

Reply via email to