From 45b48129d5e03ba60d434986f480a46ab119ddb7 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 19 Jan 2017 18:26:41 +0000 Subject: [PATCH] PR67085 move comparison functions in heap operations PR libstdc++/67085 * include/bits/stl_heap.h (push_heap, __adjust_heap, __pop_heap) (pop_heap, __make_heap, make_heap, __sort_heap, sort_heap): Use _GLIBCXX_MOVE when passing comparison function to other functions. (is_heap_until, is_heap): Use std::move when passing comparison function. * testsuite/23_containers/priority_queue/67085.cc: New test. From-SVN: r244648 --- libstdc++-v3/ChangeLog | 8 ++++ libstdc++-v3/include/bits/stl_heap.h | 29 ++++++++---- .../23_containers/priority_queue/67085.cc | 46 +++++++++++++++++++ 3 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 libstdc++-v3/testsuite/23_containers/priority_queue/67085.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c6fb5adec1d..7fd289dfd08 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,13 @@ 2017-01-19 Jonathan Wakely + PR libstdc++/67085 + * include/bits/stl_heap.h (push_heap, __adjust_heap, __pop_heap) + (pop_heap, __make_heap, make_heap, __sort_heap, sort_heap): Use + _GLIBCXX_MOVE when passing comparison function to other functions. + (is_heap_until, is_heap): Use std::move when passing comparison + function. + * testsuite/23_containers/priority_queue/67085.cc: New test. + PR libstdc++/78905 * doc/xml/manual/abi.xml (abi.versioning.history): Add markup to macro names, filenames, and literal values. Document _GLIBCXX_RELEASE. diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h index 7d1d6f23c9c..c82ce7753ed 100644 --- a/libstdc++-v3/include/bits/stl_heap.h +++ b/libstdc++-v3/include/bits/stl_heap.h @@ -200,7 +200,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); std::__push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), _GLIBCXX_MOVE(__value), - __gnu_cxx::__ops::__iter_comp_val(__comp)); + __gnu_cxx::__ops:: + __iter_comp_val(_GLIBCXX_MOVE(__comp))); } template @@ -246,7 +248,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION *__result = _GLIBCXX_MOVE(*__first); std::__adjust_heap(__first, _DistanceType(0), _DistanceType(__last - __first), - _GLIBCXX_MOVE(__value), __comp); + _GLIBCXX_MOVE(__value), _GLIBCXX_MOVE(__comp)); } /** @@ -310,7 +312,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { --__last; std::__pop_heap(__first, __last, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops:: + __iter_comp_iter(_GLIBCXX_MOVE(__comp))); } } @@ -333,7 +336,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value), - __comp); + _GLIBCXX_MOVE(__comp)); if (__parent == 0) return; __parent--; @@ -386,7 +389,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_irreflexive_pred(__first, __last, __comp); std::__make_heap(__first, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops:: + __iter_comp_iter(_GLIBCXX_MOVE(__comp))); } template @@ -397,7 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION while (__last - __first > 1) { --__last; - std::__pop_heap(__first, __last, __last, __comp); + std::__pop_heap(__first, __last, __last, _GLIBCXX_MOVE(__comp)); } } @@ -449,7 +453,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_heap_pred(__first, __last, __comp); std::__sort_heap(__first, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops:: + __iter_comp_iter(_GLIBCXX_MOVE(__comp))); } #if __cplusplus >= 201103L @@ -504,7 +509,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __first + std::__is_heap_until(__first, std::distance(__first, __last), - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops:: + __iter_comp_iter(std::move(__comp))); } /** @@ -531,7 +537,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) - { return std::is_heap_until(__first, __last, __comp) == __last; } + { + return std::is_heap_until(__first, __last, std::move(__comp)) + == __last; + } #endif _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/testsuite/23_containers/priority_queue/67085.cc b/libstdc++-v3/testsuite/23_containers/priority_queue/67085.cc new file mode 100644 index 00000000000..5a3ca32c3a8 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/priority_queue/67085.cc @@ -0,0 +1,46 @@ +// Copyright (C) 2017 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++11 } } + +#include +#include + +unsigned count; + +struct CopyCounter : std::less +{ + CopyCounter() = default; + CopyCounter(const CopyCounter&) { ++count; } + CopyCounter(CopyCounter&&) = default; +}; + +void +test01() +{ + int v[] = {1, 2, 3, 4}; + std::priority_queue, CopyCounter> q{v, v+4}; + VERIFY(count == 2); + q.push(1); + VERIFY(count == 3); +} + +int +main() +{ + test01(); +} -- 2.30.2