How to expand an expression along with a parameter tuple?

Artur Skawina art.08.09 at gmail.com
Tue Jun 18 03:56:44 PDT 2013


On 06/18/13 03:51, TommiT wrote:
> On Monday, 17 June 2013 at 13:59:34 UTC, Artur Skawina wrote:
>>
>>    struct _ForEach(alias MAP, TS...) {
>>       NTup!(TS.length, typeof(MAP(TS[0].init))) tuple;
>>
>>       this(TS values) {
>>          foreach (i, ref v; values)
>>             tuple[i] = MAP(v);
>>       }
>>    }
>>
>>    auto ForEach(alias MAP, TS...)(TS ts) {
>>       return _ForEach!(MAP, TS)(ts);
>>    }
>>
>>    void bar(T...)(T values) {
>>       foo(ForEach!(a=>arr[a]*10)(values).tuple);
>>    }

> Now, this is pretty cool. But I wonder a couple of things:
> 1) What kind of an impact does this have on compilation times compared to having this new ellipsis syntax which would allow the compiler to do a simple rewrite.

Not a significant one, I'd expect; for simple cases like these it shouldn't
make much difference.

> 2) I wonder if the compiler can optimize that _ForEach struct away.

Yes.


> Change the call to bar(1, 3L); and it wouldn't even compile.

> It's because all the types of _ForEach.tuple are the same as the first element of TS...
> 
> I mean... the same as the type of MAP(TS[0])

That was enough to handle the original problem, iirc.
Making the code work for heterogeneous args (and mapping functions) is
trivial, though:

   import std.stdio;

   template _TypeMap(alias MAP, size_t N, TS...) {
       static if (N<TS.length)
           alias _TypeMap = _TypeMap!(MAP, N+1, TS[0..N], typeof(MAP(TS[N].init), TS[N..$]));
       else
           alias _TypeMap = TS;
   }
   template TypeMap(alias MAP, TS...) {
      alias TypeMap = _TypeMap!(MAP, 0, TS);
   }

   struct _ForEach(alias MAP, TS...)
   {
       TypeMap!(MAP, TS) tuple;

       this(TS values)
       {
           foreach (i, ref v; values)
               tuple[i] = MAP(v);
       }
   }

   auto ForEach(alias MAP, TS...)(TS ts)
   {
       return _ForEach!(MAP, TS)(ts);
   }

   void foo(T...)(T values)
   {
       foreach (v; values)
           writeln(v);
   }

   void bar(T...)(T values)
   {
       foo(ForEach!(a => a + 1)(values).tuple);
   }

   void main()
   {
       bar(10, 3_000_000_000u, 2.14, -43L);
   }


artur


More information about the Digitalmars-d-learn mailing list