From da27f5567c0dd3fccf035e14bb7010a0538648e4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Dumont?= Date: Sat, 6 Sep 2014 07:38:48 +0000 Subject: [PATCH] hashtable_policy.h (_Prime_rehash_policy): Constructor noexcept qualified. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 2014-09-06 François Dumont * include/bits/hashtable_policy.h (_Prime_rehash_policy): Constructor noexcept qualified. (_Hash_code_base<>): All specialization default constructible if possible. (_Hashtable_base<>): Likewise. * include/bits/hashtable.h (_Hashtable<>()): Implementation defaulted. * include/bits/unordered_map.h (unordered_map<>::unordered_map()): New, implementation defaulted. (unordered_multimap<>::unordered_multimap()): Likewise. * include/bits/unordered_set.h (unordered_set<>::unordered_set()): Likewise. (unordered_multiset<>::unordered_multiset()): Likewise. * include/debug/unordered_map: Likewise. * include/debug/unordered_set: Likewise. * testsuite/23_containers/unordered_map/allocator/noexcept.cc (test04()): New. * testsuite/23_containers/unordered_multimap/allocator/noexcept.cc (test04()): New. * testsuite/23_containers/unordered_set/allocator/noexcept.cc (test04()): New. * testsuite/23_containers/unordered_multiset/allocator/noexcept.cc (test04()): New. From-SVN: r214986 --- libstdc++-v3/ChangeLog | 25 ++++++++ libstdc++-v3/include/bits/hashtable.h | 59 ++++++++++--------- libstdc++-v3/include/bits/hashtable_policy.h | 12 +++- libstdc++-v3/include/bits/unordered_map.h | 14 +++-- libstdc++-v3/include/bits/unordered_set.h | 16 +++-- libstdc++-v3/include/debug/unordered_map | 8 ++- libstdc++-v3/include/debug/unordered_set | 8 ++- .../unordered_map/allocator/noexcept.cc | 7 +++ .../unordered_multimap/allocator/noexcept.cc | 7 +++ .../unordered_multiset/allocator/noexcept.cc | 7 +++ .../unordered_set/allocator/noexcept.cc | 7 +++ 11 files changed, 128 insertions(+), 42 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 573bc7dd100..bf3f48db3fb 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,28 @@ +2014-09-06 François Dumont + + * include/bits/hashtable_policy.h (_Prime_rehash_policy): Constructor + noexcept qualified. + (_Hash_code_base<>): All specialization default constructible if + possible. + (_Hashtable_base<>): Likewise. + * include/bits/hashtable.h (_Hashtable<>()): Implementation defaulted. + * include/bits/unordered_map.h (unordered_map<>::unordered_map()): New, + implementation defaulted. + (unordered_multimap<>::unordered_multimap()): Likewise. + * include/bits/unordered_set.h + (unordered_set<>::unordered_set()): Likewise. + (unordered_multiset<>::unordered_multiset()): Likewise. + * include/debug/unordered_map: Likewise. + * include/debug/unordered_set: Likewise. + * testsuite/23_containers/unordered_map/allocator/noexcept.cc + (test04()): New. + * testsuite/23_containers/unordered_multimap/allocator/noexcept.cc + (test04()): New. + * testsuite/23_containers/unordered_set/allocator/noexcept.cc + (test04()): New. + * testsuite/23_containers/unordered_multiset/allocator/noexcept.cc + (test04()): New. + 2014-08-30 John David Anglin * config/abi/post/hppa-linux-gnu/baseline_symbols.txt: Update. diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index 588e69c9d4d..0eb58cfb6ed 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -310,10 +310,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const_local_iterator; private: - __bucket_type* _M_buckets; - size_type _M_bucket_count; + __bucket_type* _M_buckets = &_M_single_bucket; + size_type _M_bucket_count = 1; __node_base _M_before_begin; - size_type _M_element_count; + size_type _M_element_count = 0; _RehashPolicy _M_rehash_policy; // A single bucket used when only need for 1 bucket. Especially @@ -322,7 +322,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // qualified. // Note that we can't leave hashtable with 0 bucket without adding // numerous checks in the code to avoid 0 modulus. - __bucket_type _M_single_bucket; + __bucket_type _M_single_bucket = nullptr; bool _M_uses_single_bucket(__bucket_type* __bkts) const @@ -382,8 +382,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void _M_reset() noexcept; + _Hashtable(const _H1& __h1, const _H2& __h2, const _Hash& __h, + const _Equal& __eq, const _ExtractKey& __exk, + const allocator_type& __a) + : __hashtable_base(__exk, __h1, __h2, __h, __eq), + __hashtable_alloc(__node_alloc_type(__a)) + { } + public: // Constructor, destructor, assignment, swap + _Hashtable() = default; _Hashtable(size_type __bucket_hint, const _H1&, const _H2&, const _Hash&, const _Equal&, const _ExtractKey&, @@ -407,12 +415,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Use delegating constructors. explicit _Hashtable(const allocator_type& __a) - : _Hashtable(10, _H1(), _H2(), _Hash(), key_equal(), - __key_extract(), __a) + : __hashtable_alloc(__node_alloc_type(__a)) { } explicit - _Hashtable(size_type __n = 10, + _Hashtable(size_type __n, const _H1& __hf = _H1(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) @@ -791,15 +798,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const _H1& __h1, const _H2& __h2, const _Hash& __h, const _Equal& __eq, const _ExtractKey& __exk, const allocator_type& __a) - : __hashtable_base(__exk, __h1, __h2, __h, __eq), - __map_base(), - __rehash_base(), - __hashtable_alloc(__node_alloc_type(__a)), - _M_element_count(0), - _M_rehash_policy() + : _Hashtable(__h1, __h2, __h, __eq, __exk, __a) { - _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint); - _M_buckets = _M_allocate_buckets(_M_bucket_count); + auto __bkt = _M_rehash_policy._M_next_bkt(__bucket_hint); + if (__bkt > _M_bucket_count) + { + _M_buckets = _M_allocate_buckets(__bkt); + _M_bucket_count = __bkt; + } } template _M_bucket_count) + { + _M_buckets = _M_allocate_buckets(__bkt_count); + _M_bucket_count = __bkt_count; + } + __try { for (; __f != __l; ++__f) @@ -1101,7 +1107,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __rehash_base(__ht), __hashtable_alloc( __node_alloc_traits::_S_select_on_copy(__ht._M_node_allocator())), - _M_buckets(), + _M_buckets(nullptr), _M_bucket_count(__ht._M_bucket_count), _M_element_count(__ht._M_element_count), _M_rehash_policy(__ht._M_rehash_policy) @@ -1175,7 +1181,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __map_base(__ht), __rehash_base(__ht), __hashtable_alloc(__node_alloc_type(__a)), - _M_buckets(), + _M_buckets(nullptr), _M_bucket_count(__ht._M_bucket_count), _M_element_count(__ht._M_element_count), _M_rehash_policy(__ht._M_rehash_policy) @@ -1218,8 +1224,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ~_Hashtable() noexcept { clear(); - if (_M_buckets) - _M_deallocate_buckets(); + _M_deallocate_buckets(); } template __node_type; - // We need the default constructor for the local iterators. + // We need the default constructor for the local iterators and _Hashtable + // default constructor. _Hash_code_base() = default; _Hash_code_base(const _ExtractKey& __ex, const _H1&, const _H2&, @@ -1161,7 +1162,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef std::size_t __hash_code; typedef _Hash_node<_Value, false> __node_type; - // We need the default constructor for the local iterators. + // We need the default constructor for the local iterators and _Hashtable + // default constructor. _Hash_code_base() = default; _Hash_code_base(const _ExtractKey& __ex, @@ -1250,6 +1252,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef std::size_t __hash_code; typedef _Hash_node<_Value, true> __node_type; + // We need the default constructor for _Hashtable default constructor. + _Hash_code_base() = default; _Hash_code_base(const _ExtractKey& __ex, const _H1& __h1, const _H2& __h2, const _Default_ranged_hash&) @@ -1694,6 +1698,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __hash_code, __hash_cached::value>; protected: + _Hashtable_base() = default; _Hashtable_base(const _ExtractKey& __ex, const _H1& __h1, const _H2& __h2, const _Hash& __hash, const _Equal& __eq) : __hash_code_base(__ex, __h1, __h2, __hash), _EqualEBO(__eq) @@ -1906,6 +1911,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __alloc_rebind<__node_alloc_type, __bucket_type>; using __bucket_alloc_traits = std::allocator_traits<__bucket_alloc_type>; + _Hashtable_alloc() = default; _Hashtable_alloc(const _Hashtable_alloc&) = default; _Hashtable_alloc(_Hashtable_alloc&&) = default; diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h index 580aed9cc5c..019201d1dcc 100644 --- a/libstdc++-v3/include/bits/unordered_map.h +++ b/libstdc++-v3/include/bits/unordered_map.h @@ -128,15 +128,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER //construct/destroy/copy + /// Default constructor. + unordered_map() = default; + /** * @brief Default constructor creates no elements. - * @param __n Initial number of buckets. + * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. */ explicit - unordered_map(size_type __n = 10, + unordered_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) @@ -840,15 +843,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER //construct/destroy/copy + /// Default constructor. + unordered_multimap() = default; + /** * @brief Default constructor creates no elements. - * @param __n Initial number of buckets. + * @param __n Mnimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. */ explicit - unordered_multimap(size_type __n = 10, + unordered_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h index 3cf248d7d1c..161c6fbbe61 100644 --- a/libstdc++-v3/include/bits/unordered_set.h +++ b/libstdc++-v3/include/bits/unordered_set.h @@ -121,15 +121,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER //@} // construct/destroy/copy + + /// Default constructor. + unordered_set() = default; + /** * @brief Default constructor creates no elements. - * @param __n Initial number of buckets. + * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. */ explicit - unordered_set(size_type __n = 10, + unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) @@ -756,15 +760,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER //@} // construct/destroy/copy + + /// Default constructor. + unordered_multiset() = default; + /** * @brief Default constructor creates no elements. - * @param __n Initial number of buckets. + * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. */ explicit - unordered_multiset(size_type __n = 10, + unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map index b1596e29070..b4ff69cfd8f 100644 --- a/libstdc++-v3/include/debug/unordered_map +++ b/libstdc++-v3/include/debug/unordered_map @@ -82,8 +82,10 @@ namespace __debug typedef __gnu_debug::_Safe_local_iterator< _Base_const_local_iterator, unordered_map> const_local_iterator; + unordered_map() = default; + explicit - unordered_map(size_type __n = 10, + unordered_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) @@ -495,8 +497,10 @@ namespace __debug typedef __gnu_debug::_Safe_local_iterator< _Base_const_local_iterator, unordered_multimap> const_local_iterator; + unordered_multimap() = default; + explicit - unordered_multimap(size_type __n = 10, + unordered_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set index 63a68776084..f69f753ae49 100644 --- a/libstdc++-v3/include/debug/unordered_set +++ b/libstdc++-v3/include/debug/unordered_set @@ -82,8 +82,10 @@ namespace __debug typedef __gnu_debug::_Safe_local_iterator< _Base_const_local_iterator, unordered_set> const_local_iterator; + unordered_set() = default; + explicit - unordered_set(size_type __n = 10, + unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) @@ -491,8 +493,10 @@ namespace __debug typedef __gnu_debug::_Safe_local_iterator< _Base_const_local_iterator, unordered_multiset> const_local_iterator; + unordered_multiset() = default; + explicit - unordered_multiset(size_type __n = 10, + unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/noexcept.cc index 4e03e009978..9b282cfc45c 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/noexcept.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/noexcept.cc @@ -76,3 +76,10 @@ void test03() static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" ); static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" ); } + +void test04() +{ + typedef std::unordered_map test_type; + static_assert( noexcept( test_type() ), "Default constructor do not throw" ); + static_assert( noexcept( test_type(test_type()) ), "Move constructor do not throw" ); +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/noexcept.cc index 94cacbc0943..aabf002559f 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/noexcept.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/noexcept.cc @@ -76,3 +76,10 @@ void test03() static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" ); static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" ); } + +void test04() +{ + typedef std::unordered_multimap test_type; + static_assert( noexcept( test_type() ), "Default constructor do not throw" ); + static_assert( noexcept( test_type(test_type()) ), "Move constructor do not throw" ); +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/noexcept.cc index ecaac98c2ff..bf5e0e7573f 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/noexcept.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/noexcept.cc @@ -76,3 +76,10 @@ void test03() static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" ); static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" ); } + +void test04() +{ + typedef std::unordered_multiset test_type; + static_assert( noexcept( test_type() ), "Default constructor do not throw" ); + static_assert( noexcept( test_type(test_type()) ), "Move constructor do not throw" ); +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/noexcept.cc index 68787810fce..17c2dfaac16 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/noexcept.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/noexcept.cc @@ -76,3 +76,10 @@ void test03() static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" ); static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" ); } + +void test04() +{ + typedef std::unordered_set test_type; + static_assert( noexcept( test_type() ), "Default constructor do not throw" ); + static_assert( noexcept( test_type(test_type()) ), "Move constructor do not throw" ); +} -- 2.30.2