summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits/hashtable.h
diff options
context:
space:
mode:
authorFrançois Dumont <fdumont@gcc.gnu.org>2020-01-20 19:15:43 +0100
committerFrançois Dumont <fdumont@gcc.gnu.org>2020-07-29 11:26:42 +0200
commit12324b9a934654a5c3bf4a614853ded2e0a958af (patch)
treea66b4107aabc48b6e6275686505f7af2c3187b54 /libstdc++-v3/include/bits/hashtable.h
parentf1660ceb0d3b0076555058087307f88b80619a6f (diff)
downloadgcc-12324b9a934654a5c3bf4a614853ded2e0a958af.tar.gz
libstdc++: Fix unordered containers move constructors noexcept qualification
_Hashtable move constructor is wrongly qualified as noexcept(true) regardless of _Equal and _H1 copy constructor qualifications. _Hashtable allocator-aware move constructor is missing its noexcept qualification like the depending unordered containers ones. libstdc++-v3/ChangeLog: * include/bits/hashtable.h (_Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a, true_type)): Add noexcept qualification. (_Hashtable(_Hashtable&&)): Fix noexcept qualification. (_Hashtable(_Hashtable&&, const allocator_type&)): Add noexcept qualification. * include/bits/unordered_map.h (unordered_map(unordered_map&&, const allocator_type&)): Add noexcept qualification. (unordered_multimap(unordered_multimap&&, const allocator_type&)): Likewise. * include/bits/unordered_set.h (unordered_set(unordered_set&&, const allocator_type&)): Likewise. (unordered_multiset(unordered_multiset&&, const allocator_type&)): Likewise. * include/debug/unordered_map (unordered_map(unordered_map&&, const allocator_type&)): Likewise. (unordered_multimap(unordered_multimap&&, const allocator_type&)): Likewise. * include/debug/unordered_set (unordered_set(unordered_set&&, const allocator_type&)): Likewise. (unordered_multiset(unordered_multiset&&, const allocator_type&)): Likewise. * testsuite/23_containers/unordered_map/allocator/default_init.cc: New test. * testsuite/23_containers/unordered_map/cons/noexcept_default_construct.cc: New test. * testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc: New test. * testsuite/23_containers/unordered_map/modifiers/move_assign.cc: New test. * testsuite/23_containers/unordered_multimap/cons/noexcept_default_construct.cc: New test. * testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc: New test. * testsuite/23_containers/unordered_multiset/cons/noexcept_default_construct.cc: New test. * testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc: New test. * testsuite/23_containers/unordered_set/allocator/default_init.cc: New test. * testsuite/23_containers/unordered_set/cons/noexcept_default_construct.cc: New test. * testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc: New test.
Diffstat (limited to 'libstdc++-v3/include/bits/hashtable.h')
-rw-r--r--libstdc++-v3/include/bits/hashtable.h40
1 files changed, 33 insertions, 7 deletions
diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index 9d1ad592553..dc8ed2ee18c 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -460,6 +460,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__hashtable_alloc(__node_alloc_type(__a))
{ }
+ _Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
+ true_type /* alloc always equal */)
+ noexcept(std::is_nothrow_copy_constructible<_H1>::value &&
+ std::is_nothrow_copy_constructible<_Equal>::value);
+
+ _Hashtable(_Hashtable&&, __node_alloc_type&&,
+ false_type /* alloc always equal */);
+
template<typename _InputIterator>
_Hashtable(_InputIterator __first, _InputIterator __last,
size_type __bkt_count_hint,
@@ -486,11 +494,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Hashtable(const _Hashtable&);
- _Hashtable(_Hashtable&&) noexcept;
+ _Hashtable(_Hashtable&& __ht)
+ noexcept( noexcept(
+ _Hashtable(std::declval<_Hashtable>(),
+ std::declval<__node_alloc_type>(),
+ true_type{})) )
+ : _Hashtable(std::move(__ht), std::move(__ht._M_node_allocator()),
+ true_type{})
+ { }
_Hashtable(const _Hashtable&, const allocator_type&);
- _Hashtable(_Hashtable&&, const allocator_type&);
+ _Hashtable(_Hashtable&& __ht, const allocator_type& __a)
+ noexcept( noexcept(
+ _Hashtable(std::declval<_Hashtable>(),
+ std::declval<__node_alloc_type>(),
+ typename __node_alloc_traits::is_always_equal{})) )
+ : _Hashtable(std::move(__ht), __node_alloc_type(__a),
+ typename __node_alloc_traits::is_always_equal{})
+ { }
// Use delegating constructors.
template<typename _InputIterator>
@@ -1342,18 +1364,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Traits>
_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
_H1, _H2, _Hash, _RehashPolicy, _Traits>::
- _Hashtable(_Hashtable&& __ht) noexcept
+ _Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
+ true_type /* alloc always equal */)
+ noexcept(std::is_nothrow_copy_constructible<_H1>::value &&
+ std::is_nothrow_copy_constructible<_Equal>::value)
: __hashtable_base(__ht),
__map_base(__ht),
__rehash_base(__ht),
- __hashtable_alloc(std::move(__ht._M_base_alloc())),
+ __hashtable_alloc(std::move(__a)),
_M_buckets(__ht._M_buckets),
_M_bucket_count(__ht._M_bucket_count),
_M_before_begin(__ht._M_before_begin._M_nxt),
_M_element_count(__ht._M_element_count),
_M_rehash_policy(__ht._M_rehash_policy)
{
- // Update, if necessary, buckets if __ht is using its single bucket.
+ // Update buckets if __ht is using its single bucket.
if (__ht._M_uses_single_bucket())
{
_M_buckets = &_M_single_bucket;
@@ -1392,11 +1417,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Traits>
_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
_H1, _H2, _Hash, _RehashPolicy, _Traits>::
- _Hashtable(_Hashtable&& __ht, const allocator_type& __a)
+ _Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
+ false_type /* alloc always equal */)
: __hashtable_base(__ht),
__map_base(__ht),
__rehash_base(__ht),
- __hashtable_alloc(__node_alloc_type(__a)),
+ __hashtable_alloc(std::move(__a)),
_M_buckets(nullptr),
_M_bucket_count(__ht._M_bucket_count),
_M_element_count(__ht._M_element_count),