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
>>>
>>>

Reply via email to