On Tuesday, 18 June 2013 at 10:57:00 UTC, Artur Skawina wrote:
On 06/18/13 03:51, TommiT wrote:
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

Okay, you really seem to have figured this stuff out. I think I have difficulty seeing the solution because I'm used to C++ parameter packs, which have much less functionality than parameter tuples in D + there's no static if. But I learned a lot from this, thanks for that.

Reply via email to