On 05/31/2017 08:50 PM, jmh530 wrote:
Note: I left out the function foo, but think of foo is to Foo as tuple is to Tuple.

You should have included foo, in my opinion. I'm having trouble figuring out what your code does. `process` instantiates foo with the field names. I'd need the definition of foo to make sense of that.

A usage example of the whole thing would also help.

import std.typecons : Tuple;

struct Foo(T...)
{
     alias U = Tuple!T;
     U underlying;
     alias underlying this;

     alias Names = U.fieldNames;
     alias Types = U.Types;

     template process(B...)
     {
         auto ref process(A...)(A a)
         {
             alias fooB = foo!(B);

             static if (A.length == 1)
             {
                 return fooB(this.underlying[0][a[0]]);
             }
             else static if (A.length == 2)
             {
                 return fooB(this.underlying[0][a[0]],
                         this.underlying[1][a[1]]);
             }
             else static if (A.length == 3)
             {
                 return fooB(this.underlying[0][a[0]],
                         this.underlying[1][a[1]],
                         this.underlying[2][a[2]]);
             }
         }
     }

     auto ref opIndex(Slices...)(Slices slices)
         if (Slices.length == Types.length)
     {
         return process!(Names)(slices);
     }
}

I've pieced something together, but I'm not sure if it's what you're looking for. Note that I've changed how foo is instantiated, because it isn't obvious to me how your version works.

----
import std.typecons : Tuple;

struct Foo(T...)
{
    alias U = Tuple!T;
    U underlying;
    alias underlying this;

    alias Names = U.fieldNames;
    alias Types = U.Types;

    auto ref opIndex(Slices...)(Slices slices)
        if (Slices.length == Types.length)
    {
        import std.meta: staticMap;
        alias ElementType(A : E[], E) = E;
        alias R = staticMap!(ElementType, Types);
        R result;
        foreach (i, Ignored; Slices)
        {
            result[i] = this.underlying[i][slices[i]];
        }
        return foo(result);
    }
}

Foo!T foo(T ...)(T stuff) { return Foo!T(Tuple!T(stuff)); }

void main()
{
    auto f = foo([1, 2, 3], [4, 5, 6]);
    auto e = f[1, 2];
    assert(e == foo(2, 6));
}
----

Reply via email to