aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Kamiński <tkaminsk@redhat.com>2025-08-28 11:10:05 +0200
committerTomasz Kamiński <tkaminsk@redhat.com>2025-08-28 14:40:48 +0200
commitfcb5cd8e9483daafd6f786f3b607028cb1293ce7 (patch)
treef23827a47d8a5e8dfb427cdceba190730b78ac33
parent10418a6cbd34e0a4081f6dcdf8c36a9592aaf318 (diff)
downloadgcc-fcb5cd8e9483daafd6f786f3b607028cb1293ce7.zip
gcc-fcb5cd8e9483daafd6f786f3b607028cb1293ce7.tar.gz
gcc-fcb5cd8e9483daafd6f786f3b607028cb1293ce7.tar.bz2
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>
-rw-r--r--libstdc++-v3/libsupc++/compare85
1 files changed, 41 insertions, 44 deletions
diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare
index ef0f037..ca7c909 100644
--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -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);
}
}