Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread Yuri Gorobets

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.




Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread Steven Schveighoffer
On Fri, 16 Mar 2012 14:41:40 -0400, H. S. Teoh   
wrote:



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. :-))


Right, but I dislike this sort of boilerplaty stuff, especially for unit  
tests.  It should be avoidable...


-Steve


Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread Mantis

16.03.2012 20:35, H. S. Teoh пишет:

[...]


Actually, I found the solution: the compiler understands __FILE__ and 
__LINE__ in compile-time arguments too, so this works: void 
checkConsistency(string file=__FILE__, size_t line=__LINE__, T...)(T 
args) { ... } It's a bit painful with the assert statement, because it 
doesn't let you control the file/line number of the AssertError, but 
this can be worked around by using std.string.format: 
assert(isConsistent(a), "inconsistency found in 
%s(%d)".format(file,line)); The AssertError will still point to 
checkConsistency, but the error message will tell you where the caller 
is. T 


Yes, but the code is duplicated per every instance of template, and 
template is instantiated whenever it's CT-parameters change. This isn't 
much of a problem with functions that are meant to run at compile-time 
only (except that static locals will not work properly), but for 
run-time functions that may be undesired.


Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread H. S. Teoh
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


Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread Adam D. Ruppe

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);


Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread H. S. Teoh
On Fri, Mar 16, 2012 at 02:31:47PM -0400, Kevin Cox wrote:
> On Mar 16, 2012 2:29 PM, "Adam D. Ruppe"  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.

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.


Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread Steven Schveighoffer
On Fri, 16 Mar 2012 14:23:37 -0400, H. S. Teoh   
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


Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread H. S. Teoh
On Fri, Mar 16, 2012 at 08:26:30PM +0200, Mantis wrote:
> 16.03.2012 20:23, H. S. Teoh пишет:
> >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.
[...]
> What happens if you insert some dummy type ?:
> 
> void checkConsistency(T...)(T args, Delimiter dm = Delimiter.init,
>   string file=__FILE__, size_t line=__LINE__) { ... }


Actually, I found the solution: the compiler understands __FILE__ and
__LINE__ in compile-time arguments too, so this works:

void checkConsistency(string file=__FILE__, size_t
line=__LINE__, T...)(T args)
{
...
}

It's a bit painful with the assert statement, because it doesn't let you
control the file/line number of the AssertError, but this can be worked
around by using std.string.format:

assert(isConsistent(a),
"inconsistency found in %s(%d)".format(file,line));

The AssertError will still point to checkConsistency, but the error
message will tell you where the caller is.


T

-- 
The early bird gets the worm. Moral: ewww...


Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread Kevin Cox
On Mar 16, 2012 2:29 PM, "Adam D. Ruppe"  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.


Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread Adam D. Ruppe

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) {





Re: Capturing caller's file/line number in variadic template functions

2012-03-16 Thread Mantis

16.03.2012 20:23, H. S. Teoh пишет:

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


What happens if you insert some dummy type ?:

void checkConsistency(T...)(T args, Delimiter dm = Delimiter.init,
  string file=__FILE__, size_t line=__LINE__) { ... }




Capturing caller's file/line number in variadic template functions

2012-03-16 Thread H. S. Teoh
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