From 1cbba49e3417d9b0661e70301d6fb7a7f52fd360 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 8 Apr 2021 16:29:11 +0100 Subject: [PATCH] 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. --- libstdc++-v3/include/bits/hashtable.h | 26 ++++++++++++---------- .../unordered_map/cons/noexcept_move_construct.cc | 4 ++-- .../cons/noexcept_move_construct.cc | 4 ++-- .../cons/noexcept_move_construct.cc | 4 ++-- .../unordered_set/cons/noexcept_move_construct.cc | 4 ++-- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index fa80675..39872ce 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -472,10 +472,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __hashtable_alloc(__node_alloc_type(__a)) { } + template + 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), diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc index 96245aa..015646a 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc @@ -40,7 +40,7 @@ struct not_noexcept_copy_cons_hash using type2 = std::unordered_map; static_assert( !std::is_nothrow_move_constructible::value, - "noexcept move constructor" ); + "not noexcept move constructor" ); static_assert( !std::is_nothrow_constructible::value, "not noexcept move constructor with allocator" ); @@ -59,7 +59,7 @@ using type3 = std::unordered_map, not_noexcept_copy_cons_equal_to>; static_assert( !std::is_nothrow_move_constructible::value, - "noexcept move constructor" ); + "not noexcept move constructor" ); static_assert( !std::is_nothrow_constructible::value, "not noexcept move constructor with allocator" ); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc index efc8d33..1e0b105 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc @@ -40,7 +40,7 @@ struct not_noexcept_copy_cons_hash using type2 = std::unordered_multimap; static_assert( !std::is_nothrow_move_constructible::value, - "noexcept move constructor" ); + "not not noexcept move constructor" ); static_assert( !std::is_nothrow_constructible::value, "not noexcept move constructor with allocator" ); @@ -59,7 +59,7 @@ using type3 = std::unordered_multimap, not_noexcept_copy_cons_equal_to>; static_assert( !std::is_nothrow_move_constructible::value, - "noexcept move constructor" ); + "not not noexcept move constructor" ); static_assert( !std::is_nothrow_constructible::value, "not noexcept move constructor with allocator" ); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc index cc2a8e3..3e60380 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc @@ -40,7 +40,7 @@ struct not_noexcept_copy_cons_hash using type2 = std::unordered_multiset; static_assert( !std::is_nothrow_move_constructible::value, - "noexcept move constructor" ); + "not noexcept move constructor" ); static_assert( !std::is_nothrow_constructible::value, "not noexcept move constructor with allocator" ); @@ -59,7 +59,7 @@ using type3 = std::unordered_multiset, not_noexcept_copy_cons_equal_to>; static_assert( !std::is_nothrow_move_constructible::value, - "noexcept move constructor" ); + "not noexcept move constructor" ); static_assert( !std::is_nothrow_constructible::value, "not noexcept move constructor with allocator" ); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc index f680953..28cb539 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc @@ -40,7 +40,7 @@ struct not_noexcept_copy_cons_hash using type2 = std::unordered_set; static_assert( !std::is_nothrow_move_constructible::value, - "noexcept move constructor" ); + "not noexcept move constructor" ); static_assert( !std::is_nothrow_constructible::value, "not noexcept move constructor with allocator" ); @@ -59,7 +59,7 @@ using type3 = std::unordered_set, not_noexcept_copy_cons_equal_to>; static_assert( !std::is_nothrow_move_constructible::value, - "noexcept move constructor" ); + "not noexcept move constructor" ); static_assert( !std::is_nothrow_constructible::value, "not noexcept move constructor with allocator" ); -- 2.7.4