Consider the following code:
import std;
auto logVariadic(T...)(T x,int line=__LINE__,string file=__FILE__) {
writeln(file,":",line," ",x);
}
int variadicCnt;
auto logVariadicWrapper(T...)(T x, int line=__LINE__, string file=__FILE__) {
variadicCnt++;
logVariadic(x,line,file);
}
auto args(T...)(T x) {
static struct Args(T...) {
static foreach(i, t; T) {
mixin(t, " v",i,";");
}
}
return Args!T(x);
}
auto log(Args)(Args args, int line=__LINE__, string file=__FILE__) {
writeln(file,":",line," ",args.tupleof);
}
int cnt;
auto logWrapper(Args)(Args args, int line=__LINE__, string file=__FILE__) {
cnt++;
log(args,line,file);
}
void main()
{
logVariadic("Hello ",1234);
logVariadicWrapper(1234, " is a number."); //produces wrong line number and adds line number and file name at the end
writeln(variadicCnt);
log(args("Hello ",1234));
logWrapper(args(1234, " is a number."));
writeln(cnt);
}
Produces output:
onlineapp.d:32 Hello 1234
onlineapp.d:10 1234 is a number.33onlineapp.d
1
onlineapp.d:35 Hello 1234
onlineapp.d:36 1234 is a number.
1
Any other ways to be able to achieve the same without double wrapping arguments like above? I guess the above is okay but I thought I would see other options.
(I know that one can pass line and file as template arguments, but that produces a new instance of log or logWrapper per use).