]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Simplify noexcept-specifiers for move constructors
authorJonathan Wakely <jwakely@redhat.com>
Thu, 8 Apr 2021 15:29:11 +0000 (16:29 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 8 Apr 2021 16:49:59 +0000 (17:49 +0100)
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
libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc
libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc
libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc
libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc

index fa80675ad91e72e9631164639d25f7970e34823f..39872ce5342a55cb99b9a8391f2b9574ca7f54c9 100644 (file)
@@ -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),
index 96245aa4c8814a7e8a363e10847572ee69cfb68c..015646adf23132c3370ffbfd9d782fa42b57e92d 100644 (file)
@@ -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" );
index efc8d337e7e3fc5f407cceaace09d67bf61880ba..1e0b1059d7dad45da624f9a23bae6784cb54b914 100644 (file)
@@ -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" );
index cc2a8e31051eaebb2a458ba0d17ba972a9af911c..3e603802f13ea45faf578d6d8e80b054047e1865 100644 (file)
@@ -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" );
index f68095302d56fe92e305770471a6fedf0ef47fe2..28cb539e9f555359e0914f4ea344dd974f54775e 100644 (file)
@@ -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" );