https://gcc.gnu.org/g:0ea9d760fbf44c6f50c50a4e259d3ef2c756606c

commit r16-5624-g0ea9d760fbf44c6f50c50a4e259d3ef2c756606c
Author: Tomasz Kamiński <[email protected]>
Date:   Thu Nov 20 11:23:30 2025 +0100

    libstdc++: Make C++20s operator wrappers operator() static.
    
    The operator() for function objects introduced in C++20 (e.g., 
std::identity,
    std::compare_three_way, std::ranges::equal) is now defined as static.
    Although static operator() is a C++23 feature, it is supported in C++20 by
    both GCC and clang (since their support was added in clang-16).
    
    This change is not user-observable, as all affected operators are template
    functions. Taking the address of such an operator requires casting to a 
pointer
    to member function with a specific signature. The exact signature is 
unspecified
    per C++20 [member.functions] p2 (e.g. due to potential parameters with 
default
    arguments).
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/ranges_cmp.h (std::identity::operator()):
            (ranges::equal_to:operator(), ranges::not_equal_to:operator())
            (ranges::greater::operator(), ranges::greater_equal::operator())
            (ranges::less::operator(), ranges::less_equal::operator()):
            Declare as static.
            * libsupc++/compare (std::compare_three_way::operator()):
            Declare as static.
    
    Reviewed-by: Jonathan Wakely <[email protected]>
    Reviewed-by: Patrick Palka <[email protected]>
    Signed-off-by: Tomasz Kamiński <[email protected]>

Diff:
---
 libstdc++-v3/include/bits/ranges_cmp.h | 34 ++++++++++++++++++++--------------
 libstdc++-v3/libsupc++/compare         |  7 +++++--
 2 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/libstdc++-v3/include/bits/ranges_cmp.h 
b/libstdc++-v3/include/bits/ranges_cmp.h
index cd5f7b8b37a2..a53cd5645635 100644
--- a/libstdc++-v3/include/bits/ranges_cmp.h
+++ b/libstdc++-v3/include/bits/ranges_cmp.h
@@ -46,11 +46,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// [func.identity] The identity function.
   struct identity
   {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++23-extensions" // static operator()
     template<typename _Tp>
       [[nodiscard]]
-      constexpr _Tp&&
-      operator()(_Tp&& __t) const noexcept
+      static constexpr _Tp&&
+      operator()(_Tp&& __t) noexcept
       { return std::forward<_Tp>(__t); }
+#pragma GCC diagnostic pop
 
     using is_transparent = __is_transparent;
   };
@@ -79,13 +82,15 @@ namespace ranges
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 3530 BUILTIN-PTR-MEOW should not opt the type out of syntactic checks
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++23-extensions" // static operator()
   /// ranges::equal_to function object type.
   struct equal_to
   {
     template<typename _Tp, typename _Up>
       requires equality_comparable_with<_Tp, _Up>
-      constexpr bool
-      operator()(_Tp&& __t, _Up&& __u) const
+      static constexpr bool
+      operator()(_Tp&& __t, _Up&& __u)
       noexcept(noexcept(std::declval<_Tp>() == std::declval<_Up>()))
       { return std::forward<_Tp>(__t) == std::forward<_Up>(__u); }
 
@@ -97,8 +102,8 @@ namespace ranges
   {
     template<typename _Tp, typename _Up>
       requires equality_comparable_with<_Tp, _Up>
-      constexpr bool
-      operator()(_Tp&& __t, _Up&& __u) const
+      static constexpr bool
+      operator()(_Tp&& __t, _Up&& __u)
       noexcept(noexcept(std::declval<_Tp>() == std::declval<_Up>()))
       { return !equal_to{}(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
 
@@ -110,8 +115,8 @@ namespace ranges
   {
     template<typename _Tp, typename _Up>
       requires totally_ordered_with<_Tp, _Up>
-      constexpr bool
-      operator()(_Tp&& __t, _Up&& __u) const
+      static constexpr bool
+      operator()(_Tp&& __t, _Up&& __u)
       noexcept(noexcept(std::declval<_Tp>() < std::declval<_Up>()))
       {
        if constexpr (__detail::__less_builtin_ptr_cmp<_Tp, _Up>)
@@ -137,8 +142,8 @@ namespace ranges
   {
     template<typename _Tp, typename _Up>
       requires totally_ordered_with<_Tp, _Up>
-      constexpr bool
-      operator()(_Tp&& __t, _Up&& __u) const
+      static constexpr bool
+      operator()(_Tp&& __t, _Up&& __u)
       noexcept(noexcept(std::declval<_Up>() < std::declval<_Tp>()))
       { return less{}(std::forward<_Up>(__u), std::forward<_Tp>(__t)); }
 
@@ -150,8 +155,8 @@ namespace ranges
   {
     template<typename _Tp, typename _Up>
       requires totally_ordered_with<_Tp, _Up>
-      constexpr bool
-      operator()(_Tp&& __t, _Up&& __u) const
+      static constexpr bool
+      operator()(_Tp&& __t, _Up&& __u)
       noexcept(noexcept(std::declval<_Tp>() < std::declval<_Up>()))
       { return !less{}(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
 
@@ -163,13 +168,14 @@ namespace ranges
   {
     template<typename _Tp, typename _Up>
       requires totally_ordered_with<_Tp, _Up>
-      constexpr bool
-      operator()(_Tp&& __t, _Up&& __u) const
+      static constexpr bool
+      operator()(_Tp&& __t, _Up&& __u)
       noexcept(noexcept(std::declval<_Up>() < std::declval<_Tp>()))
       { return !less{}(std::forward<_Up>(__u), std::forward<_Tp>(__t)); }
 
     using is_transparent = __is_transparent;
   };
+#pragma GCC diagnostic pop
 
 } // namespace ranges
 #endif // __glibcxx_ranges
diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare
index 458b47c3fcab..08f2b2ba47ed 100644
--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -573,10 +573,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
   // [cmp.object], typename compare_three_way
   struct compare_three_way
   {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++23-extensions" // static operator()
     template<typename _Tp, typename _Up>
       requires three_way_comparable_with<_Tp, _Up>
-      constexpr auto
-      operator() [[nodiscard]] (_Tp&& __t, _Up&& __u) const
+      static constexpr auto
+      operator() [[nodiscard]] (_Tp&& __t, _Up&& __u)
       noexcept(noexcept(std::declval<_Tp>() <=> std::declval<_Up>()))
       {
        if constexpr (__detail::__3way_builtin_ptr_cmp<_Tp, _Up>)
@@ -592,6 +594,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
        else
          return static_cast<_Tp&&>(__t) <=> static_cast<_Up&&>(__u);
       }
+#pragma GCC diagnostic pop
 
     using is_transparent = void;
   };

Reply via email to