]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/libsupc++/compare
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / libsupc++ / compare
index 3c22d9addf178407086908f2fc547f5305417220..686aa6d218fe54646a21d29e882d729f00cc8577 100644 (file)
@@ -1,6 +1,6 @@
 // -*- C++ -*- operator<=> three-way comparison support.
 
-// Copyright (C) 2019-2022 Free Software Foundation, Inc.
+// Copyright (C) 2019-2024 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
 
 #pragma GCC system_header
 
-#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
+#define __glibcxx_want_three_way_comparison
+#include <bits/version.h>
 
-#pragma GCC visibility push(default)
+#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
 
 #include <concepts>
 
-#if __cpp_lib_concepts
-# define __cpp_lib_three_way_comparison 201907L
-#endif
-
-namespace std
+namespace std _GLIBCXX_VISIBILITY(default)
 {
   // [cmp.categories], comparison category types
 
@@ -56,7 +53,7 @@ namespace std
 
     struct __unspec
     {
-      constexpr __unspec(__unspec*) noexcept { }
+      consteval __unspec(__unspec*) noexcept { }
     };
   }
 
@@ -450,7 +447,8 @@ namespace std
     using common_comparison_category_t
       = typename common_comparison_category<_Ts...>::type;
 
-#if __cpp_lib_concepts
+#if __cpp_lib_three_way_comparison >= 201907L
+  // C++ >= 20 && impl_3way_comparison >= 201907 && lib_concepts
   namespace __detail
   {
     template<typename _Tp, typename _Cat>
@@ -568,7 +566,9 @@ namespace std
     using is_transparent = void;
   };
 
-  namespace __cmp_cust
+  /// @cond undocumented
+  // Namespace for helpers for the <compare> customization points.
+  namespace __compare
   {
     template<floating_point _Tp>
       constexpr weak_ordering
@@ -612,6 +612,8 @@ namespace std
          }
       }
 
+    void strong_order() = delete;
+
     template<typename _Tp, typename _Up>
       concept __adl_strong = requires(_Tp&& __t, _Up&& __u)
        {
@@ -619,6 +621,8 @@ namespace std
                                       static_cast<_Up&&>(__u)));
        };
 
+    void weak_order() = delete;
+
     template<typename _Tp, typename _Up>
       concept __adl_weak = requires(_Tp&& __t, _Up&& __u)
        {
@@ -626,6 +630,8 @@ namespace std
                                   static_cast<_Up&&>(__u)));
        };
 
+    void partial_order() = delete;
+
     template<typename _Tp, typename _Up>
       concept __adl_partial = requires(_Tp&& __t, _Up&& __u)
        {
@@ -674,15 +680,29 @@ namespace std
        _X86_80bit,  // x86 80-bit extended precision
        _M68k_80bit, // m68k 80-bit extended precision
        _Dbldbl, // IBM 128-bit double-double
-       // TODO: _Bfloat16,
+       _Bfloat16,   // std::bfloat16_t
       };
 
+#ifndef __cpp_using_enum
+      // XXX Remove these once 'using enum' support is ubiquitous.
+      static constexpr _Fp_fmt _Binary16 = _Fp_fmt::_Binary16;
+      static constexpr _Fp_fmt _Binary32 = _Fp_fmt::_Binary32;
+      static constexpr _Fp_fmt _Binary64 = _Fp_fmt::_Binary64;
+      static constexpr _Fp_fmt _Binary128 = _Fp_fmt::_Binary128;
+      static constexpr _Fp_fmt _X86_80bit = _Fp_fmt::_X86_80bit;
+      static constexpr _Fp_fmt _M68k_80bit = _Fp_fmt::_M68k_80bit;
+      static constexpr _Fp_fmt _Dbldbl = _Fp_fmt::_Dbldbl;
+      static constexpr _Fp_fmt _Bfloat16 = _Fp_fmt::_Bfloat16;
+#endif
+
       // Identify the format used by a floating-point type.
       template<typename _Tp>
        static consteval _Fp_fmt
        _S_fp_fmt() noexcept
        {
+#ifdef __cpp_using_enum
          using enum _Fp_fmt;
+#endif
 
          // Identify these formats first, then assume anything else is IEEE.
          // N.B. ARM __fp16 alternative format can be handled as binary16.
@@ -703,6 +723,10 @@ namespace std
          if constexpr (__is_same(_Tp, __float80))
            return _X86_80bit;
 #endif
+#ifdef __STDCPP_BFLOAT16_T__
+         if constexpr (__is_same(_Tp, decltype(0.0bf16)))
+           return _Bfloat16;
+#endif
 
          constexpr int __width = sizeof(_Tp) * __CHAR_BIT__;
 
@@ -810,7 +834,9 @@ namespace std
            return __builtin_bit_cast(int16_t, __val);
          else
            {
+#ifdef __cpp_using_enum
              using enum _Fp_fmt;
+#endif
              constexpr auto __fmt = _S_fp_fmt<_Tp>();
              if constexpr (__fmt == _X86_80bit || __fmt == _M68k_80bit)
                {
@@ -844,8 +870,16 @@ namespace std
        _S_fp_cmp(_Tp __x, _Tp __y) noexcept
        {
 #ifdef __vax__
-         // VAX format has no NaN, only "excess" for Inf, so totally ordered.
-         return __builtin_bit_cast(strong_ordering, __x <=> __y);
+         if (__builtin_isnan(__x) || __builtin_isnan(__y))
+           {
+             int __ix = (bool) __builtin_isnan(__x);
+             int __iy = (bool) __builtin_isnan(__y);
+             __ix *= __builtin_signbit(__x) ? -1 : 1;
+             __iy *= __builtin_signbit(__y) ? -1 : 1;
+             return __ix <=> __iy;
+           }
+         else
+           return __builtin_bit_cast(strong_ordering, __x <=> __y);
 #endif
 
          auto __ix = _S_fp_bits(__x);
@@ -854,7 +888,9 @@ namespace std
          if (__ix == __iy)
            return strong_ordering::equal; // All bits are equal, we're done.
 
+#ifdef __cpp_using_enum
          using enum _Fp_fmt;
+#endif
          constexpr auto __fmt = _S_fp_fmt<_Tp>();
 
          if constexpr (__fmt == _Dbldbl) // double-double
@@ -972,7 +1008,7 @@ namespace std
        noexcept(_S_noexcept<_Tp, _Up>())
        {
          if constexpr (floating_point<decay_t<_Tp>>)
-           return __cmp_cust::__fp_weak_ordering(__e, __f);
+           return __compare::__fp_weak_ordering(__e, __f);
          else if constexpr (__adl_weak<_Tp, _Up>)
            return weak_ordering(weak_order(static_cast<_Tp&&>(__e),
                                            static_cast<_Up&&>(__f)));
@@ -1144,27 +1180,29 @@ namespace std
              : partial_ordering::unordered;
        }
     };
-  } // namespace __cmp_cust
+  } // namespace @endcond
 
   // [cmp.alg], comparison algorithms
-  inline namespace __cmp_alg
+
+  inline namespace _Cpo
   {
-    inline constexpr __cmp_cust::_Strong_order strong_order{};
+    inline constexpr __compare::_Strong_order strong_order{};
 
-    inline constexpr __cmp_cust::_Weak_order weak_order{};
+    inline constexpr __compare::_Weak_order weak_order{};
 
-    inline constexpr __cmp_cust::_Partial_order partial_order{};
+    inline constexpr __compare::_Partial_order partial_order{};
 
-    inline constexpr __cmp_cust::_Strong_fallback
-    compare_strong_order_fallback{};
+    inline constexpr __compare::_Strong_fallback
+      compare_strong_order_fallback{};
 
-    inline constexpr __cmp_cust::_Weak_fallback
-    compare_weak_order_fallback{};
+    inline constexpr __compare::_Weak_fallback
+      compare_weak_order_fallback{};
 
-    inline constexpr __cmp_cust::_Partial_fallback
-    compare_partial_order_fallback{};
+    inline constexpr __compare::_Partial_fallback
+      compare_partial_order_fallback{};
   }
 
+  /// @cond undocumented
   namespace __detail
   {
     // [expos.only.func] synth-three-way
@@ -1211,11 +1249,10 @@ namespace std
        = decltype(__detail::__synth3way(std::declval<_Tp&>(),
                                         std::declval<_Up&>()));
   } // namespace __detail
-#endif // concepts
+  /// @endcond
+#endif // __cpp_lib_three_way_comparison >= 201907L
 } // namespace std
 
-#pragma GCC visibility pop
-
 #endif // C++20
 
 #endif // _COMPARE