On Mon, Oct 13, 2025 at 6:42 AM 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.
> ---
>
LGTM

>  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