digitalmars.D.learn - Capturing caller's file/line number in variadic template functions
- H. S. Teoh (27/27) Mar 16 2012 I'm writing some unittests with very repetitive tests for a myriad of
- Adam D. Ruppe (5/11) Mar 16 2012 Put the string file = blaha in the template argument list,
- Kevin Cox (3/6) Mar 16 2012 T...)(T t) {
- Adam D. Ruppe (4/5) Mar 16 2012 Nah, it just works, at least for the implicit calls:
- H. S. Teoh (13/23) Mar 16 2012 No you don't. The compiler automatically infers the compile-time
- Steven Schveighoffer (5/23) Mar 16 2012 I know this is already answered, but do you get a stack trace? Shouldn'...
- H. S. Teoh (14/16) Mar 16 2012 [...]
- Steven Schveighoffer (5/18) Mar 16 2012 Right, but I dislike this sort of boilerplaty stuff, especially for unit...
- Yuri Gorobets (18/23) Mar 16 2012 Does it make sense to consider to add a new type to hold the file
I'm writing some unittests with very repetitive tests for a myriad of different types, so I wrote a helper function: version(unittest) { void checkConsistency(T...)(T args) { foreach (a; args) { assert(isConsistent(a)); } } } unittest { A a; B b; C c; checkConsistency(a,b,c); } However, when a consistency check fails, the assert error points to checkConsistency instead of the unittest, so it's a pain trying to figure out exactly which test case failed. I tried adding default arguments to checkConsistency: void checkConsistency(T...)(T args, string file=__FILE__, size_t line=__LINE__) { ... } but this causes compile errors because when C==string, then the call is ambiguous. Is there an easy of working around this? T -- To err is human; to forgive is not our policy. -- Samuel Adler
Mar 16 2012
On Friday, 16 March 2012 at 18:21:54 UTC, H. S. Teoh wrote:void checkConsistency(T...)(T args, string file=__FILE__, size_t line=__LINE__) { ... } but this causes compile errors because when C==string, then the call is ambiguous. Is there an easy of working around this?Put the string file = blaha in the template argument list, before the variadic. voic checkConsistency(string file = __FILE__, int line = __LINE__, T...)(T t) {
Mar 16 2012
On Mar 16, 2012 2:29 PM, "Adam D. Ruppe" <destructionator gmail.com> wrote:Put the string file = blaha in the template argument list, before the variadic. voic checkConsistency(string file = __FILE__, int line = __LINE__,T...)(T t) {But then you have to write it each time.
Mar 16 2012
On Friday, 16 March 2012 at 18:31:58 UTC, Kevin Cox wrote:But then you have to write it each time.Nah, it just works, at least for the implicit calls: checkConsistency(1, "2", 3); // calls checkConsistenct!(__FILE__, __LINE__, int, string, int)(1, "2", 3);
Mar 16 2012
On Fri, Mar 16, 2012 at 02:31:47PM -0400, Kevin Cox wrote:On Mar 16, 2012 2:29 PM, "Adam D. Ruppe" <destructionator gmail.com> wrote:No you don't. The compiler automatically infers the compile-time arguments for you. This works: int a; char b; float c; checkConsistency(a,b,c); // Gets translated to: checkConsistency!(__FILE__, __LINE__, int, char, float)(a,b,c); exactly as I wanted. T -- People say I'm arrogant, but they're just ignorant fools.Put the string file = blaha in the template argument list, before the variadic. voic checkConsistency(string file = __FILE__, int line = __LINE__,T...)(T t) {But then you have to write it each time.
Mar 16 2012
On Fri, 16 Mar 2012 14:23:37 -0400, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:I'm writing some unittests with very repetitive tests for a myriad of different types, so I wrote a helper function: version(unittest) { void checkConsistency(T...)(T args) { foreach (a; args) { assert(isConsistent(a)); } } } unittest { A a; B b; C c; checkConsistency(a,b,c); } However, when a consistency check fails, the assert error points to checkConsistency instead of the unittest, so it's a pain trying to figure out exactly which test case failed.I know this is already answered, but do you get a stack trace? Shouldn't the second stack frame point to the offending line? -Steve
Mar 16 2012
On Fri, Mar 16, 2012 at 02:30:25PM -0400, Steven Schveighoffer wrote: [...]I know this is already answered, but do you get a stack trace? Shouldn't the second stack frame point to the offending line?[...] I didn't compile with debugging turned on, so it only showed a hex address. Using compile-time args for __FILE__ and __LINE__ lets me see the offending line even when debug is off. (And actually, the offending line is several frames down; the top few frames look like unittest scaffolding the compiler inserted for catching assert errors and handling unittest-specific stuff. Kinda painful to figure out where the problem is if a straight error message will tell you immediately. :-)) T -- Indifference will certainly be the downfall of mankind, but who cares? -- Miquel van Smoorenburg
Mar 16 2012
On Fri, 16 Mar 2012 14:41:40 -0400, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:On Fri, Mar 16, 2012 at 02:30:25PM -0400, Steven Schveighoffer wrote: [...]Right, but I dislike this sort of boilerplaty stuff, especially for unit tests. It should be avoidable... -SteveI know this is already answered, but do you get a stack trace? Shouldn't the second stack frame point to the offending line?[...] I didn't compile with debugging turned on, so it only showed a hex address. Using compile-time args for __FILE__ and __LINE__ lets me see the offending line even when debug is off. (And actually, the offending line is several frames down; the top few frames look like unittest scaffolding the compiler inserted for catching assert errors and handling unittest-specific stuff. Kinda painful to figure out where the problem is if a straight error message will tell you immediately. :-))
Mar 16 2012
On Friday, 16 March 2012 at 18:21:54 UTC, H. S. Teoh wrote:void checkConsistency(T...)(T args, string file=__FILE__, size_t line=__LINE__) { ... } but this causes compile errors because when C==string, then the call is ambiguous.Does it make sense to consider to add a new type to hold the file name and line? So the types clash can be avoided: class file_line { this(string f=__FILE__, size_t ln=__LINE__) { file = f; line = ln; } string file; size_t line; }; void checkConsistency(T...) (T args, file_line pos = new file_line) {...} checkConsistency!(A,B,C)(a,b,c); Seems to work, but requires an explicit checkConsistency call - I didn't manage to make it implicit.
Mar 16 2012