diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 004d767224d..f7e851718c1 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1294,13 +1294,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: using _Base = pointer_traits<_Iterator>; + template + using __base_rebind = typename _Base::template rebind<_Tp>; + public: using element_type = typename _Base::element_type; using pointer = __gnu_cxx::__normal_iterator<_Iterator, _Container>; using difference_type = typename _Base::difference_type; template - using rebind = __gnu_cxx::__normal_iterator<_Tp, _Container>; + using rebind = + __gnu_cxx::__normal_iterator<__base_rebind<_Tp>, _Container>; static pointer pointer_to(element_type& __e) noexcept diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 5584d06de5a..5461d2b342f 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -1013,6 +1013,44 @@ 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<_Iterator, _Sequence, + _Category>> + { + private: + using _Base = pointer_traits<_Iterator>; + + template + using __base_rebind = typename _Base::template rebind<_Tp>; + + public: + using element_type = typename _Base::element_type; + using pointer = + __gnu_debug::_Safe_iterator<_Iterator, _Sequence, _Category>; + using difference_type = typename _Base::difference_type; + + template + using rebind = + __gnu_debug::_Safe_iterator<__base_rebind<_Tp>, _Sequence, _Category>; + + static pointer + pointer_to(element_type& __e) noexcept + { return pointer(_Base::pointer_to(__e), nullptr); } + +#if __cplusplus >= 202002L + static element_type* + to_address(pointer __p) noexcept + { return __p.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());