mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
libstdc++: Provide helpers to interoperate between __cmp_cat::_Ord and ordering types.
This patch adds two new internal helpers for ordering types: * __cmp_cat::__ord to retrieve an internal _Ord value, * __cmp_cat::__make<Ordering> to create an ordering from an _Ord value. Conversions between ordering types are now handled by __cmp_cat::__make. As a result, ordering types no longer need to befriend each other, only the new helpers. The __fp_weak_ordering implementation has also been simplified by: * using the new helpers to convert partial_ordering to weak_ordering, * using strong_ordering to weak_ordering conversion operator, for the __isnan_sign comparison, * removing the unused __cat local variable. Finally, the _Ncmp enum is removed, and the unordered enumerator is added to the existing _Ord enum. libstdc++-v3/ChangeLog: * libsupc++/compare (__cmp_cat::_Ord): Add unordered enumerator. (__cmp_cat::_Ncmp): Remove. (__cmp_cat::__ord, __cmp_cat::__make): Define. (partial_ordering::partial_ordering(__cmp_cat::_Ncmp)): Remove. (operator<=>(__cmp_cat::__unspec, partial_ordering)) (partial_ordering::unordered): Replace _Ncmp with _Ord. (std::partial_ordering, std::weak_ordering, std::strong_ordering): Befriend __ord and __make helpers, remove friend declartions for other orderings. (__compare::__fp_weak_ordering): Remove unused __cat variable. Simplify ordering conversions. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
This commit is contained in:
@@ -54,9 +54,24 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
using type = signed char;
|
||||
|
||||
enum class _Ord : type { equivalent = 0, less = -1, greater = 1 };
|
||||
enum class _Ord : type
|
||||
{
|
||||
equivalent = 0, less = -1, greater = 1,
|
||||
// value remains unchanged when negated
|
||||
unordered = -__SCHAR_MAX__ - 1
|
||||
};
|
||||
|
||||
enum class _Ncmp : type { unordered = -__SCHAR_MAX__ - 1 };
|
||||
template<typename _Ordering>
|
||||
[[__gnu__::__always_inline__]]
|
||||
constexpr _Ord
|
||||
__ord(_Ordering __o) noexcept
|
||||
{ return _Ord(__o._M_value); }
|
||||
|
||||
template<typename _Ordering>
|
||||
[[__gnu__::__always_inline__]]
|
||||
constexpr _Ordering
|
||||
__make(_Ord __o) noexcept
|
||||
{ return _Ordering(__o); }
|
||||
|
||||
struct __unspec
|
||||
{
|
||||
@@ -74,22 +89,19 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
: _M_value(__cmp_cat::type(__v))
|
||||
{ }
|
||||
|
||||
constexpr explicit
|
||||
partial_ordering(__cmp_cat::_Ncmp __v) noexcept
|
||||
: _M_value(__cmp_cat::type(__v))
|
||||
{ }
|
||||
|
||||
friend class weak_ordering;
|
||||
friend class strong_ordering;
|
||||
|
||||
[[__gnu__::__always_inline__]]
|
||||
constexpr __cmp_cat::type
|
||||
_M_reverse() const
|
||||
{
|
||||
// leaves _Ncmp::unordered unchanged
|
||||
// leaves _Ord::unordered unchanged
|
||||
return static_cast<__cmp_cat::type>(-_M_value);
|
||||
}
|
||||
|
||||
friend constexpr __cmp_cat::_Ord
|
||||
__cmp_cat::__ord<partial_ordering>(partial_ordering) noexcept;
|
||||
friend constexpr partial_ordering
|
||||
__cmp_cat::__make<partial_ordering>(__cmp_cat::_Ord) noexcept;
|
||||
|
||||
public:
|
||||
// valid values
|
||||
static const partial_ordering less;
|
||||
@@ -155,7 +167,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
[[nodiscard]]
|
||||
friend constexpr partial_ordering
|
||||
operator<=>(__cmp_cat::__unspec, partial_ordering __v) noexcept
|
||||
{ return partial_ordering(__cmp_cat::_Ncmp(__v._M_reverse())); }
|
||||
{ return partial_ordering(__cmp_cat::_Ord(__v._M_reverse())); }
|
||||
};
|
||||
|
||||
// valid values' definitions
|
||||
@@ -169,7 +181,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
partial_ordering::greater(__cmp_cat::_Ord::greater);
|
||||
|
||||
inline constexpr partial_ordering
|
||||
partial_ordering::unordered(__cmp_cat::_Ncmp::unordered);
|
||||
partial_ordering::unordered(__cmp_cat::_Ord::unordered);
|
||||
|
||||
class weak_ordering
|
||||
{
|
||||
@@ -179,7 +191,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
weak_ordering(__cmp_cat::_Ord __v) noexcept : _M_value(__cmp_cat::type(__v))
|
||||
{ }
|
||||
|
||||
friend class strong_ordering;
|
||||
friend constexpr __cmp_cat::_Ord
|
||||
__cmp_cat::__ord<weak_ordering>(weak_ordering) noexcept;
|
||||
friend constexpr weak_ordering
|
||||
__cmp_cat::__make<weak_ordering>(__cmp_cat::_Ord) noexcept;
|
||||
|
||||
public:
|
||||
// valid values
|
||||
@@ -189,7 +204,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr operator partial_ordering() const noexcept
|
||||
{ return partial_ordering(__cmp_cat::_Ord(_M_value)); }
|
||||
{ return __cmp_cat::__make<partial_ordering>(__cmp_cat::_Ord(_M_value)); }
|
||||
|
||||
// comparisons
|
||||
[[nodiscard]]
|
||||
@@ -271,6 +286,11 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
: _M_value(__cmp_cat::type(__v))
|
||||
{ }
|
||||
|
||||
friend constexpr __cmp_cat::_Ord
|
||||
__cmp_cat::__ord<strong_ordering>(strong_ordering) noexcept;
|
||||
friend constexpr strong_ordering
|
||||
__cmp_cat::__make<strong_ordering>(__cmp_cat::_Ord) noexcept;
|
||||
|
||||
public:
|
||||
// valid values
|
||||
static const strong_ordering less;
|
||||
@@ -280,11 +300,11 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr operator partial_ordering() const noexcept
|
||||
{ return partial_ordering(__cmp_cat::_Ord(_M_value)); }
|
||||
{ return __cmp_cat::__make<partial_ordering>(__cmp_cat::_Ord(_M_value)); }
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr operator weak_ordering() const noexcept
|
||||
{ return weak_ordering(__cmp_cat::_Ord(_M_value)); }
|
||||
{ return __cmp_cat::__make<weak_ordering>(__cmp_cat::_Ord(_M_value)); }
|
||||
|
||||
// comparisons
|
||||
[[nodiscard]]
|
||||
@@ -584,26 +604,9 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
constexpr weak_ordering
|
||||
__fp_weak_ordering(_Tp __e, _Tp __f)
|
||||
{
|
||||
// Returns an integer with the same sign as the argument, and magnitude
|
||||
// indicating the classification: zero=1 subnorm=2 norm=3 inf=4 nan=5
|
||||
auto __cat = [](_Tp __fp) -> int {
|
||||
const int __sign = __builtin_signbit(__fp) ? -1 : 1;
|
||||
if (__builtin_isnormal(__fp))
|
||||
return (__fp == 0 ? 1 : 3) * __sign;
|
||||
if (__builtin_isnan(__fp))
|
||||
return 5 * __sign;
|
||||
if (int __inf = __builtin_isinf_sign(__fp))
|
||||
return 4 * __inf;
|
||||
return 2 * __sign;
|
||||
};
|
||||
|
||||
auto __po = __e <=> __f;
|
||||
if (is_lt(__po))
|
||||
return weak_ordering::less;
|
||||
else if (is_gt(__po))
|
||||
return weak_ordering::greater;
|
||||
else if (__po == partial_ordering::equivalent)
|
||||
return weak_ordering::equivalent;
|
||||
auto __po = __cmp_cat::__ord(__e <=> __f);
|
||||
if (__po != __cmp_cat::_Ord::unordered)
|
||||
return __cmp_cat::__make<weak_ordering>(__po);
|
||||
else // unordered, at least one argument is NaN
|
||||
{
|
||||
// return -1 for negative nan, +1 for positive nan, 0 otherwise.
|
||||
@@ -612,13 +615,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||
? __builtin_signbit(__fp) ? -1 : 1
|
||||
: 0;
|
||||
};
|
||||
auto __ord = __isnan_sign(__e) <=> __isnan_sign(__f);
|
||||
if (is_eq(__ord))
|
||||
return weak_ordering::equivalent;
|
||||
else if (is_lt(__ord))
|
||||
return weak_ordering::less;
|
||||
else
|
||||
return weak_ordering::greater;
|
||||
return __isnan_sign(__e) <=> __isnan_sign(__f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user