This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[patch] libstdc++/61023 - copy comparison functor in RB tree move assignment
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Wed, 7 May 2014 15:13:20 +0100
- Subject: [patch] libstdc++/61023 - copy comparison functor in RB tree move assignment
- Authentication-results: sourceware.org; auth=none
As noted in the PR, the standard doesn't actually say what containers
should do with their functors on move construction/assignment.
Our unordered containers currently move the hash and predicate
functions.
Our RB trees copy the comparison function in the move constructor but
do nothing with it in the move assignment. I think moving in both
cases is probably correct, but rather than change the existing move
constructor this patch just makes the move assignment copy the
function, for consistency.
When the standard is clarified we can review whether we should be
moving instead of copying.
Tested x86_64-linux, committed to trunk and the 4.9 branch.
commit 42ea108aeb7528ff3b41f7c1b9d11f3a8ba1bae8
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Wed May 7 14:25:48 2014 +0100
PR libstdc++/61023
* include/bits/stl_tree.h (_Rb_tree::_M_move_assign): Copy the
comparison function.
* testsuite/23_containers/set/cons/61023.cc: New.
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 288c9fa..ce43ab8 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -1073,6 +1073,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_move_assign(_Rb_tree& __x)
{
+ _M_impl._M_key_compare = __x._M_impl._M_key_compare;
if (_Alloc_traits::_S_propagate_on_move_assign()
|| _Alloc_traits::_S_always_equal()
|| _M_get_Node_allocator() == __x._M_get_Node_allocator())
diff --git a/libstdc++-v3/testsuite/23_containers/set/cons/61023.cc b/libstdc++-v3/testsuite/23_containers/set/cons/61023.cc
new file mode 100644
index 0000000..087b9cc
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/cons/61023.cc
@@ -0,0 +1,56 @@
+// { dg-options "-std=gnu++11" }
+
+// Copyright (C) 2014 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/>.
+
+#include <set>
+#include <stdexcept>
+
+struct Comparator
+{
+ Comparator() : valid(false) { }
+ explicit Comparator(bool) : valid(true) { }
+
+ bool operator()(int i, int j) const
+ {
+ if (!valid)
+ throw std::logic_error("Comparator is invalid");
+ return i < j;
+ }
+
+private:
+ bool valid;
+};
+
+int main()
+{
+ using test_type = std::set<int, Comparator>;
+
+ Comparator cmp{true};
+
+ test_type good{cmp};
+
+ test_type s1;
+ s1 = good; // copy-assign
+ s1.insert(1);
+ s1.insert(2);
+
+ test_type s2;
+ s2 = std::move(good); // move-assign
+ s2.insert(1);
+ s2.insert(2);
+}