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