mirror of git://gcc.gnu.org/git/gcc.git
libstdc++/77334 move assign RB trees of non-copyable types
PR libstdc++/77334 * include/bits/stl_tree.h (_Rb_tree::_M_move_assign): New functions. (_Rb_tree::operator=(_Rb_tree&&)): Dispatch to _M_move_assign. * testsuite/23_containers/map/77334.cc: New test. From-SVN: r239698
This commit is contained in:
parent
5d1c6b3e76
commit
5ea387db6c
|
|
@ -1,5 +1,10 @@
|
||||||
2016-08-23 Jonathan Wakely <jwakely@redhat.com>
|
2016-08-23 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
PR libstdc++/77334
|
||||||
|
* include/bits/stl_tree.h (_Rb_tree::_M_move_assign): New functions.
|
||||||
|
(_Rb_tree::operator=(_Rb_tree&&)): Dispatch to _M_move_assign.
|
||||||
|
* testsuite/23_containers/map/77334.cc: New test.
|
||||||
|
|
||||||
* doc/xml/manual/using.xml: Remove reference to -pthreads option.
|
* doc/xml/manual/using.xml: Remove reference to -pthreads option.
|
||||||
* doc/html/*: Regenerate.
|
* doc/html/*: Regenerate.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1264,6 +1264,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
// which might result in a copy not a move.
|
// which might result in a copy not a move.
|
||||||
void
|
void
|
||||||
_M_move_data(_Rb_tree&, std::false_type);
|
_M_move_data(_Rb_tree&, std::false_type);
|
||||||
|
|
||||||
|
// Move assignment from container with equal allocator.
|
||||||
|
void
|
||||||
|
_M_move_assign(_Rb_tree&, std::true_type);
|
||||||
|
|
||||||
|
// Move assignment from container with possibly non-equal allocator,
|
||||||
|
// which might result in a copy not a move.
|
||||||
|
void
|
||||||
|
_M_move_assign(_Rb_tree&, std::false_type);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1379,24 +1388,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
template<typename _Key, typename _Val, typename _KeyOfValue,
|
template<typename _Key, typename _Val, typename _KeyOfValue,
|
||||||
typename _Compare, typename _Alloc>
|
typename _Compare, typename _Alloc>
|
||||||
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
|
inline void
|
||||||
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
|
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
|
||||||
operator=(_Rb_tree&& __x)
|
_M_move_assign(_Rb_tree& __x, true_type)
|
||||||
noexcept(_Alloc_traits::_S_nothrow_move()
|
|
||||||
&& is_nothrow_move_assignable<_Compare>::value)
|
|
||||||
{
|
{
|
||||||
_M_impl._M_key_compare = __x._M_impl._M_key_compare;
|
clear();
|
||||||
if (_Alloc_traits::_S_propagate_on_move_assign()
|
if (__x._M_root() != nullptr)
|
||||||
|| _Alloc_traits::_S_always_equal()
|
_M_move_data(__x, std::true_type());
|
||||||
|| _M_get_Node_allocator() == __x._M_get_Node_allocator())
|
std::__alloc_on_move(_M_get_Node_allocator(),
|
||||||
{
|
__x._M_get_Node_allocator());
|
||||||
clear();
|
}
|
||||||
if (__x._M_root() != nullptr)
|
|
||||||
_M_move_data(__x, std::true_type());
|
template<typename _Key, typename _Val, typename _KeyOfValue,
|
||||||
std::__alloc_on_move(_M_get_Node_allocator(),
|
typename _Compare, typename _Alloc>
|
||||||
__x._M_get_Node_allocator());
|
void
|
||||||
return *this;
|
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
|
||||||
}
|
_M_move_assign(_Rb_tree& __x, false_type)
|
||||||
|
{
|
||||||
|
if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
|
||||||
|
return _M_move_assign(__x, true_type{});
|
||||||
|
|
||||||
// Try to move each node reusing existing nodes and copying __x nodes
|
// Try to move each node reusing existing nodes and copying __x nodes
|
||||||
// structure.
|
// structure.
|
||||||
|
|
@ -1416,6 +1426,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_M_impl._M_node_count = __x._M_impl._M_node_count;
|
_M_impl._M_node_count = __x._M_impl._M_node_count;
|
||||||
__x.clear();
|
__x.clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename _Key, typename _Val, typename _KeyOfValue,
|
||||||
|
typename _Compare, typename _Alloc>
|
||||||
|
inline _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
|
||||||
|
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
|
||||||
|
operator=(_Rb_tree&& __x)
|
||||||
|
noexcept(_Alloc_traits::_S_nothrow_move()
|
||||||
|
&& is_nothrow_move_assignable<_Compare>::value)
|
||||||
|
{
|
||||||
|
_M_impl._M_key_compare = __x._M_impl._M_key_compare;
|
||||||
|
constexpr bool __move_storage =
|
||||||
|
_Alloc_traits::_S_propagate_on_move_assign()
|
||||||
|
|| _Alloc_traits::_S_always_equal();
|
||||||
|
_M_move_assign(__x, __bool_constant<__move_storage>());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright (C) 2016 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 compile { target c++11 } }
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
struct A { A(A&&) = delete; };
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
std::map<int, A> m1, m2;
|
||||||
|
m2 = std::move(m1);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue