1 // { dg-do compile { target c++20 } }
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__
22 template<> constexpr D epsilon
<D
> = std::numeric_limits
<double>::epsilon();
24 template<typename Float
>
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
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) {
61 // Check that each operand compares equal to itself.
62 if (std::strong_order(t
.lhs
, t
.lhs
) != std::strong_ordering::equal
)
64 if (std::strong_order(t
.rhs
, t
.rhs
) != std::strong_ordering::equal
)
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
),
87 VERIFY(test({ f
, -f
, greater
}));
88 VERIFY(test({ f
, min
, greater
}, false));
91 VERIFY(test({ f
, g
, &f
<=> &g
}, false));
92 VERIFY(test({ f
, -g
, greater
}, false));
99 static_assert( test_fp
<float>() );
100 static_assert( test_fp
<double>() );
101 static_assert( test_fp
<long double>() );