#include <cmath>
#include <iostream>
#include <limits>
#include <vector>

// A finite, bounded teaching contract; not a general extreme-value comparator.
bool near_small(double actual, double expected, double atol, double rtol) {
    if (!std::isfinite(actual) || !std::isfinite(expected) ||
        !std::isfinite(atol) || !std::isfinite(rtol)) return false;
    if (std::abs(actual) > 100.0 || std::abs(expected) > 100.0 ||
        atol < 0.0 || atol > 1.0 || rtol < 0.0 || rtol > 1.0) return false;
    const double scale = std::abs(actual) > std::abs(expected)
        ? std::abs(actual) : std::abs(expected);
    return std::abs(actual - expected) <= atol + rtol * scale;
}

struct Case {
    double actual;
    double expected;
    double atol;
    double rtol;
    bool accepted;
};

int main() {
    static_assert(std::numeric_limits<double>::has_quiet_NaN);
    static_assert(std::numeric_limits<double>::has_infinity);
    const double nan = std::numeric_limits<double>::quiet_NaN();
    const double inf = std::numeric_limits<double>::infinity();
    const std::vector<Case> cases{
        {1.0, 1.0, 0.0, 0.0, true},
        {0.0000005, 0.0, 0.000001, 0.01, true},
        {1.01, 1.0, 0.001, 0.001, false},
        {nan, 1.0, 0.001, 0.001, false},
        {inf, inf, 0.001, 0.001, false},
        {1.0, 1.0, -0.001, 0.001, false},
        {1.0, 1.0, 0.001, nan, false},
        {101.0, 101.0, 0.001, 0.001, false}
    };
    int checks{0};
    int failures{0};
    for (const auto& c : cases) {
        const bool accepted = near_small(c.actual, c.expected, c.atol, c.rtol);
        ++checks;
        if (accepted != c.accepted) ++failures;
        std::cout << "case=" << checks << " accepted=" << accepted << '\n';
    }
    if (checks != 8) ++failures;
    std::cout << "checks=" << checks << " failures=" << failures << '\n';
    return failures == 0 ? 0 : 1;
}
