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.