Last active
April 3, 2025 10:48
-
-
Save tclamb/9149587 to your computer and use it in GitHub Desktop.
minimal working implementation of catch-lib's CHECK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
struct is_unary | |
{ | |
operator bool() { return {}; }; | |
}; | |
template <typename lhsT, typename rhsT> | |
struct result | |
{ | |
lhsT lhs_val; | |
rhsT rhs_val; | |
bool passed; | |
result(lhsT l, rhsT r, bool p) : lhs_val{l}, rhs_val{r}, passed{p} {}; | |
bool binary = true; | |
result<lhsT, rhsT> done() { | |
return *this; | |
} | |
}; | |
template <typename lhsT> | |
struct result<lhsT, is_unary> | |
{ | |
lhsT lhs_val; | |
is_unary rhs_val; | |
bool passed; | |
result(lhsT l, is_unary, bool p) : lhs_val{l}, passed{p} {}; | |
bool binary = false; | |
}; | |
template <typename lhsT> | |
struct result_builder | |
{ | |
lhsT lhs_val; | |
result_builder(lhsT l) : lhs_val{l} {}; | |
#define BIN_OPS X(==) \ | |
X(!=) \ | |
X(< ) \ | |
X(<=) \ | |
X(> ) \ | |
X(>=) | |
#define X(bin_op) template<typename rhsT> \ | |
result<lhsT, rhsT const&> operator bin_op (rhsT const& rhs_val) { \ | |
return {lhs_val, rhs_val, lhs_val bin_op rhs_val}; \ | |
} | |
BIN_OPS | |
#undef X | |
#undef BIN_OPS | |
/* | |
template<typename rhsT> | |
result<lhsT, rhsT const&> operator==(rhsT const& expr) { | |
return {lhs_val, expr, lhs_val == expr}; | |
} | |
*/ | |
result<lhsT, is_unary> done() { | |
return {lhs_val, is_unary{}, static_cast<bool>(lhs_val)}; | |
} | |
}; | |
struct lhs | |
{ | |
template<typename T> | |
result_builder<T const&> operator<= (T const& expr) { | |
return {expr}; | |
} | |
}; | |
#define CHECK(expr) do { \ | |
auto res = (lhs{}<=expr).done(); \ | |
if (!res.passed) { \ | |
std::cerr << "check failed: " #expr "\n"; \ | |
if (res.binary) { \ | |
std::cerr << " expanded: " << res.lhs_val << " == " << res.rhs_val << "\n"; \ | |
} else { \ | |
std::cerr << " expanded: " << res.lhs_val << "\n"; \ | |
} \ | |
} \ | |
} while(0) | |
int main() { | |
auto zero = [](){ return 0; }; | |
auto one = [](){ return 1; }; | |
CHECK(zero() == one()); | |
CHECK(zero()); | |
CHECK(one()); | |
CHECK(one() == 1); | |
CHECK(one() != 1); | |
CHECK(zero() > one()); | |
CHECK(zero() <= one()); | |
auto counter = [x=0]() mutable { return x++; } | |
CHECK(counter() == zero()); | |
CHECK(counter() == one()); | |
CHECK(counter() == one()); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
this is good but you need to save the operator(s) to reconstruct the right expression, as the current version prints this