@@ -472,10 +472,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__hashtable_alloc(__node_alloc_type(__a))
{ }
+ template<bool _No_realloc = true>
+ static constexpr bool
+ _S_nothrow_move()
+ {
+ if _GLIBCXX17_CONSTEXPR (_No_realloc)
+ if _GLIBCXX17_CONSTEXPR (is_nothrow_copy_constructible<_Hash>())
+ return is_nothrow_copy_constructible<_Equal>();
+ return false;
+ }
+
_Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
true_type /* alloc always equal */)
- noexcept(std::is_nothrow_copy_constructible<_Hash>::value &&
- std::is_nothrow_copy_constructible<_Equal>::value);
+ noexcept(_S_nothrow_move());
_Hashtable(_Hashtable&&, __node_alloc_type&&,
false_type /* alloc always equal */);
@@ -508,19 +517,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Use delegating constructors.
_Hashtable(_Hashtable&& __ht)
- noexcept( noexcept(
- _Hashtable(std::declval<_Hashtable>(),
- std::declval<__node_alloc_type>(),
- true_type{})) )
+ noexcept(_S_nothrow_move())
: _Hashtable(std::move(__ht), std::move(__ht._M_node_allocator()),
true_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{})) )
+ noexcept(_S_nothrow_move<__node_alloc_traits::_S_always_equal()>())
: _Hashtable(std::move(__ht), __node_alloc_type(__a),
typename __node_alloc_traits::is_always_equal{})
{ }
@@ -1400,8 +1403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
_Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
true_type /* alloc always equal */)
- noexcept(std::is_nothrow_copy_constructible<_Hash>::value &&
- std::is_nothrow_copy_constructible<_Equal>::value)
+ noexcept(_S_nothrow_move())
: __hashtable_base(__ht),
__map_base(__ht),
__rehash_base(__ht),
@@ -40,7 +40,7 @@ struct not_noexcept_copy_cons_hash
using type2 = std::unordered_map<int, int, not_noexcept_copy_cons_hash>;
static_assert( !std::is_nothrow_move_constructible<type2>::value,
- "noexcept move constructor" );
+ "not noexcept move constructor" );
static_assert( !std::is_nothrow_constructible<type2, type2&&,
const typename type2::allocator_type&>::value,
"not noexcept move constructor with allocator" );
@@ -59,7 +59,7 @@ using type3 = std::unordered_map<int, int, std::hash<int>,
not_noexcept_copy_cons_equal_to>;
static_assert( !std::is_nothrow_move_constructible<type3>::value,
- "noexcept move constructor" );
+ "not noexcept move constructor" );
static_assert( !std::is_nothrow_constructible<type3, type3&&,
const typename type3::allocator_type&>::value,
"not noexcept move constructor with allocator" );
@@ -40,7 +40,7 @@ struct not_noexcept_copy_cons_hash
using type2 = std::unordered_multimap<int, int, not_noexcept_copy_cons_hash>;
static_assert( !std::is_nothrow_move_constructible<type2>::value,
- "noexcept move constructor" );
+ "not not noexcept move constructor" );
static_assert( !std::is_nothrow_constructible<type2, type2&&,
const typename type2::allocator_type&>::value,
"not noexcept move constructor with allocator" );
@@ -59,7 +59,7 @@ using type3 = std::unordered_multimap<int, int, std::hash<int>,
not_noexcept_copy_cons_equal_to>;
static_assert( !std::is_nothrow_move_constructible<type3>::value,
- "noexcept move constructor" );
+ "not not noexcept move constructor" );
static_assert( !std::is_nothrow_constructible<type3, type3&&,
const typename type3::allocator_type&>::value,
"not noexcept move constructor with allocator" );
@@ -40,7 +40,7 @@ struct not_noexcept_copy_cons_hash
using type2 = std::unordered_multiset<int, not_noexcept_copy_cons_hash>;
static_assert( !std::is_nothrow_move_constructible<type2>::value,
- "noexcept move constructor" );
+ "not noexcept move constructor" );
static_assert( !std::is_nothrow_constructible<type2, type2&&,
const typename type2::allocator_type&>::value,
"not noexcept move constructor with allocator" );
@@ -59,7 +59,7 @@ using type3 = std::unordered_multiset<int, std::hash<int>,
not_noexcept_copy_cons_equal_to>;
static_assert( !std::is_nothrow_move_constructible<type3>::value,
- "noexcept move constructor" );
+ "not noexcept move constructor" );
static_assert( !std::is_nothrow_constructible<type3, type3&&,
const typename type3::allocator_type&>::value,
"not noexcept move constructor with allocator" );
@@ -40,7 +40,7 @@ struct not_noexcept_copy_cons_hash
using type2 = std::unordered_set<int, not_noexcept_copy_cons_hash>;
static_assert( !std::is_nothrow_move_constructible<type2>::value,
- "noexcept move constructor" );
+ "not noexcept move constructor" );
static_assert( !std::is_nothrow_constructible<type2, type2&&,
const typename type2::allocator_type&>::value,
"not noexcept move constructor with allocator" );
@@ -59,7 +59,7 @@ using type3 = std::unordered_set<int, std::hash<int>,
not_noexcept_copy_cons_equal_to>;
static_assert( !std::is_nothrow_move_constructible<type3>::value,
- "noexcept move constructor" );
+ "not noexcept move constructor" );
static_assert( !std::is_nothrow_constructible<type3, type3&&,
const typename type3::allocator_type&>::value,
"not noexcept move constructor with allocator" );