https://gcc.gnu.org/g:95f5abd112020f86aba51ed35a6d517fb09682fe

commit r15-10609-g95f5abd112020f86aba51ed35a6d517fb09682fe
Author: Patrick Palka <[email protected]>
Date:   Fri Dec 5 13:43:26 2025 -0500

    libstdc++: Consolidate bullet 1 __common_reference_impl partial specs
    
    ... and in passing use requires-clauses instead of void_t based SFINAE.
    This is a non-functional change that'll simplify implementing the
    P2655R3 change to common_reference.
    
            PR c++/120446
    
    libstdc++-v3/ChangeLog:
    
            * include/std/type_traits (__common_reference_impl): Rewrite
            partial specializations to use requires-clause instead of
            an additional void_t template parameter.  Consolidate the
            partial specializations corresponding to bullet 1.
    
    Reviewed-by: Tomasz KamiƄski <[email protected]>
    Reviewed-by: Jonathan Wakely <[email protected]>
    (cherry picked from commit cbdbbdd1fccfd789e6fbcb37b1b602bb7482de4b)

Diff:
---
 libstdc++-v3/include/std/type_traits | 40 ++++++++++++------------------------
 1 file changed, 13 insertions(+), 27 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 676cdf2d7e66..0a402617c52d 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -4113,7 +4113,7 @@ template<typename _Ret, typename _Fn, typename... _Args>
     { using type = _Tp0; };
 
   /// @cond undocumented
-  template<typename _Tp1, typename _Tp2, int _Bullet = 1, typename = void>
+  template<typename _Tp1, typename _Tp2, int _Bullet = 1>
     struct __common_reference_impl
     : __common_reference_impl<_Tp1, _Tp2, _Bullet + 1>
     { };
@@ -4126,46 +4126,32 @@ template<typename _Ret, typename _Fn, typename... _Args>
 
   // If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, 
...
   template<typename _Tp1, typename _Tp2>
-    struct __common_reference_impl<_Tp1&, _Tp2&, 1,
-                                  void_t<__common_ref<_Tp1&, _Tp2&>>>
-    { using type = __common_ref<_Tp1&, _Tp2&>; };
-
-  template<typename _Tp1, typename _Tp2>
-    struct __common_reference_impl<_Tp1&&, _Tp2&&, 1,
-                                  void_t<__common_ref<_Tp1&&, _Tp2&&>>>
-    { using type = __common_ref<_Tp1&&, _Tp2&&>; };
-
-  template<typename _Tp1, typename _Tp2>
-    struct __common_reference_impl<_Tp1&, _Tp2&&, 1,
-                                  void_t<__common_ref<_Tp1&, _Tp2&&>>>
-    { using type = __common_ref<_Tp1&, _Tp2&&>; };
-
-  template<typename _Tp1, typename _Tp2>
-    struct __common_reference_impl<_Tp1&&, _Tp2&, 1,
-                                  void_t<__common_ref<_Tp1&&, _Tp2&>>>
-    { using type = __common_ref<_Tp1&&, _Tp2&>; };
+    requires is_reference_v<_Tp1> && is_reference_v<_Tp2>
+      && requires { typename __common_ref<_Tp1, _Tp2>; }
+    struct __common_reference_impl<_Tp1, _Tp2, 1>
+    { using type = __common_ref<_Tp1, _Tp2>; };
 
   // Otherwise, if basic_common_reference<...>::type is well-formed, ...
   template<typename _Tp1, typename _Tp2>
-    struct __common_reference_impl<_Tp1, _Tp2, 2,
-                                  void_t<__basic_common_ref<_Tp1, _Tp2>>>
+    requires requires { typename __basic_common_ref<_Tp1, _Tp2>; }
+    struct __common_reference_impl<_Tp1, _Tp2, 2>
     { using type = __basic_common_ref<_Tp1, _Tp2>; };
 
   // Otherwise, if COND-RES(T1, T2) is well-formed, ...
   template<typename _Tp1, typename _Tp2>
-    struct __common_reference_impl<_Tp1, _Tp2, 3,
-                                  void_t<__cond_res<_Tp1, _Tp2>>>
+    requires requires { typename __cond_res<_Tp1, _Tp2>; }
+    struct __common_reference_impl<_Tp1, _Tp2, 3>
     { using type = __cond_res<_Tp1, _Tp2>; };
 
   // Otherwise, if common_type_t<T1, T2> is well-formed, ...
   template<typename _Tp1, typename _Tp2>
-    struct __common_reference_impl<_Tp1, _Tp2, 4,
-                                  void_t<common_type_t<_Tp1, _Tp2>>>
+    requires requires { typename common_type_t<_Tp1, _Tp2>; }
+    struct __common_reference_impl<_Tp1, _Tp2, 4>
     { using type = common_type_t<_Tp1, _Tp2>; };
 
   // Otherwise, there shall be no member type.
   template<typename _Tp1, typename _Tp2>
-    struct __common_reference_impl<_Tp1, _Tp2, 5, void>
+    struct __common_reference_impl<_Tp1, _Tp2, 5>
     { };
 
   // Otherwise, if sizeof...(T) is greater than two, ...
@@ -4184,7 +4170,7 @@ template<typename _Ret, typename _Fn, typename... _Args>
     { };
   /// @endcond
 
-#endif // C++2a
+#endif // C++20
 
   /// @} group metaprogramming

Reply via email to