diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h index c64553e2571..8c5c5df5266 100644 --- a/libstdc++-v3/include/bits/stl_heap.h +++ b/libstdc++-v3/include/bits/stl_heap.h @@ -85,7 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Distance __parent = 0; for (_Distance __child = 1; __child < __n; ++__child) { - if (__comp(__first[__parent], __first[__child])) + if (__comp(*(__first + __parent), *(__first + __child))) return __child; if ((__child & 1) == 0) ++__parent; @@ -143,7 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Compare& __comp) { _Distance __parent = (__holeIndex - 1) / 2; - while (__holeIndex > __topIndex && __comp(__first[__parent], __value)) + while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) { *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent)); __holeIndex = __parent; @@ -233,8 +233,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION while (__secondChild < (__len - 1) / 2) { __secondChild = 2 * (__secondChild + 1); - if (__comp(__first[__secondChild], - __first[__secondChild - 1])) + if (__comp(*(__first + __secondChild), + *(__first + _Distance(__secondChild - 1)))) __secondChild--; *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild)); __holeIndex = __secondChild; diff --git a/libstdc++-v3/testsuite/25_algorithms/sort_heap/check_proxy_brackets.cc b/libstdc++-v3/testsuite/25_algorithms/sort_heap/check_proxy_brackets.cc new file mode 100644 index 00000000000..c556c26dfa8 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/sort_heap/check_proxy_brackets.cc @@ -0,0 +1,67 @@ +// { dg-do run } + +#undef _GLIBCXX_CONCEPT_CHECKS + +#include +#include +#include +#include + +using __gnu_test::test_container; +using __gnu_test::proxy_random_access_iterator_wrapper; + +typedef std::pair V; +typedef test_container Container; + +struct Deduced +{ + template + bool operator()(const std::pair& lhs, + const std::pair& rhs) const + { return lhs.first < rhs.first; } +}; + +struct Conversion +{ + struct First + { + First(const V& p) : v(p.first) + {} + + int v; + }; + + bool operator()(First lhs, First rhs) const + { return lhs.v < rhs.v; } +}; + +template +void +test01(Cmp cmp) +{ + V s1[] = { V(0, 10), V(8, 18), V(6, 16), V(7, 17), V(9, 19), + V(5, 15), V(4, 14), V(3, 13), V(2, 12), V(1, 11) }; + const int N = sizeof(s1) / sizeof(V); + Container con(s1, s1 + N); + + std::make_heap(con.begin(), con.end() - std::ptrdiff_t(2), cmp); + std::push_heap(con.begin(), con.end() - std::ptrdiff_t(1), cmp); + std::push_heap(con.begin(), con.end(), cmp); +#if __cplusplus >= 201103L + (void)std::is_heap_until(con.begin(), con.end(), cmp); +#endif + std::sort_heap(con.begin(), con.end(), cmp); + for(int i = 0; i < N; ++i) + { + VERIFY( s1[i].first == i ); + VERIFY( s1[i].second == 10 + i ); + } +} + +int +main() +{ + test01(Deduced()); + test01(Conversion()); + return 0; +} diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h index 95589b2626d..caede49e41b 100644 --- a/libstdc++-v3/testsuite/util/testsuite_iterators.h +++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h @@ -664,6 +664,204 @@ namespace __gnu_test #endif + template + struct subscript_proxy + { + _GLIBCXX_CONSTEXPR + operator T&() const + { return *ptr; } + + _GLIBCXX14_CONSTEXPR + subscript_proxy& operator=(const T& val) + { + *ptr = val; + return *this; + } + + T* ptr; + }; + + template + struct subscript_proxy + { + _GLIBCXX_CONSTEXPR + operator const T&() const + { return *ptr; } + + const T* ptr; + }; + + /** + * @brief random_access_iterator wrapper for pointer, + * that returns proxy from subscript. + * + * This class takes a pointer and wraps it to provide exactly + * the requirements of a random_access_iterator. It should not be + * instantiated directly, but generated from a test_container + */ + template + struct proxy_random_access_iterator_wrapper + : public bidirectional_iterator_wrapper + { + typedef BoundsContainer ContainerType; + typedef std::random_access_iterator_tag iterator_category; + + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) + : bidirectional_iterator_wrapper(_ptr, SharedInfo_in) + { } + + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper() + : bidirectional_iterator_wrapper() + { } + +#if __cplusplus >= 201103L + proxy_random_access_iterator_wrapper( + const proxy_random_access_iterator_wrapper&) = default; + + proxy_random_access_iterator_wrapper& + operator=(const proxy_random_access_iterator_wrapper&) = default; +#endif + + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper& + operator++() + { + ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last); + this->ptr++; + return *this; + } + + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper + operator++(int) + { + proxy_random_access_iterator_wrapper tmp = *this; + ++*this; + return tmp; + } + + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper& + operator--() + { + ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first); + this->ptr--; + return *this; + } + + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper + operator--(int) + { + proxy_random_access_iterator_wrapper tmp = *this; + --*this; + return tmp; + } + + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper& + operator+=(std::ptrdiff_t n) + { + if(n > 0) + { + ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr); + this->ptr += n; + } + else + { + ITERATOR_VERIFY(-n <= this->ptr - this->SharedInfo->first); + this->ptr += n; + } + return *this; + } + + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper& + operator-=(std::ptrdiff_t n) + { return *this += -n; } + + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper + operator-(std::ptrdiff_t n) const + { + proxy_random_access_iterator_wrapper tmp = *this; + return tmp -= n; + } + + _GLIBCXX14_CONSTEXPR + std::ptrdiff_t + operator-(const proxy_random_access_iterator_wrapper& in) const + { + ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo); + return this->ptr - in.ptr; + } + + _GLIBCXX14_CONSTEXPR + subscript_proxy + operator[](std::ptrdiff_t n) const + { + subscript_proxy tmp = { *this + n }; + return tmp; + } + +#if __cplusplus >= 201103L + // Ensure that the iterator's difference_type is always used. + template void operator+=(D) = delete; + template void operator-=(D) = delete; + template void operator[](D) const = delete; + template + typename std::enable_if::value>::type + operator-(D) const = delete; +#endif + + _GLIBCXX14_CONSTEXPR + bool operator<(const proxy_random_access_iterator_wrapper& in) const + { + ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo); + return this->ptr < in.ptr; + } + + _GLIBCXX14_CONSTEXPR + bool operator>(const proxy_random_access_iterator_wrapper& in) const + { + return in < *this; + } + + _GLIBCXX14_CONSTEXPR + bool operator>=(const proxy_random_access_iterator_wrapper& in) const + { + return !(*this < in); + } + + _GLIBCXX14_CONSTEXPR + bool operator<=(const proxy_random_access_iterator_wrapper& in) const + { + return !(*this > in); + } + }; + + template + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper + operator+(proxy_random_access_iterator_wrapper it, std::ptrdiff_t n) + { return it += n; } + + template + _GLIBCXX14_CONSTEXPR + proxy_random_access_iterator_wrapper + operator+(std::ptrdiff_t n, proxy_random_access_iterator_wrapper it) + { return it += n; } + +#if __cplusplus >= 201103L + // Ensure that the iterator's difference_type is always used. + template + void operator+(proxy_random_access_iterator_wrapper, D) = delete; + template + void operator+(D, proxy_random_access_iterator_wrapper) = delete; +#endif + /** * @brief A container-type class for holding iterator wrappers * test_container takes two parameters, a class T and an iterator