A little example ...
import std.stdio;
import std.traits;
import std.typetuple;
import std.metastrings;
alias ParameterStorageClassTuple PSCT;
alias ParameterStorageClass PSC;
alias ParameterTypeTuple PTT;
string ToStorageName(alias T)()
{
static if(T == PSC.REF) return "ref";
else static if (T == PSC.OUT) return "out";
else static if (T == PSC.LAZY) return "lazy";
else static if (T == PSC.SCOPE) return "scope";
else static if (T == PSC.NONE) return "in";
else static assert(false, "other");
}
string PrintStorageTuple(int index, alias F, STs...)()
{
alias PTT!F Ts;
string ret = "";
static if (STs.length > 0)
{
ret ~= ToStorageName!(STs[0])() ~ " " ~ Ts[0].stringof;
ret ~= " arg" ~ toStringNow!(index);
}
static if (STs.length > 1)
{
void func(Ts[1..$] a)
{
}
const a = index + 1;
ret ~= ", " ~ PrintStorageTuple!(a, func, STs[1..$])();
}
return ret;
}
string PrintStorage(alias F)(string name)
{
alias PSCT!F STs;
string ret = "auto " ~ name ~ "(" ~ PrintStorageTuple!(0, F, STs)() ~ ")";
return ret;
}
// **** tests
int Multiply(int a, int b, out int c)
{
return c = a * b;
}
mixin(PrintStorage!Multiply("DebugMultiply") ~ q{
{
writeln("DEBUG: ", arg0, " ", arg1, " ", arg2);
return Multiply(arg0, arg1, arg2);
}
});
void main()
{
int a= 10, b = -3, c;
writeln(Multiply(a, b, c));
writeln(c);
a = 3;
b = -4;
writeln(DebugMultiply(a, b, c));
writeln(c);
}