On Mon, Oct 13, 2025 at 10:07 AM Jonathan Wakely <[email protected]> wrote:
> > > On Mon, 13 Oct 2025, 08:26 Tomasz Kaminski, <[email protected]> wrote: > >> >> >> On Mon, Oct 13, 2025 at 6:42 AM Patrick Palka <[email protected]> wrote: >> >>> ... 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. >>> --- >>> >> LGTM, I believe nothing changed. >> > > ... including the "C++2a" comment tweak, but nevermind, still ok for > trunk. > Ah, yeah. Still could be fixed before pushing. > > > > > libstdc++-v3/include/std/type_traits | 38 +++++++++------------------- >>> 1 file changed, 12 insertions(+), 26 deletions(-) >>> >>> diff --git a/libstdc++-v3/include/std/type_traits >>> b/libstdc++-v3/include/std/type_traits >>> index 77ebb7e2c2f9..8b5110464e50 100644 >>> --- a/libstdc++-v3/include/std/type_traits >>> +++ b/libstdc++-v3/include/std/type_traits >>> @@ -4208,7 +4208,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> >>> { }; >>> @@ -4221,46 +4221,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, ... >>> -- >>> 2.51.0.491.g4b71b29477 >>> >>>
