diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index 384e5fdcdc996ee15d1f131e87a2b0c4d4903410..751b7ad119b0273c2950e33351ee9e8f936bec8f 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -308,51 +308,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __a; } - // Fallback implementation of the function in bits/stl_iterator.h used to - // remove the __normal_iterator wrapper. See copy, fill, ... - template<typename _Iterator> - _GLIBCXX20_CONSTEXPR - inline _Iterator - __niter_base(_Iterator __it) - _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value) - { return __it; } - -#if __cplusplus < 201103L - template<typename _Ite, typename _Seq> - _Ite - __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, - std::random_access_iterator_tag>&); - - template<typename _Ite, typename _Cont, typename _Seq> - _Ite - __niter_base(const ::__gnu_debug::_Safe_iterator< - ::__gnu_cxx::__normal_iterator<_Ite, _Cont>, _Seq, - std::random_access_iterator_tag>&); -#else - template<typename _Ite, typename _Seq> - _GLIBCXX20_CONSTEXPR - decltype(std::__niter_base(std::declval<_Ite>())) - __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, - std::random_access_iterator_tag>&) - noexcept(std::is_nothrow_copy_constructible<_Ite>::value); -#endif - - // Reverse the __niter_base transformation to get a - // __normal_iterator back again (this assumes that __normal_iterator - // is only used to wrap random access iterators, like pointers). - template<typename _From, typename _To> - _GLIBCXX20_CONSTEXPR - inline _From - __niter_wrap(_From __from, _To __res) - { return __from + (std::__niter_base(__res) - std::__niter_base(__from)); } - - // No need to wrap, iterator already has the right type. - template<typename _Iterator> - _GLIBCXX20_CONSTEXPR - inline _Iterator - __niter_wrap(const _Iterator&, _Iterator __res) - { return __res; } - // All of these auxiliary structs serve two purposes. (1) Replace // calls to copy with memmove whenever possible. (Memmove, not memcpy, // because the input and output ranges are permitted to overlap.) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 28a600c81cb25190efbe26b11ae08001a5c94b06..be3fa6f7a349e7c8ffcd44b2412dc2525600f2d2 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -654,24 +654,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION # endif // C++20 # endif // __glibcxx_make_reverse_iterator - template<typename _Iterator> - _GLIBCXX20_CONSTEXPR - auto - __niter_base(reverse_iterator<_Iterator> __it) - -> decltype(__make_reverse_iterator(__niter_base(__it.base()))) - { return __make_reverse_iterator(__niter_base(__it.base())); } - template<typename _Iterator> struct __is_move_iterator<reverse_iterator<_Iterator> > : __is_move_iterator<_Iterator> { }; - - template<typename _Iterator> - _GLIBCXX20_CONSTEXPR - auto - __miter_base(reverse_iterator<_Iterator> __it) - -> decltype(__make_reverse_iterator(__miter_base(__it.base()))) - { return __make_reverse_iterator(__miter_base(__it.base())); } #endif // C++11 // 24.4.2.2.1 back_insert_iterator @@ -1336,19 +1322,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } _GLIBCXX_END_NAMESPACE_VERSION -} // namespace +} // namespace __gnu_cxx namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - template<typename _Iterator, typename _Container> - _GLIBCXX20_CONSTEXPR - _Iterator - __niter_base(__gnu_cxx::__normal_iterator<_Iterator, _Container> __it) - _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value) - { return __it.base(); } - #if __cplusplus >= 201103L && __cplusplus <= 201703L // Need to overload __to_address because the pointer_traits primary template // will deduce element_type of __normal_iterator<T*, C> as T* rather than T. @@ -1820,13 +1799,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __make_move_if_noexcept_iterator(_Tp* __i) { return _ReturnType(__i); } - template<typename _Iterator> - _GLIBCXX20_CONSTEXPR - auto - __niter_base(move_iterator<_Iterator> __it) - -> decltype(make_move_iterator(__niter_base(__it.base()))) - { return make_move_iterator(__niter_base(__it.base())); } - template<typename _Iterator> struct __is_move_iterator<move_iterator<_Iterator> > { @@ -1834,12 +1806,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef __true_type __type; }; - template<typename _Iterator> - _GLIBCXX20_CONSTEXPR - auto - __miter_base(move_iterator<_Iterator> __it) - -> decltype(__miter_base(__it.base())) - { return __miter_base(__it.base()); } #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) std::make_move_iterator(_Iter) #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) \ @@ -2985,6 +2951,108 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @} group iterators +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence, typename _Category> + class _Safe_iterator; +} + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + /// @cond undocumented + + // Unwrap a __normal_iterator to get the underlying iterator + // (usually a pointer). See uses in std::copy, std::fill, etc. + template<typename _Iterator, typename _Container> + _GLIBCXX20_CONSTEXPR + _Iterator + __niter_base(__gnu_cxx::__normal_iterator<_Iterator, _Container> __it) + _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value) + { return __it.base(); } + + // Fallback implementation used for iterators that can't be unwrapped. + template<typename _Iterator> + _GLIBCXX20_CONSTEXPR + inline _Iterator + __niter_base(_Iterator __it) + _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value) + { return __it; } + + // Overload for _Safe_iterator needs to be declared before uses of + // std::__niter_base because we call it qualified so isn't found by ADL. +#if __cplusplus < 201103L + template<typename _Ite, typename _Seq> + _Ite + __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, + std::random_access_iterator_tag>&); + + template<typename _Ite, typename _Cont, typename _Seq> + _Ite + __niter_base(const ::__gnu_debug::_Safe_iterator< + ::__gnu_cxx::__normal_iterator<_Ite, _Cont>, _Seq, + std::random_access_iterator_tag>&); +#else + template<typename _Ite, typename _Seq> + _GLIBCXX20_CONSTEXPR + decltype(std::__niter_base(std::declval<_Ite>())) + __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, + std::random_access_iterator_tag>&) + noexcept(std::is_nothrow_copy_constructible<_Ite>::value); +#endif + +#if __cplusplus >= 201103L + template<typename _Iterator> + _GLIBCXX20_CONSTEXPR + auto + __niter_base(reverse_iterator<_Iterator> __it) + -> decltype(__make_reverse_iterator(__niter_base(__it.base()))) + { return __make_reverse_iterator(__niter_base(__it.base())); } + + template<typename _Iterator> + _GLIBCXX20_CONSTEXPR + auto + __niter_base(move_iterator<_Iterator> __it) + -> decltype(make_move_iterator(__niter_base(__it.base()))) + { return make_move_iterator(__niter_base(__it.base())); } + + template<typename _Iterator> + _GLIBCXX20_CONSTEXPR + auto + __miter_base(reverse_iterator<_Iterator> __it) + -> decltype(__make_reverse_iterator(__miter_base(__it.base()))) + { return __make_reverse_iterator(__miter_base(__it.base())); } + + template<typename _Iterator> + _GLIBCXX20_CONSTEXPR + auto + __miter_base(move_iterator<_Iterator> __it) + -> decltype(__miter_base(__it.base())) + { return __miter_base(__it.base()); } +#endif + + // Reverse the __niter_base transformation to get a __normal_iterator + // back again (this assumes that __normal_iterator is only used to wrap + // random access iterators, like pointers). + // All overloads of std::__niter_base must be declared before this. + template<typename _From, typename _To> + _GLIBCXX20_CONSTEXPR + inline _From + __niter_wrap(_From __from, _To __res) + { return __from + (std::__niter_base(__res) - std::__niter_base(__from)); } + + // No need to wrap, iterator already has the right type. + template<typename _Iterator> + _GLIBCXX20_CONSTEXPR + inline _Iterator + __niter_wrap(const _Iterator&, _Iterator __res) + { return __res; } + + /// @endcond + #if __cpp_deduction_guides >= 201606 // These helper traits are used for deduction guides // of associative containers. diff --git a/libstdc++-v3/testsuite/24_iterators/normal_iterator/wrapping.cc b/libstdc++-v3/testsuite/24_iterators/normal_iterator/wrapping.cc new file mode 100644 index 0000000000000000000000000000000000000000..bbfd4264a3610950b140463548454a4bfde9209e --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/normal_iterator/wrapping.cc @@ -0,0 +1,29 @@ +#include <iterator> +#include <algorithm> +#include <vector> +#ifndef _GLIBCXX_DEBUG +#include <debug/vector> +#endif + +struct S { }; + +int main() +{ + S s[1]; + std::vector<S> v(1); + std::copy(s, s, v.rbegin()); +#if __cplusplus >= 201103L + std::copy(s, s, std::make_move_iterator(v.begin())); + std::copy(s, s, std::make_move_iterator(v.rbegin())); +#endif + +#ifndef _GLIBCXX_DEBUG + __gnu_debug::vector<S> dv(1); + std::copy(s, s, dv.rbegin()); +#if __cplusplus >= 201103L + std::copy(s, s, std::make_move_iterator(dv.begin())); + std::copy(s, s, std::make_move_iterator(dv.rbegin())); +#endif +#endif +} +