digitalmars.D.learn - Capturing __FILE__ and __LINE in a variadic templated function
- =?UTF-8?B?Tm9yZGzDtnc=?= (28/28) Nov 01 2015 Is it possible to make the following definition
- Adam D. Ruppe (6/6) Nov 01 2015 Yeah, just make the other args normal runtime instead of template:
- anonymous (10/11) Nov 01 2015 Or make it two nested templates:
- =?UTF-8?B?Tm9yZGzDtnc=?= (5/17) Nov 02 2015 Doesn't work.
- Gary Willoughby (2/3) Nov 02 2015 typeof(T).stringof
- =?UTF-8?B?Tm9yZGzDtnc=?= (45/48) Nov 02 2015 No, I want the variable name from the calling scope.
- John Colvin (27/77) Nov 02 2015 Works for me on multiple compilers. To be precise, this worked:
- Daniel N (3/5) Nov 02 2015 Except it prints Arg instead of x, try:
- =?UTF-8?B?Tm9yZGzDtnc=?= (18/44) Nov 02 2015 No. This prints:
- Daniel N (3/5) Nov 02 2015 See my previous comment:
- =?UTF-8?B?Tm9yZGzDtnc=?= (2/8) Nov 02 2015 Ahh! Great! Thx!
- Jonathan M Davis via Digitalmars-d-learn (8/19) Nov 02 2015 You should pretty much never use __FILE__ or __LINE__ as template argume...
- =?UTF-8?B?Tm9yZGzDtnc=?= (3/11) Nov 02 2015 Ahh, thanks.
- =?UTF-8?B?Tm9yZGzDtnc=?= (3/11) Nov 02 2015 So why is this pattern is used all over std.experimental.logger?
- Jonathan M Davis via Digitalmars-d-learn (17/29) Nov 03 2015 I don't know. I haven't looked at std.experimental.logger much. I do vag...
Is it possible to make the following definition void show(alias T, string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { import std.stdio: writeln; try { debug writeln(file, ":",line, ":" /* , ": in ",fun */, " debug: ", T.stringof, ":", T); } catch (Exception) { } } used as unittest { int x = 11; int y = 12; int z = 13; show!x; show!y; show!z; } variadic so that it, instead, can be called as unittest { int x = 11; int y = 12; int z = 13; show!(x,y,z); } and still capture current file, line and function?
Nov 01 2015
Yeah, just make the other args normal runtime instead of template: void show(T...)(string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__) { // same body } // same usage
Nov 01 2015
On 01.11.2015 23:49, Adam D. Ruppe wrote:Yeah, just make the other args normal runtime instead of template:Or make it two nested templates: template show(T ...) { void show(string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { ... } }
Nov 01 2015
On Sunday, 1 November 2015 at 23:36:15 UTC, anonymous wrote:On 01.11.2015 23:49, Adam D. Ruppe wrote:Doesn't work. I need `T` to be an alias in order for .stringof to work. How do I specify a variadic template argument alias list of aliases?Yeah, just make the other args normal runtime instead of template:Or make it two nested templates: template show(T...) { void show(string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { ... } }
Nov 02 2015
On Monday, 2 November 2015 at 08:23:16 UTC, Nordlöw wrote:I need `T` to be an alias in order for .stringof to work.typeof(T).stringof
Nov 02 2015
On Monday, 2 November 2015 at 09:02:28 UTC, Gary Willoughby wrote:On Monday, 2 November 2015 at 08:23:16 UTC, Nordlöw wrote:No, I want the variable name from the calling scope. This works for a single argument. void show(alias arg, string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { import std.stdio: writeln; try { debug writeln(file, ":",line, ":" /* , ": in ",fun */, " debug: ", arg.stringof, " is ", arg); } catch (Exception) { } } unittest { int x = 11; show!x; } Prints dbg.d:80: debug: x is 11 My try at variadic template show(Args...) { void show(string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { import std.stdio: write, writeln; try { debug write(file, ":",line, ":" /* , ": in ",fun */, " debug: "); foreach (const i, Arg; Args) { if (i) debug write(", "); // separator debug write(Arg.stringof, " is ", Arg); } debug writeln(); } catch (Exception) { } } } fails with compilation error dbg.d(83,5): Error: variable x cannot be read at compile time Why can't I make Args a sequence of aliases?I need `T` to be an alias in order for .stringof to work.typeof(T).stringof
Nov 02 2015
On Monday, 2 November 2015 at 09:16:09 UTC, Nordlöw wrote:On Monday, 2 November 2015 at 09:02:28 UTC, Gary Willoughby wrote:Works for me on multiple compilers. To be precise, this worked: template show(Args...) { void show(string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { import std.stdio: write, writeln; try { debug write(file, ":",line, ":" /* , ": in ",fun */, " debug: "); foreach (const i, Arg; Args) { if (i) debug write(", "); // separator debug write(Arg.stringof, " is ", Arg); } debug writeln(); } catch (Exception) { } } } unittest { int x = 11; show!x; }On Monday, 2 November 2015 at 08:23:16 UTC, Nordlöw wrote:No, I want the variable name from the calling scope. This works for a single argument. void show(alias arg, string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { import std.stdio: writeln; try { debug writeln(file, ":",line, ":" /* , ": in ",fun */, " debug: ", arg.stringof, " is ", arg); } catch (Exception) { } } unittest { int x = 11; show!x; } Prints dbg.d:80: debug: x is 11 My try at variadic template show(Args...) { void show(string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { import std.stdio: write, writeln; try { debug write(file, ":",line, ":" /* , ": in ",fun */, " debug: "); foreach (const i, Arg; Args) { if (i) debug write(", "); // separator debug write(Arg.stringof, " is ", Arg); } debug writeln(); } catch (Exception) { } } } fails with compilation error dbg.d(83,5): Error: variable x cannot be read at compile time Why can't I make Args a sequence of aliases?I need `T` to be an alias in order for .stringof to work.typeof(T).stringof
Nov 02 2015
On Monday, 2 November 2015 at 09:54:50 UTC, John Colvin wrote:Except it prints Arg instead of x, try: debug write(Args[i].stringof, " is ", Arg);Why can't I make Args a sequence of aliases?Works for me on multiple compilers. To be precise, this worked:
Nov 02 2015
On Monday, 2 November 2015 at 09:54:50 UTC, John Colvin wrote:Works for me on multiple compilers. To be precise, this worked: template show(Args...) { void show(string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { import std.stdio: write, writeln; try { debug write(file, ":",line, ":" /* , ": in ",fun */, " debug: "); foreach (const i, Arg; Args) { if (i) debug write(", "); // separator debug write(Arg.stringof, " is ", Arg); } debug writeln(); } catch (Exception) { } } } unittest { int x = 11; show!x; }No. This prints: Arg is 11 I want it to print the name of Arg in the closing as x is 11 equivalent to what my single-parameter overload void show(alias arg, string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { import std.stdio: writeln; try { debug writeln(file, ":",line, ":" /* , ": in ",fun */, " debug: ", arg.stringof, " is ", arg); } catch (Exception) { } } does.
Nov 02 2015
On Monday, 2 November 2015 at 11:36:27 UTC, Nordlöw wrote:I want it to print the name of Arg in the closing as x is 11See my previous comment: Arg -> Args[i].stringof
Nov 02 2015
On Monday, 2 November 2015 at 11:44:45 UTC, Daniel N wrote:On Monday, 2 November 2015 at 11:36:27 UTC, Nordlöw wrote:Ahh! Great! Thx!I want it to print the name of Arg in the closing as x is 11See my previous comment: Arg -> Args[i].stringof
Nov 02 2015
On Monday, November 02, 2015 00:36:14 anonymous via Digitalmars-d-learn wrote:On 01.11.2015 23:49, Adam D. Ruppe wrote:You should pretty much never use __FILE__ or __LINE__ as template arguments unless you actually need to. The reason is that it will end up creating a new instantiation of the template pretty much every time that it's used, which is going to be mean a _lot_ of extra code bloat if you use the template much. And in some, rare circumstances that may be exactly what you want. But it almost never is. - Jonathan M DavisYeah, just make the other args normal runtime instead of template:Or make it two nested templates: template show(T ...) { void show(string file = __FILE__, uint line = __LINE__, string fun = __FUNCTION__)() { ... } }
Nov 02 2015
On Tuesday, 3 November 2015 at 06:14:14 UTC, Jonathan M Davis wrote:You should pretty much never use __FILE__ or __LINE__ as template arguments unless you actually need to. The reason is that it will end up creating a new instantiation of the template pretty much every time that it's used, which is going to be mean a _lot_ of extra code bloat if you use the template much. And in some, rare circumstances that may be exactly what you want. But it almost never is. - Jonathan M DavisAhh, thanks.
Nov 02 2015
On Tuesday, 3 November 2015 at 06:14:14 UTC, Jonathan M Davis wrote:You should pretty much never use __FILE__ or __LINE__ as template arguments unless you actually need to. The reason is that it will end up creating a new instantiation of the template pretty much every time that it's used, which is going to be mean a _lot_ of extra code bloat if you use the template much. And in some, rare circumstances that may be exactly what you want. But it almost never is. - Jonathan M DavisSo why is this pattern is used all over std.experimental.logger?
Nov 02 2015
On Tuesday, November 03, 2015 07:35:40 Nordlöw via Digitalmars-d-learn wrote:On Tuesday, 3 November 2015 at 06:14:14 UTC, Jonathan M Davis wrote:I don't know. I haven't looked at std.experimental.logger much. I do vaguely recall there being a discussion about that and there being something that prevented it from using __FILE__ and __LINE__ as runtime arguments, but I don't remember the reason. If I had to guess though, it would be be because of variadic arguments, since AFAIK, you can't have any function parameters after the variadic ones (even if they have default arguments), which makes it so that you can't put __FILE__ and __LINE__ as default arguments at the end like you'd normally do. Maybe that would be a good reason for a language enhancement that made it possible. It doesn't make sense when you want to be able provide arguments other than the default arguments to those trailing parameters, but it does make sense when you just want to use the default arguments - which really only makes sense with stuff like __FILE__ and __LINE__, but it would allow us to get rid of all of the template bloat that std.experimental.logger is going to generate if it's taking the __FILE__ and __LINE__ as template arguments. - Jonathan M DavisYou should pretty much never use __FILE__ or __LINE__ as template arguments unless you actually need to. The reason is that it will end up creating a new instantiation of the template pretty much every time that it's used, which is going to be mean a _lot_ of extra code bloat if you use the template much. And in some, rare circumstances that may be exactly what you want. But it almost never is. - Jonathan M DavisSo why is this pattern is used all over std.experimental.logger?
Nov 03 2015