From cbdbbdd1fccfd789e6fbcb37b1b602bb7482de4b Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Fri, 5 Dec 2025 13:43:26 -0500 Subject: [PATCH] libstdc++: Consolidate bullet 1 __common_reference_impl partial specs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit ... 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 Reviewed-by: Jonathan Wakely --- 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 5c09fac8662..418e2187779 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -4225,7 +4225,7 @@ template { using type = _Tp0; }; /// @cond undocumented - template + template struct __common_reference_impl : __common_reference_impl<_Tp1, _Tp2, _Bullet + 1> { }; @@ -4238,46 +4238,32 @@ template // If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, ... template - struct __common_reference_impl<_Tp1&, _Tp2&, 1, - void_t<__common_ref<_Tp1&, _Tp2&>>> - { using type = __common_ref<_Tp1&, _Tp2&>; }; - - template - struct __common_reference_impl<_Tp1&&, _Tp2&&, 1, - void_t<__common_ref<_Tp1&&, _Tp2&&>>> - { using type = __common_ref<_Tp1&&, _Tp2&&>; }; - - template - struct __common_reference_impl<_Tp1&, _Tp2&&, 1, - void_t<__common_ref<_Tp1&, _Tp2&&>>> - { using type = __common_ref<_Tp1&, _Tp2&&>; }; - - template - 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 - 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 - 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 is well-formed, ... template - struct __common_reference_impl<_Tp1, _Tp2, 4, - void_t>> + 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 - struct __common_reference_impl<_Tp1, _Tp2, 5, void> + struct __common_reference_impl<_Tp1, _Tp2, 5> { }; // Otherwise, if sizeof...(T) is greater than two, ... @@ -4296,7 +4282,7 @@ template { }; /// @endcond -#endif // C++2a +#endif // C++20 #if __cplusplus >= 201103L // Stores a tuple of indices. Used by tuple and pair, and by bind() to -- 2.47.3