On Mon, 13 Oct 2025, 09:00 Jonathan Wakely, <[email protected]> wrote:

>
>
> On Mon, 13 Oct 2025, 05:42 Patrick Palka, <[email protected]> wrote:
>
>> We implement this paper as a DR against C++20 (as do MSVC and libc++).
>>
>>         PR libstdc++/120446
>>
>> libstdc++-v3/ChangeLog:
>>
>>         * include/bits/version.def (common_reference): New.
>>         * include/bits/version.h: Regenerate.
>>         * include/std/type_traits (__glibcxx_want_common_reference):
>>         Define.
>>         (__common_reference_impl<T1, T2, 1>): Add pointer convertibility
>>         constraints as per P2655R3.
>>         * testsuite/20_util/common_reference/p2655r3.cc: New test.
>>
>
> ok for trunk
>

This looks safe for backports too, do we want to do that?



>
> ---
>>  libstdc++-v3/include/bits/version.def             |  8 ++++++++
>>  libstdc++-v3/include/bits/version.h               | 10 ++++++++++
>>  libstdc++-v3/include/std/type_traits              |  7 +++++++
>>  .../testsuite/20_util/common_reference/p2655r3.cc | 15 +++++++++++++++
>>  4 files changed, 40 insertions(+)
>>  create mode 100644
>> libstdc++-v3/testsuite/20_util/common_reference/p2655r3.cc
>>
>> diff --git a/libstdc++-v3/include/bits/version.def
>> b/libstdc++-v3/include/bits/version.def
>> index 83f1817bf8e4..e2b064e09b1e 100644
>> --- a/libstdc++-v3/include/bits/version.def
>> +++ b/libstdc++-v3/include/bits/version.def
>> @@ -1793,6 +1793,14 @@ ftms = {
>>    };
>>  };
>>
>> +ftms = {
>> +  name = common_reference;
>> +  values = {
>> +    v = 202302;
>> +    cxxmin = 20; // We treat P2655R3 as a DR against C++20.
>> +  };
>> +};
>> +
>>  ftms = {
>>    name = formatters;
>>    values = {
>> diff --git a/libstdc++-v3/include/bits/version.h
>> b/libstdc++-v3/include/bits/version.h
>> index 0d6692d244a6..4581519d3a7d 100644
>> --- a/libstdc++-v3/include/bits/version.h
>> +++ b/libstdc++-v3/include/bits/version.h
>> @@ -2001,6 +2001,16 @@
>>  #endif /* !defined(__cpp_lib_flat_set) */
>>  #undef __glibcxx_want_flat_set
>>
>> +#if !defined(__cpp_lib_common_reference)
>> +# if (__cplusplus >= 202002L)
>> +#  define __glibcxx_common_reference 202302L
>> +#  if defined(__glibcxx_want_all) ||
>> defined(__glibcxx_want_common_reference)
>> +#   define __cpp_lib_common_reference 202302L
>> +#  endif
>> +# endif
>> +#endif /* !defined(__cpp_lib_common_reference) &&
>> defined(__glibcxx_want_common_reference) */
>> +#undef __glibcxx_want_common_reference
>> +
>>  #if !defined(__cpp_lib_formatters)
>>  # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
>>  #  define __glibcxx_formatters 202302L
>> diff --git a/libstdc++-v3/include/std/type_traits
>> b/libstdc++-v3/include/std/type_traits
>> index 8b5110464e50..47cbf21b4c1d 100644
>> --- a/libstdc++-v3/include/std/type_traits
>> +++ b/libstdc++-v3/include/std/type_traits
>> @@ -41,6 +41,7 @@
>>
>>  #define __glibcxx_want_bool_constant
>>  #define __glibcxx_want_bounded_array_traits
>> +#define __glibcxx_want_common_reference
>>  #define __glibcxx_want_constant_wrapper
>>  #define __glibcxx_want_has_unique_object_representations
>>  #define __glibcxx_want_integral_constant_callable
>> @@ -4223,6 +4224,12 @@ template<typename _Ret, typename _Fn, typename...
>> _Args>
>>    template<typename _Tp1, typename _Tp2>
>>      requires is_reference_v<_Tp1> && is_reference_v<_Tp2>
>>        && requires { typename __common_ref<_Tp1, _Tp2>; }
>> +#if __cpp_lib_common_reference // C++ >= 20
>> +      && is_convertible_v<add_pointer_t<_Tp1>,
>> +                         add_pointer_t<__common_ref<_Tp1, _Tp2>>>
>> +      && is_convertible_v<add_pointer_t<_Tp2>,
>> +                         add_pointer_t<__common_ref<_Tp1, _Tp2>>>
>> +#endif
>>      struct __common_reference_impl<_Tp1, _Tp2, 1>
>>      { using type = __common_ref<_Tp1, _Tp2>; };
>>
>> diff --git a/libstdc++-v3/testsuite/20_util/common_reference/p2655r3.cc
>> b/libstdc++-v3/testsuite/20_util/common_reference/p2655r3.cc
>> new file mode 100644
>> index 000000000000..4188dd2fb29f
>> --- /dev/null
>> +++ b/libstdc++-v3/testsuite/20_util/common_reference/p2655r3.cc
>> @@ -0,0 +1,15 @@
>> +// P2655R3 - common_reference_t of reference_wrapper Should Be a
>> Reference Type
>> +// Implemented as a DR against C++20
>> +// { dg-do compile { target c++20 } }
>> +
>> +#include <type_traits>
>> +
>> +#if __cpp_lib_common_reference != 202302L
>> +# error "Feature-test macro __cpp_lib_common_reference has wrong value
>> in <type_traits>"
>> +#endif
>> +
>> +struct A { };
>> +struct B { operator A&() const; };
>> +
>> +static_assert( std::is_same_v<std::common_reference_t<A&, const B&>, A&>
>> );
>> +static_assert( std::is_same_v<std::common_reference_t<const B&, A&>, A&>
>> );
>> --
>> 2.51.0.491.g4b71b29477
>>
>>

Reply via email to