c++: prev declared hidden tmpl friend inst [PR112288]
[official-gcc.git] / libstdc++-v3 / testsuite / 18_support / comparisons / algorithms / strong_order_floats.cc
blob135cba2e6588345a6fa0c6ad870f75f7b55f585c
1 // { dg-do compile { target c++20 } }
3 #include <compare>
4 #include <limits>
5 #include <testsuite_hooks.h>
7 // Test floating-point ordering.
9 template<typename T> constexpr T epsilon = std::numeric_limits<T>::epsilon();
11 // PR middle-end/19779 IBM 128bit long double format is not constant folded.
12 // 1.0L + numeric_limits<long double>::epsilon() is not a constant expression
13 // so just use numeric_limits<double>::epsilon() instead.
14 #if defined __LONG_DOUBLE_IBM128__
15 using D = long double;
16 #elif defined __LONG_DOUBLE_IEEE128__ && defined __SIZEOF_IBM128__
17 using D = __ibm128;
18 #else
19 using D = double;
20 #endif
22 template<> constexpr D epsilon<D> = std::numeric_limits<double>::epsilon();
24 template<typename Float>
25 constexpr bool
26 test_fp()
28 const auto& less = std::strong_ordering::less;
29 const auto& greater = std::strong_ordering::greater;
31 static_assert( std::numeric_limits<Float>::is_specialized);
32 Float min = std::numeric_limits<Float>::lowest();
33 Float max = std::numeric_limits<Float>::max();
34 Float qnan = std::numeric_limits<Float>::quiet_NaN();
35 Float snan = std::numeric_limits<Float>::signaling_NaN();
36 Float inf = std::numeric_limits<Float>::infinity();
37 Float denorm = std::numeric_limits<Float>::denorm_min();
38 Float smallest = std::numeric_limits<Float>::min();
40 // -qnan < -snan < -inf < -num < -zero < +zero < +num < +inf < +snan < +qnan
42 struct Test
44 Float lhs;
45 Float rhs;
46 std::strong_ordering expected;
48 constexpr explicit operator bool() const noexcept
49 { return std::strong_order(lhs, rhs) == expected; }
51 constexpr Test rev() const noexcept
52 { return { rhs, lhs, 0 <=> expected }; }
54 constexpr Test neg() const noexcept
55 { return { -lhs, -rhs, 0 <=> expected }; }
58 auto test = [&](Test t, bool selftest = true) {
59 if (selftest)
61 // Check that each operand compares equal to itself.
62 if (std::strong_order(t.lhs, t.lhs) != std::strong_ordering::equal)
63 return false;
64 if (std::strong_order(t.rhs, t.rhs) != std::strong_ordering::equal)
65 return false;
67 return t && t.rev() && t.neg() && t.rev().neg();
70 VERIFY(test({ 1.0, 2.0, less }));
71 VERIFY(test({ 1.0, -2.0, greater }));
72 VERIFY(test({ 3e6, 2e9, less }));
73 VERIFY(test({ 8e8, -9e9, greater }));
74 VERIFY(test({ 0.0, -0.0, greater }));
75 VERIFY(test({ -inf, min, less }));
76 VERIFY(test({ -snan, min, less }));
77 VERIFY(test({ -qnan, min, less }));
79 const Float vals[] = {
80 Float(0.0), denorm, smallest, Float(0.004), Float(0.2), Float(1.0),
81 Float(1) + epsilon<Float>, Float(1.1), Float(1e3), Float(123e4), Float(1e9),
82 max, inf, snan, qnan
85 for (auto& f : vals)
87 VERIFY(test({ f, -f, greater }));
88 VERIFY(test({ f, min, greater }, false));
89 for (auto& g : vals)
91 VERIFY(test({ f, g, &f <=> &g }, false));
92 VERIFY(test({ f, -g, greater }, false));
96 return true;
99 static_assert( test_fp<float>() );
100 static_assert( test_fp<double>() );
101 static_assert( test_fp<long double>() );