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