public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r13-2884] libstdc++: Update std::pointer_traits to match new LWG 3545 wording Date: Mon, 26 Sep 2022 22:48:30 +0000 (GMT) [thread overview] Message-ID: <20220926224831.001A0385840C@sourceware.org> (raw) https://gcc.gnu.org/g:03cb9ed8dd603dbb77762ca948fc6381ba190731 commit r13-2884-g03cb9ed8dd603dbb77762ca948fc6381ba190731 Author: Jonathan Wakely <jwakely@redhat.com> Date: Mon Sep 26 18:59:45 2022 +0100 libstdc++: Update std::pointer_traits to match new LWG 3545 wording It was pointed out in recent LWG 3545 discussion that having a constrained partial specialization of std::pointer_traits can cause ambiguities with program-defined specializations. For example, the addition to the testcase has: template<typename P> requires std::derived_from<P, base_type struct std::pointer_traits<P>; This would be ambiguous with the library's own constrained partial specialization: template<typename Ptr> requires requires { typename Ptr::element_type; } struct std::pointer_traits<Ptr>; Neither specialization is more specialized than the other for a type that is derived from base_type and also has an element_type member. The solution is to remove the library's partial specialization, and do the check for Ptr::element_type in the __ptr_traits_elem helper (which is what we already do for !__cpp_concepts anyway). libstdc++-v3/ChangeLog: * include/bits/ptr_traits.h (__ptr_traits_elem) [__cpp_concepts]: Also define the __ptr_traits_elem class template for the concepts case. (pointer_traits<Ptr>): Remove constrained partial specialization. * testsuite/20_util/pointer_traits/lwg3545.cc: Check for ambiguitiy with program-defined partial specialization. Diff: --- libstdc++-v3/include/bits/ptr_traits.h | 20 ++++++-------------- .../testsuite/20_util/pointer_traits/lwg3545.cc | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h index ae8810706ab..71370ff4fc9 100644 --- a/libstdc++-v3/include/bits/ptr_traits.h +++ b/libstdc++-v3/include/bits/ptr_traits.h @@ -73,25 +73,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __replace_first_arg<_SomeTemplate<_Tp, _Types...>, _Up> { using type = _SomeTemplate<_Up, _Types...>; }; -#if __cpp_concepts - // When concepts are supported detection of _Ptr::element_type is done - // by a requires-clause, so __ptr_traits_elem_t only needs to do this: - template<typename _Ptr> - using __ptr_traits_elem_t = typename __get_first_arg<_Ptr>::type; -#else // Detect the element type of a pointer-like type. template<typename _Ptr, typename = void> struct __ptr_traits_elem : __get_first_arg<_Ptr> { }; // Use _Ptr::element_type if is a valid type. +#if __cpp_concepts + template<typename _Ptr> requires requires { typename _Ptr::element_type; } + struct __ptr_traits_elem<_Ptr, void> + { using type = typename _Ptr::element_type; }; +#else template<typename _Ptr> struct __ptr_traits_elem<_Ptr, __void_t<typename _Ptr::element_type>> { using type = typename _Ptr::element_type; }; +#endif template<typename _Ptr> using __ptr_traits_elem_t = typename __ptr_traits_elem<_Ptr>::type; -#endif /// @endcond @@ -182,13 +181,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct pointer_traits : __ptr_traits_impl<_Ptr, __ptr_traits_elem_t<_Ptr>> { }; -#if __cpp_concepts - template<typename _Ptr> requires requires { typename _Ptr::element_type; } - struct pointer_traits<_Ptr> - : __ptr_traits_impl<_Ptr, typename _Ptr::element_type> - { }; -#endif - /** * @brief Partial specialization for built-in pointers. * @headerfile memory diff --git a/libstdc++-v3/testsuite/20_util/pointer_traits/lwg3545.cc b/libstdc++-v3/testsuite/20_util/pointer_traits/lwg3545.cc index 08c3ed01b75..93c64a353bd 100644 --- a/libstdc++-v3/testsuite/20_util/pointer_traits/lwg3545.cc +++ b/libstdc++-v3/testsuite/20_util/pointer_traits/lwg3545.cc @@ -99,3 +99,20 @@ static_assert( is_same<pointer<Ctraits>, clever_ptr<char>>::value, "" ); static_assert( is_same<difference_type<Ctraits>, std::ptrdiff_t>::value, "" ); static_assert( is_same<rebind<Ctraits>, clever_ptr<short>>::value, "" ); static_assert( is_same<pointer_to<Ctraits>, clever_ptr<char>>::value, "" ); + +#ifdef __cpp_concepts +struct ptr_base { }; + +// Program-defined specialization must not be ambiguous with primary template. +template<typename P> requires std::derived_from<P, ptr_base> +struct std::pointer_traits<P> +{ + using element_type = int; + using difference_type = long; + using pointer = P; +}; + +struct Ptr : ptr_base { using element_type = int; }; + +using E = std::pointer_traits<Ptr>::element_type; +#endif
reply other threads:[~2022-09-26 22:48 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220926224831.001A0385840C@sourceware.org \ --to=redi@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).