On Sep 15, 2013, at 18:36, Gavin Lambert
On 9/16/2013 12:45 PM, Quoth Jared Grubb:
The && operator actually isnt all that bad, since you would use short-circuit evaluation. So, "A && B && C" would result in one of "A failed", "A passed, but B failed", or "A and B passed, but C failed".
Short-circuit evaluation typically only happens for primitive types (ie. bool). When using custom types with overloaded operators the compiler will evaluate all arguments in a non-short-circuit manner. (Even if one of them is bool -- "false && expr()" will still result in evaluating the expression and calling the && operator when the expression returns a non-primitive type that implements operator&&.)
While it would be possible to print the messages as if short-circuit evaluation had been done, this would actually be discarding potentially useful information (eg. when A failed but B and C passed it suggests a different underlying fault than if all three failed). So I would suggest being verbose all the time anyway.
Short-circuit is still possible because the hamcrest-assertions are partially bound. So: BOOST_CHECK_PREDICATE( A && B, (value)); becomes like "(A && B)(value)". The wrapping object around "A && B" would hold A and B as members and would forward "value" according to short-circuit evaluation rules.
Assertion failed. Expected all of the following to pass: * contains(42) - passed * any of the following conditions: * contains(43) - failed * contains(44) - failed
I like this sort of syntax, except that for symmetry between the && and || operations I would expect it to look more like this:
Assertion failed. * all of the following conditions: * contains(42) - passed * any of the following conditions: * contains(43) - failed * contains(44) - failed
The idea being that the && and || operators would return something that would add a sibling message to a previous matching operator (for compactness of a && b && c && d etc) but would add a nested message to a different operator.
Yes, I think that is a good suggestion. Jared