Jared Grubb
3. Boost.Test already have this macro. It is called BOOST_CHECK_PREDICATE
BOOST_CHECK_PREDICATE( P, (a)(b)(c) );
Very nice symmetry and most of your your other points covered (stackability etc)
I hadnt seen that one; I tried it, but it does require extra parens that I find distracting:
I find your asymmetry more distructing
BOOST_CHECK_PREDICATE(vec, (Contains(42)));
This obviously is wrong syntax.
However, there are a class of assertions that get a bit ugly in the BOOST_TEST form: * Contains(42) vs vec.find(42) != vec.end() * Any(Contains(42), Contains(43)) vs. ( vec.find(42) != vec.end() || vec.find(43) != vec.end())
I would use || and && and ! instead of Any, All, Not: BOOST_CHECK_PREDICATE( contains(42) || contains(65), (container) ); BOOST_CHECK_PREDICATE( contains(5) && !contains(6), (container) );
Using a higher level concept, rather than raw STL algorithm, also lets the failure messages be a bit more coherent.
There are 3 issues: * We probably to do not want to replicate whole STL with "better error message" predicates operating on containers instead of iterators * What if I do want to use iterators? * I wonder how will you combine generically messages from 3 different predicates in And predicate? We failed because "error msg 1" and "err msg 2" and "err msg 3". This can become ugly very fast.
The partially-bound nature of these assertions ( where _THAT( a, A(x) ) => "A(x)(a)" ) is useful because it means the value-under-test can be written once and, even more important, the value's expression is evaluated only once.
This is also true in BOOST_CHECK_PREDICATE case (both parts). I do not see any single reason to use this asymmetric syntax. Another complication to keep in mind is that you need to make all your predicate "silently" bindable (here silently means an absence of bind invocation. In other words both these should be valid: BOOST_CHECK_PREDICATE( contains(1), (container) ); BOOST_CHECK_PREDICATE( contains, (container, 1) ); BOOST_CHECK_PREDICATE( within_range(1,10), (value) ); BOOST_CHECK_PREDICATE( !within_range, (value,1,10) ); Gennadiy