Consider the following code:
```d
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).

Reply via email to