libstdc++: Simplify noexcept-specifiers for move constructors
This puts the logic for the noexcept-specifier in one place, and then reuses it elsewhere. This means checking whether the move constructor can throw doesn't need to do overload resolution and then check whether some other constructor can throw, we just get the answer directly. libstdc++-v3/ChangeLog: * include/bits/hashtable.h (_Hashtable::_S_nothrow_move()): New function to determine noexcept-specifier for move constructors. (_Hashtable): Use _S_nothrow_move() on move constructors. * testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc: Correct static assertion message. * testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc: Likewise. * testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc: Likewise. * testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc: Likewise.
This commit is contained in:
parent
59d09f9fe4
commit
1cbba49e34
@ -472,10 +472,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
__hashtable_alloc(__node_alloc_type(__a))
|
__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,
|
_Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
|
||||||
true_type /* alloc always equal */)
|
true_type /* alloc always equal */)
|
||||||
noexcept(std::is_nothrow_copy_constructible<_Hash>::value &&
|
noexcept(_S_nothrow_move());
|
||||||
std::is_nothrow_copy_constructible<_Equal>::value);
|
|
||||||
|
|
||||||
_Hashtable(_Hashtable&&, __node_alloc_type&&,
|
_Hashtable(_Hashtable&&, __node_alloc_type&&,
|
||||||
false_type /* alloc always equal */);
|
false_type /* alloc always equal */);
|
||||||
@ -508,19 +517,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
// Use delegating constructors.
|
// Use delegating constructors.
|
||||||
_Hashtable(_Hashtable&& __ht)
|
_Hashtable(_Hashtable&& __ht)
|
||||||
noexcept( noexcept(
|
noexcept(_S_nothrow_move())
|
||||||
_Hashtable(std::declval<_Hashtable>(),
|
|
||||||
std::declval<__node_alloc_type>(),
|
|
||||||
true_type{})) )
|
|
||||||
: _Hashtable(std::move(__ht), std::move(__ht._M_node_allocator()),
|
: _Hashtable(std::move(__ht), std::move(__ht._M_node_allocator()),
|
||||||
true_type{})
|
true_type{})
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
_Hashtable(_Hashtable&& __ht, const allocator_type& __a)
|
_Hashtable(_Hashtable&& __ht, const allocator_type& __a)
|
||||||
noexcept( noexcept(
|
noexcept(_S_nothrow_move<__node_alloc_traits::_S_always_equal()>())
|
||||||
_Hashtable(std::declval<_Hashtable>(),
|
|
||||||
std::declval<__node_alloc_type>(),
|
|
||||||
typename __node_alloc_traits::is_always_equal{})) )
|
|
||||||
: _Hashtable(std::move(__ht), __node_alloc_type(__a),
|
: _Hashtable(std::move(__ht), __node_alloc_type(__a),
|
||||||
typename __node_alloc_traits::is_always_equal{})
|
typename __node_alloc_traits::is_always_equal{})
|
||||||
{ }
|
{ }
|
||||||
@ -1400,8 +1403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
_Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
|
_Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
|
||||||
_Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
|
_Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
|
||||||
true_type /* alloc always equal */)
|
true_type /* alloc always equal */)
|
||||||
noexcept(std::is_nothrow_copy_constructible<_Hash>::value &&
|
noexcept(_S_nothrow_move())
|
||||||
std::is_nothrow_copy_constructible<_Equal>::value)
|
|
||||||
: __hashtable_base(__ht),
|
: __hashtable_base(__ht),
|
||||||
__map_base(__ht),
|
__map_base(__ht),
|
||||||
__rehash_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>;
|
using type2 = std::unordered_map<int, int, not_noexcept_copy_cons_hash>;
|
||||||
|
|
||||||
static_assert( !std::is_nothrow_move_constructible<type2>::value,
|
static_assert( !std::is_nothrow_move_constructible<type2>::value,
|
||||||
"noexcept move constructor" );
|
"not noexcept move constructor" );
|
||||||
static_assert( !std::is_nothrow_constructible<type2, type2&&,
|
static_assert( !std::is_nothrow_constructible<type2, type2&&,
|
||||||
const typename type2::allocator_type&>::value,
|
const typename type2::allocator_type&>::value,
|
||||||
"not noexcept move constructor with allocator" );
|
"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>;
|
not_noexcept_copy_cons_equal_to>;
|
||||||
|
|
||||||
static_assert( !std::is_nothrow_move_constructible<type3>::value,
|
static_assert( !std::is_nothrow_move_constructible<type3>::value,
|
||||||
"noexcept move constructor" );
|
"not noexcept move constructor" );
|
||||||
static_assert( !std::is_nothrow_constructible<type3, type3&&,
|
static_assert( !std::is_nothrow_constructible<type3, type3&&,
|
||||||
const typename type3::allocator_type&>::value,
|
const typename type3::allocator_type&>::value,
|
||||||
"not noexcept move constructor with allocator" );
|
"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>;
|
using type2 = std::unordered_multimap<int, int, not_noexcept_copy_cons_hash>;
|
||||||
|
|
||||||
static_assert( !std::is_nothrow_move_constructible<type2>::value,
|
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&&,
|
static_assert( !std::is_nothrow_constructible<type2, type2&&,
|
||||||
const typename type2::allocator_type&>::value,
|
const typename type2::allocator_type&>::value,
|
||||||
"not noexcept move constructor with allocator" );
|
"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>;
|
not_noexcept_copy_cons_equal_to>;
|
||||||
|
|
||||||
static_assert( !std::is_nothrow_move_constructible<type3>::value,
|
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&&,
|
static_assert( !std::is_nothrow_constructible<type3, type3&&,
|
||||||
const typename type3::allocator_type&>::value,
|
const typename type3::allocator_type&>::value,
|
||||||
"not noexcept move constructor with allocator" );
|
"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>;
|
using type2 = std::unordered_multiset<int, not_noexcept_copy_cons_hash>;
|
||||||
|
|
||||||
static_assert( !std::is_nothrow_move_constructible<type2>::value,
|
static_assert( !std::is_nothrow_move_constructible<type2>::value,
|
||||||
"noexcept move constructor" );
|
"not noexcept move constructor" );
|
||||||
static_assert( !std::is_nothrow_constructible<type2, type2&&,
|
static_assert( !std::is_nothrow_constructible<type2, type2&&,
|
||||||
const typename type2::allocator_type&>::value,
|
const typename type2::allocator_type&>::value,
|
||||||
"not noexcept move constructor with allocator" );
|
"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>;
|
not_noexcept_copy_cons_equal_to>;
|
||||||
|
|
||||||
static_assert( !std::is_nothrow_move_constructible<type3>::value,
|
static_assert( !std::is_nothrow_move_constructible<type3>::value,
|
||||||
"noexcept move constructor" );
|
"not noexcept move constructor" );
|
||||||
static_assert( !std::is_nothrow_constructible<type3, type3&&,
|
static_assert( !std::is_nothrow_constructible<type3, type3&&,
|
||||||
const typename type3::allocator_type&>::value,
|
const typename type3::allocator_type&>::value,
|
||||||
"not noexcept move constructor with allocator" );
|
"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>;
|
using type2 = std::unordered_set<int, not_noexcept_copy_cons_hash>;
|
||||||
|
|
||||||
static_assert( !std::is_nothrow_move_constructible<type2>::value,
|
static_assert( !std::is_nothrow_move_constructible<type2>::value,
|
||||||
"noexcept move constructor" );
|
"not noexcept move constructor" );
|
||||||
static_assert( !std::is_nothrow_constructible<type2, type2&&,
|
static_assert( !std::is_nothrow_constructible<type2, type2&&,
|
||||||
const typename type2::allocator_type&>::value,
|
const typename type2::allocator_type&>::value,
|
||||||
"not noexcept move constructor with allocator" );
|
"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>;
|
not_noexcept_copy_cons_equal_to>;
|
||||||
|
|
||||||
static_assert( !std::is_nothrow_move_constructible<type3>::value,
|
static_assert( !std::is_nothrow_move_constructible<type3>::value,
|
||||||
"noexcept move constructor" );
|
"not noexcept move constructor" );
|
||||||
static_assert( !std::is_nothrow_constructible<type3, type3&&,
|
static_assert( !std::is_nothrow_constructible<type3, type3&&,
|
||||||
const typename type3::allocator_type&>::value,
|
const typename type3::allocator_type&>::value,
|
||||||
"not noexcept move constructor with allocator" );
|
"not noexcept move constructor with allocator" );
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user