On Friday, 2 August 2013 at 12:58:08 UTC, John Colvin wrote:
Is this what you want?
I just ran in to a problem with this. It can't work for
anything other than global functions.
void main()
{
int fun6(int i)
{
writeln("fun6 ", i);
return i;
}
a!(fun6)(99);
}
std/typetuple.d(664): Error: template instance pred!(fun6)
cannot use local 'fun6' as parameter to non-global template
isVoidFun(alias fun)
So it's back to that same problem again.
The "root" problem is that filter just isn't adapted here. If you
don't mind writing "filter 2 (for example)" though...
//--------
import std.stdio, std.typetuple;
template isVoidArg(alias F, U)
{
enum isVoidArg = is(typeof(F(U.init)) == void);
}
template isNonVoidArg(alias F, U)
{
enum isNonVoidArg = is(typeof({auto a = F(U.init);}));
}
template isErrorArg(alias F, U)
{
enum isErrorArg = !is(typeof(F(U.init)));
}
template Filter2(alias pred, U, TList...)
{
static if (TList.length == 0)
{
alias Filter2 = TypeTuple!();
}
else static if (TList.length == 1)
{
static if (pred!(TList[0], U))
alias Filter2 = TypeTuple!(TList[0]);
else
alias Filter2 = TypeTuple!();
}
else
{
alias Filter2 =
TypeTuple!(
Filter2!(pred, U, TList[ 0 .. $/2]),
Filter2!(pred, U, TList[$/2 .. $ ]));
}
}
template a(funs...)
{
auto a(R)(R r)
{
alias nonVoidFuns = Filter2!(isNonVoidArg, R, funs);
alias voidFuns = Filter2!(isVoidArg, R, funs);
alias voidErrorFuns = Filter2!(isErrorArg, R, funs);
import std.functional : adjoin;
writeln("Calling all non voids!");
adjoin!nonVoidFuns(r);
writeln("Calling all voids!");
adjoin!voidFuns(r);
}
}
void main()
{
void fun1(string i)
{
writeln("fun1 ", i);
}
int fun2()
{
writeln("fun2");
return int.min;
}
void fun3(int i)
{
writeln("fun3 ", i);
}
int fun4(int i)
{
writeln("fun4 ", i);
return i;
}
a!(fun1, fun2, fun3, fun4)(99);
}
//--------
The template names kind of suck though. You may want to change
some of them.