diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 8afd6756613..594d4d5b65f 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1017,6 +1017,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template class __normal_iterator { +#if __cplusplus >= 201103L + using __ite_ptr_traits = std::pointer_traits<_Iterator>; + + template + using __ite_rebind = typename __ite_ptr_traits::template rebind<_Tp>; +#endif + protected: _Iterator _M_current; @@ -1036,6 +1043,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename __traits_type::reference reference; typedef typename __traits_type::pointer pointer; +#if __cplusplus >= 201103L + using element_type = typename __ite_ptr_traits::element_type; + + template + using rebind = __normal_iterator<__ite_rebind<_Up>, _Container>; + + static __normal_iterator + pointer_to(element_type& __e) + { return { __ite_ptr_traits::pointer_to(__e) }; } +#endif + #if __cplusplus > 201703L && __cpp_lib_concepts using iterator_concept = std::__detail::__iter_concept<_Iterator>; #endif @@ -1311,34 +1329,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __it.base(); } #if __cplusplus >= 201103L - - // 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>> - { - 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; - - template - using rebind = __gnu_cxx::__normal_iterator<_Tp, _Container>; - - static pointer - pointer_to(element_type& __e) noexcept - { return pointer(_Base::pointer_to(__e)); } - -#if __cplusplus >= 202002L - static element_type* - to_address(pointer __p) noexcept - { return __p.base(); } -#endif - }; - /** * @addtogroup iterators * @{ diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 5584d06de5a..b175c9e4a31 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -653,6 +653,13 @@ namespace __gnu_debug : public _Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag> { +#if __cplusplus >= 201103L + using __ite_ptr_traits = std::pointer_traits<_Iterator>; + + template + using __ite_rebind = typename __ite_ptr_traits::template rebind<_Tp>; +#endif + typedef _Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag> _Safe_base; typedef typename _Safe_base::_OtherIterator _OtherIterator; @@ -672,6 +679,19 @@ namespace __gnu_debug typedef typename _Safe_base::difference_type difference_type; typedef typename _Safe_base::reference reference; + +#if __cplusplus >= 201103L + using element_type = typename __ite_ptr_traits::element_type; + + template + using rebind = _Safe_iterator<__ite_rebind<_Up>, _Sequence, + std::random_access_iterator_tag>; + + static _Safe_iterator + pointer_to(element_type& __e) + { return { __ite_ptr_traits::pointer_to(__e), nullptr }; } +#endif + /// @post the iterator is singular and unattached _Safe_iterator() _GLIBCXX_NOEXCEPT { } 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());