diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 8afd6756613..f6dbe562505 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1314,23 +1314,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Need to specialize pointer_traits because the primary template will // deduce element_type of __normal_iterator as T* rather than T. - template - struct pointer_traits<__gnu_cxx::__normal_iterator<_Iterator, _Container>> + template + struct pointer_traits<__gnu_cxx::__normal_iterator<_Tp*, _Container>> { - private: - using _Base = pointer_traits<_Iterator>; - - public: - using element_type = typename _Base::element_type; - using pointer = __gnu_cxx::__normal_iterator<_Iterator, _Container>; - using difference_type = typename _Base::difference_type; + using element_type = _Tp; + using pointer = __gnu_cxx::__normal_iterator<_Tp*, _Container>; + using difference_type = ptrdiff_t; - template - using rebind = __gnu_cxx::__normal_iterator<_Tp, _Container>; + template + using rebind = __gnu_cxx::__normal_iterator<_Up*, _Container>; - static pointer - pointer_to(element_type& __e) noexcept - { return pointer(_Base::pointer_to(__e)); } + static _GLIBCXX20_CONSTEXPR pointer + pointer_to(__make_not_void& __r) noexcept + { return pointer(std::addressof(__r)); } #if __cplusplus >= 202002L static element_type* diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 5584d06de5a..d2469574240 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -1013,6 +1013,45 @@ namespace __gnu_debug } // namespace __gnu_debug +#if __cplusplus >= 201103L +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + template + struct pointer_traits<__gnu_debug::_Safe_iterator< + __gnu_cxx::__normal_iterator<_Tp*, _Container>, _Sequence, + std::random_access_iterator_tag>> + { + private: + using __base_ptr = + __gnu_cxx::__normal_iterator<_Tp*, _Container>; + + public: + using element_type = _Tp; + using pointer = __gnu_debug::_Safe_iterator< + __gnu_cxx::__normal_iterator<_Tp*, _Container>, _Sequence, + std::random_access_iterator_tag>; + using difference_type = ptrdiff_t; + + template + using rebind = __gnu_debug::_Safe_iterator< + __gnu_cxx::__normal_iterator<_Up*, _Container>, _Sequence, + std::random_access_iterator_tag>; + + static pointer + pointer_to(element_type& __e) noexcept + { return { __base_ptr(std::addressof(__e)), nullptr }; } + +#if __cplusplus >= 202002L + static element_type* + to_address(const pointer& __p) noexcept + { return __p.base().base(); } +#endif + }; +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace +#endif + #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS diff --git a/libstdc++-v3/testsuite/20_util/pointer_traits/rebind.cc b/libstdc++-v3/testsuite/20_util/pointer_traits/rebind.cc index 159ea8f5294..b78e974d777 100644 --- a/libstdc++-v3/testsuite/20_util/pointer_traits/rebind.cc +++ b/libstdc++-v3/testsuite/20_util/pointer_traits/rebind.cc @@ -18,6 +18,7 @@ // { dg-do compile { target c++11 } } #include +#include using std::is_same; @@ -66,3 +67,13 @@ template }; // PR libstdc++/72793 specialization of pointer_traits is still well-formed: std::pointer_traits>::element_type e; + +static_assert(is_same::iterator, long>>::element_type, + long>::value, + "iterator rebind"); + +static_assert(is_same::const_iterator, long>>::element_type, + long>::value, + "const_iterator rebind"); diff --git a/libstdc++-v3/testsuite/24_iterators/normal_iterator/to_address.cc b/libstdc++-v3/testsuite/24_iterators/normal_iterator/to_address.cc index 510d627435f..433c803beb1 100644 --- a/libstdc++-v3/testsuite/24_iterators/normal_iterator/to_address.cc +++ b/libstdc++-v3/testsuite/24_iterators/normal_iterator/to_address.cc @@ -1,6 +1,9 @@ // { dg-do compile { target { c++11 } } } #include +#include #include char* p = std::__to_address(std::string("1").begin()); const char* q = std::__to_address(std::string("2").cbegin()); +int* r = std::__to_address(std::vector(1, 1).begin()); +const int* s = std::__to_address(std::vector(1, 1).cbegin());