// Copyright 2019 Hans Dembinski // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include using namespace boost::histogram::detail; struct TotallyOrdered : totally_ordered { TotallyOrdered(int i) : x(i) {} bool operator<(const TotallyOrdered& o) const noexcept { return x < o.x; } bool operator==(const TotallyOrdered& o) const noexcept { return x == o.x; } bool operator<(const int& o) const noexcept { return x < o; } bool operator>(const int& o) const noexcept { return x > o; } bool operator==(const int& o) const noexcept { return x == o; } int x; }; std::ostream& operator<<(std::ostream& os, const TotallyOrdered& t) { os << t.x; return os; } struct PartiallyOrdered : partially_ordered { PartiallyOrdered(double i) : x(i) {} bool operator<(const PartiallyOrdered& o) const noexcept { return x < o.x; } bool operator==(const PartiallyOrdered& o) const noexcept { return x == o.x; } bool operator<(const double& o) const noexcept { return x < o; } bool operator>(const double& o) const noexcept { return x > o; } bool operator==(const double& o) const noexcept { return x == o; } double x; }; std::ostream& operator<<(std::ostream& os, const PartiallyOrdered& t) { os << t.x; return os; } template void test_nan(std::false_type) {} template void test_nan(std::true_type) { const U nan = std::numeric_limits::quiet_NaN(); // IEEE 754: Any comparison with nan is false, except != which is true. // But some of the following tests fail on MSVC: // BOOST_TEST_NOT(nan < nan); // true, should be false // BOOST_TEST_NOT(nan > nan); // BOOST_TEST_NOT(nan == nan); // BOOST_TEST_NOT(nan <= nan); // true, should be false // BOOST_TEST_NOT(nan >= nan); // BOOST_TEST(nan != nan); // Probably related: // https://developercommunity.visualstudio.com/content/problem/445462/nan-nan-is-constant-folded-to-true-but-should-prob.html // The tests below don't fail probably because constant-folding doesn't happen. BOOST_TEST_NOT(T(1.0) < T(nan)); BOOST_TEST_NOT(T(1.0) > T(nan)); BOOST_TEST_NOT(T(1.0) == T(nan)); BOOST_TEST_NOT(T(1.0) <= T(nan)); BOOST_TEST_NOT(T(1.0) >= T(nan)); BOOST_TEST(T(1.0) != T(nan)); BOOST_TEST_NOT(T(nan) < 1.0); BOOST_TEST_NOT(T(nan) > 1.0); BOOST_TEST_NOT(T(nan) == 1.0); BOOST_TEST_NOT(T(nan) <= 1.0); BOOST_TEST_NOT(T(nan) >= 1.0); BOOST_TEST(T(nan) != 1.0); BOOST_TEST_NOT(1.0 < T(nan)); BOOST_TEST_NOT(1.0 > T(nan)); BOOST_TEST_NOT(1.0 == T(nan)); BOOST_TEST_NOT(1.0 <= T(nan)); BOOST_TEST_NOT(1.0 >= T(nan)); BOOST_TEST(1.0 != T(nan)); BOOST_TEST_NOT(T(nan) < T(nan)); BOOST_TEST_NOT(T(nan) > T(nan)); BOOST_TEST_NOT(T(nan) == T(nan)); BOOST_TEST_NOT(T(nan) <= T(nan)); BOOST_TEST_NOT(T(nan) >= T(nan)); BOOST_TEST(T(nan) != T(nan)); BOOST_TEST_NOT(T(nan) < nan); BOOST_TEST_NOT(T(nan) > nan); BOOST_TEST_NOT(T(nan) == nan); BOOST_TEST_NOT(T(nan) <= nan); BOOST_TEST_NOT(T(nan) >= nan); BOOST_TEST(T(nan) != nan); BOOST_TEST_NOT(nan < T(nan)); BOOST_TEST_NOT(nan > T(nan)); BOOST_TEST_NOT(nan == T(nan)); BOOST_TEST_NOT(nan <= T(nan)); BOOST_TEST_NOT(nan >= T(nan)); BOOST_TEST(nan != T(nan)); } template void test() { T x{1}; U e{1}, l{0}, u{2}; BOOST_TEST_EQ(x, e); BOOST_TEST_NE(x, l); BOOST_TEST_LT(x, u); BOOST_TEST_GT(x, l); BOOST_TEST_LE(x, e); BOOST_TEST_LE(x, u); BOOST_TEST_GE(x, e); BOOST_TEST_GE(x, l); BOOST_TEST_EQ(e, x); BOOST_TEST_NE(l, x); BOOST_TEST_LT(l, x); BOOST_TEST_GT(u, x); BOOST_TEST_LE(e, x); BOOST_TEST_LE(l, x); BOOST_TEST_GE(e, x); BOOST_TEST_GE(u, x); test_nan(std::is_floating_point{}); } int main() { test(); test(); test(); test(); return boost::report_errors(); }