How to create TypeTuple/ExpressionTuple from tuple/tuples
Philippe Sigaud
philippe.sigaud at gmail.com
Tue Aug 7 23:58:15 PDT 2012
On Wed, Aug 8, 2012 at 7:01 AM, Philippe Sigaud
<philippe.sigaud at gmail.com> wrote:
>> But that doesn't work for variadic templates, which is the OP's case:
>>
>> int foo(T...)(T t) { return 1; }
>> alias expander!foo efoo; // error
>
> The template can easily be modified to deal with template functions,
> but in that case, you lose the parameter-type verification, for
> example if the function template has a constraint.
Like this:
/// Helper template to flatten a Tuple
template Expand(T)
{
static if (isTuple!T)
alias T.Types Expand;
else
alias T Expand;
}
/**
Take a function fun and return a transformed function that will expand
std.typecons.Tuple's provided as arguments and let other args untouched
*/
template expander(alias fun)
{
auto expander(Args...)(Args args)
{
static if (isSomeFunction!fun)
alias ParameterTypeTuple!fun Expanded;
else
alias staticMap!(Expand, Args) Expanded; // flatten the tuples
Expanded expanded;
/// Does the filling work: put values extracted from t in expanded
void from(int index = 0, TupleOrNot...)(TupleOrNot t)
{
static if (TupleOrNot.length > 0)
{
static if (isTuple!(TupleOrNot[0])) // It's a tuple,
expand it ...
{
expanded[index..index+TupleOrNot[0].length] = t[0].expand;
from!(index+TupleOrNot[0].length)(t[1..$]);
}
else // it's not a tuple, let it that way...
{
expanded[index] = t[0];
from!(index+1)(t[1..$]); // ...and continue the recursion
}
}
}
from(args);
return fun(expanded);
}
}
int foo(Ts...)(Ts ts)
{
return Ts.length;
}
void main()
{
alias expander!foo efoo;
writeln( foo(1, 3.14, "abc", 'a') ); // 4
writeln( efoo(tuple(1, 3.14, "abc", 'a')) ); // 4
writeln( efoo(tuple(1, 3.14), "abc", 'a') ); // 4
writeln( efoo(tuple(1, 3.14), tuple("abc", 'a')) ); // 4
}
More information about the Digitalmars-d-learn
mailing list