Changing Template Static Ifs to Recursion

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed May 31 12:25:22 PDT 2017


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));
}
----


More information about the Digitalmars-d-learn mailing list