Skip to content

Instantly share code, notes, and snippets.

@tclamb
Last active April 3, 2025 10:48
Show Gist options
  • Save tclamb/9149587 to your computer and use it in GitHub Desktop.
Save tclamb/9149587 to your computer and use it in GitHub Desktop.
minimal working implementation of catch-lib's CHECK
#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;
}
@izabera
Copy link

izabera commented Apr 3, 2025

this is good but you need to save the operator(s) to reconstruct the right expression, as the current version prints this

check failed: zero() > one()
    expanded: 0 == 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment