Capturing caller's file/line number in variadic template functions
H. S. Teoh
hsteoh at quickfur.ath.cx
Fri Mar 16 11:35:37 PDT 2012
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...
More information about the Digitalmars-d-learn
mailing list