Matching variational template arguments in D

Is there a built-in or library-provided way to map a set of variational template arguments in D?

For example:

void foo(Args...)(Args args) { bar(fun(args)); } 

I want this extension to be:

 void foo(Args...)(Args args) { bar(fun(args[0]), fun(args[1]), fun(args[2]), /* ... */); } 

C ++ 11 variational patterns support this. How do you do the same in D?

+7
source share
2 answers

This is the best I came up with:

 auto staticMappedCall(alias call, alias F, T...)(T t) { T a; foreach(i, arg; t) a[i] = F(arg); return call(a); } 

You use it as follows:

  staticMappedCall!(bar,t)(1, 2); 

Where bar is a call function and t is a transform.

 void bar(int a, int b) { writeln(a, " ", b); } int t(int a) { return a*2; } staticMappedCall!(bar, t)(1, 2); > test 2 4 
+6
source

Here's an updated version that compiles with the latest versions of the D compiler:

 /** Return a Tuple expression of $(D Func) being applied to every tuple argument. */ template Map(alias Func, args...) { static auto ref ArgCall(alias Func, alias arg)() { return Func(arg); } static if (args.length > 1) alias Map = TypeTuple!(ArgCall!(Func, args[0]), Map!(Func, args[1 .. $])); else alias Map = ArgCall!(Func, args[0]); } /// unittest { import std.conv; int square(int arg) { return arg * arg; } int refSquare(ref int arg) { arg *= arg; return arg; } ref int refRetSquare(ref int arg) { arg *= arg; return arg; } void test(int a, int b) { assert(a == 4, a.text); assert(b == 16, b.text); } void testRef(ref int a, ref int b) { assert(a++ == 16, a.text); assert(b++ == 256, b.text); } int a = 2; int b = 4; test(Map!(square, a, b)); test(Map!(refSquare, a, b)); assert(a == 4); assert(b == 16); testRef(Map!(refRetSquare, a, b)); assert(a == 17); assert(b == 257); } 
+7
source

All Articles