summaryrefslogtreecommitdiffstats
path: root/libstdc++-v3/include/bits
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2014-01-23 17:17:04 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2014-01-23 17:17:04 +0000
commit1c690794225c87ef115bd14e361f120b021280ac (patch)
tree47cf2c8686043d9391364d3de8bf7968d7a53e60 /libstdc++-v3/include/bits
parent6d42c149a7601be54508a5c22850820581fdeb41 (diff)
downloadppe42-gcc-1c690794225c87ef115bd14e361f120b021280ac.tar.gz
ppe42-gcc-1c690794225c87ef115bd14e361f120b021280ac.zip
PR libstdc++/59872
* include/bits/stl_map.h (map::operator=(map&&)): Fix comment. * include/bits/stl_multimap.h (multimap::operator=(multimap&&)): Likewise. * include/bits/stl_multiset.h (multiset::operator=(multiset&&)): Likewise. * include/bits/stl_set.h (set::operator=(set&&)): Likewise. * include/bits/stl_tree.h (_Rb_tree::_M_move_data): New overloaded functions to perform moving or copying of elements from rvalue tree. (_Rb_tree::_Rb_tree(_Rb_tree&&)): Use _M_move_data. (_Rb_tree::_Rb_tree(_Rb_tree&&, _Node_allocator&&)): Likewise. * testsuite/23_containers/map/59872.cc: New. * testsuite/23_containers/map/56613.cc: Remove duplicate include. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206994 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/bits')
-rw-r--r--libstdc++-v3/include/bits/stl_map.h5
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h5
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h6
-rw-r--r--libstdc++-v3/include/bits/stl_set.h5
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h87
5 files changed, 63 insertions, 45 deletions
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index e261be8ed18..fa121e2d9a3 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -301,8 +301,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief %Map move assignment operator.
* @param __x A %map of identical element and allocator types.
*
- * The contents of @a __x are moved into this map (without copying).
- * @a __x is a valid, but unspecified %map.
+ * The contents of @a __x are moved into this map (without copying
+ * if the allocators compare equal or get moved on assignment).
+ * Afterwards @a __x is in a valid, but unspecified state.
*/
map&
operator=(map&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 84046cbb191..e4575c15da9 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -295,8 +295,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief %Multimap move assignment operator.
* @param __x A %multimap of identical element and allocator types.
*
- * The contents of @a __x are moved into this multimap (without copying).
- * @a __x is a valid, but unspecified multimap.
+ * The contents of @a __x are moved into this multimap (without copying
+ * if the allocators compare equal or get moved on assignment).
+ * Afterwards @a __x is in a valid, but unspecified state.
*/
multimap&
operator=(multimap&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index 3305107efdd..6d71c1b8621 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -267,9 +267,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief %Multiset move assignment operator.
* @param __x A %multiset of identical element and allocator types.
*
- * The contents of @a __x are moved into this %multiset
- * (without copying). @a __x is a valid, but unspecified
- * %multiset.
+ * The contents of @a __x are moved into this %multiset (without
+ * copying if the allocators compare equal or get moved on assignment).
+ * Afterwards @a __x is in a valid, but unspecified state.
*/
multiset&
operator=(multiset&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 652be58d977..3a391545ec8 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -271,8 +271,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief %Set move assignment operator.
* @param __x A %set of identical element and allocator types.
*
- * The contents of @a __x are moved into this %set (without copying).
- * @a __x is a valid, but unspecified %set.
+ * The contents of @a __x are moved into this %set (without copying
+ * if the allocators compare equal or get moved on assignment).
+ * Afterwards @a __x is in a valid, but unspecified state.
*/
set&
operator=(set&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index e41b1340e69..d24b1f750bc 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -698,8 +698,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
_Rb_tree(_Rb_tree&& __x)
- : _Rb_tree(std::move(__x), std::move(__x._M_get_Node_allocator()))
- { }
+ : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator())
+ {
+ if (__x._M_root() != 0)
+ _M_move_data(__x, std::true_type());
+ }
_Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
: _Rb_tree(std::move(__x), _Node_allocator(__a))
@@ -948,6 +951,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
bool
_M_move_assign(_Rb_tree&);
+
+ private:
+ // Move elements from container with equal allocator.
+ void
+ _M_move_data(_Rb_tree&, std::true_type);
+
+ // Move elements from container with possibly non-equal allocator,
+ // which might result in a copy not a move.
+ void
+ _M_move_data(_Rb_tree&, std::false_type);
#endif
};
@@ -1013,30 +1026,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
: _M_impl(__x._M_impl._M_key_compare, std::move(__a))
{
+ using __eq = integral_constant<bool, _Alloc_traits::_S_always_equal()>;
if (__x._M_root() != 0)
- {
- if (!_Alloc_traits::_S_always_equal()
- && __x._M_get_Node_allocator() != __a)
- {
- _M_root() = _M_copy(__x._M_begin(), _M_end());
- _M_leftmost() = _S_minimum(_M_root());
- _M_rightmost() = _S_maximum(_M_root());
- _M_impl._M_node_count = __x._M_impl._M_node_count;
- }
- else
- {
- _M_root() = __x._M_root();
- _M_leftmost() = __x._M_leftmost();
- _M_rightmost() = __x._M_rightmost();
- _M_root()->_M_parent = _M_end();
+ _M_move_data(__x, __eq());
+ }
- __x._M_root() = 0;
- __x._M_leftmost() = __x._M_end();
- __x._M_rightmost() = __x._M_end();
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ void
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_move_data(_Rb_tree& __x, std::true_type)
+ {
+ _M_root() = __x._M_root();
+ _M_leftmost() = __x._M_leftmost();
+ _M_rightmost() = __x._M_rightmost();
+ _M_root()->_M_parent = _M_end();
- this->_M_impl._M_node_count = __x._M_impl._M_node_count;
- __x._M_impl._M_node_count = 0;
- }
+ __x._M_root() = 0;
+ __x._M_leftmost() = __x._M_end();
+ __x._M_rightmost() = __x._M_end();
+
+ this->_M_impl._M_node_count = __x._M_impl._M_node_count;
+ __x._M_impl._M_node_count = 0;
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ void
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_move_data(_Rb_tree& __x, std::false_type)
+ {
+ if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
+ _M_move_data(__x, std::true_type());
+ else
+ {
+ _M_root() = _M_copy(__x._M_begin(), _M_end());
+ _M_leftmost() = _S_minimum(_M_root());
+ _M_rightmost() = _S_maximum(_M_root());
+ _M_impl._M_node_count = __x._M_impl._M_node_count;
}
}
@@ -1052,19 +1079,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
clear();
if (__x._M_root() != 0)
- {
- _M_root() = __x._M_root();
- _M_leftmost() = __x._M_leftmost();
- _M_rightmost() = __x._M_rightmost();
- _M_root()->_M_parent = _M_end();
-
- __x._M_root() = 0;
- __x._M_leftmost() = __x._M_end();
- __x._M_rightmost() = __x._M_end();
-
- this->_M_impl._M_node_count = __x._M_impl._M_node_count;
- __x._M_impl._M_node_count = 0;
- }
+ _M_move_data(__x, std::true_type());
if (_Alloc_traits::_S_propagate_on_move_assign())
std::__alloc_on_move(_M_get_Node_allocator(),
__x._M_get_Node_allocator());
OpenPOWER on IntegriCloud