PR67085 move comparison functions in heap operations
authorJonathan Wakely <jwakely@redhat.com>
Thu, 19 Jan 2017 18:26:41 +0000 (18:26 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 19 Jan 2017 18:26:41 +0000 (18:26 +0000)
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
libstdc++-v3/include/bits/stl_heap.h
libstdc++-v3/testsuite/23_containers/priority_queue/67085.cc [new file with mode: 0644]

index c6fb5adec1d4853f18edc220bf151e015e35622d..7fd289dfd08452aaa75fb9a978491bdee1a615e3 100644 (file)
@@ -1,5 +1,13 @@
 2017-01-19  Jonathan Wakely  <jwakely@redhat.com>
 
+       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.
index 7d1d6f23c9c7b3c52c3dde4669d26543d849bdd0..c82ce7753ed7cddc57b7a32d25e5f7df7ccfd637 100644 (file)
@@ -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<typename _RandomAccessIterator, typename _Distance,
@@ -229,7 +230,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        }
       std::__push_heap(__first, __holeIndex, __topIndex, 
                       _GLIBCXX_MOVE(__value),
-                      __gnu_cxx::__ops::__iter_comp_val(__comp));
+                      __gnu_cxx::__ops::
+                      __iter_comp_val(_GLIBCXX_MOVE(__comp)));
     }
 
   template<typename _RandomAccessIterator, typename _Compare>
@@ -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<typename _RandomAccessIterator, typename _Compare>
@@ -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 (file)
index 0000000..5a3ca32
--- /dev/null
@@ -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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <queue>
+#include <testsuite_hooks.h>
+
+unsigned count;
+
+struct CopyCounter : std::less<int>
+{
+  CopyCounter() = default;
+  CopyCounter(const CopyCounter&) { ++count; }
+  CopyCounter(CopyCounter&&) = default;
+};
+
+void
+test01()
+{
+  int v[] = {1, 2, 3, 4};
+  std::priority_queue<int, std::vector<int>, CopyCounter> q{v, v+4};
+  VERIFY(count == 2);
+  q.push(1);
+  VERIFY(count == 3);
+}
+
+int
+main()
+{
+  test01();
+}