Variadic macro question and namespace Catch question

50 views
Skip to first unread message

Pepe Paulson

unread,
Mar 20, 2014, 5:02:38 PM3/20/14
to catch...@googlegroups.com
Hello, I have some questions about CATCH.

1. Could all of the macros that take expressions be variadic? Consider code like this:

CHECK(position() == coordinate{5,3});

Which fails to compile because the CPP thinks that's a 2-argument macro instead of one. I have been adding an extra set of parenthesis to the macros but that is annoying and error-prone.

2. Are there any rules for adding to the Catch namespace? For example, I want to do this to get around ADL issues:

namespace Catch { // CATCH won't find this in the global namespace
std::ostream& operator<<(std::ostream& o, std::vector<int> const& s) {
    for(auto&& i : s)
        o << i << ' ';
    return o;
}
}
but I want to make sure I'm not relying on undocumented features. Is this safe/good?

Many thanks,
Pepe

Phil Nash

unread,
Mar 21, 2014, 2:41:55 PM3/21/14
to catch...@googlegroups.com


On Thursday, 20 March 2014 21:02:38 UTC, Pepe Paulson wrote:
Hello, I have some questions about CATCH.

1. Could all of the macros that take expressions be variadic? Consider code like this:

CHECK(position() == coordinate{5,3});

Which fails to compile because the CPP thinks that's a 2-argument macro instead of one. I have been adding an extra set of parenthesis to the macros but that is annoying and error-prone.

Ah yes, C++11 introduces more ways to break the preprocessor!
Making them variadic might be sufficient to workaround that. I had half a mind to reserve the use of variadics here for annotations, but you're right - it's a pain that could, potentially, be avoided. I'll certainly consider it (but, note, I'm not actively working on it for a few weeks as I prepare for some conferences).
 
2. Are there any rules for adding to the Catch namespace? For example, I want to do this to get around ADL issues:

namespace Catch { // CATCH won't find this in the global namespace
std::ostream& operator<<(std::ostream& o, std::vector<int> const& s) {
    for(auto&& i : s)
        o << i << ' ';
    return o;
}
}
but I want to make sure I'm not relying on undocumented features. Is this safe/good?

 To answer your immediate question: it's certainly not as strict as the std namespace, and for adding specialisations for your own types it's the only way.
Here, though, you're using std::vector. Catch already has specialisations for std::vector (but on toString() - or more specifically StringMaker - rather than operator<<). Catch generally only falls back to ostream's operator<< if it can't find a toString/ StringMaker specialisation. So in what context are you seeing a need for this specific example?

In other cases you should specialise Catch::toString (for simple types) or, if you need partial specialisation (as for vector<T>) Catch::StringMaker.

HTH
Reply all
Reply to author
Forward
0 new messages