diff options
-rw-r--r-- | libstdc++-v3/include/bits/ptr_traits.h | 20 | ||||
-rw-r--r-- | libstdc++-v3/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 ae88107..71370ff 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 08c3ed0..93c64a3 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 |