hashtable_policy.h (_Prime_rehash_policy): Constructor noexcept qualified.
authorFrançois Dumont <fdumont@gcc.gnu.org>
Sat, 6 Sep 2014 07:38:48 +0000 (07:38 +0000)
committerFrançois Dumont <fdumont@gcc.gnu.org>
Sat, 6 Sep 2014 07:38:48 +0000 (07:38 +0000)
2014-09-06  François Dumont  <fdumont@gcc.gnu.org>

* 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
libstdc++-v3/include/bits/hashtable.h
libstdc++-v3/include/bits/hashtable_policy.h
libstdc++-v3/include/bits/unordered_map.h
libstdc++-v3/include/bits/unordered_set.h
libstdc++-v3/include/debug/unordered_map
libstdc++-v3/include/debug/unordered_set
libstdc++-v3/testsuite/23_containers/unordered_map/allocator/noexcept.cc
libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/noexcept.cc
libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/noexcept.cc
libstdc++-v3/testsuite/23_containers/unordered_set/allocator/noexcept.cc

index 573bc7dd1007fd5e1bc26d6e8941ee7d5adb2ec2..bf3f48db3fbe1d173d36327727ceb17f0b7fad31 100644 (file)
@@ -1,3 +1,28 @@
+2014-09-06  François Dumont  <fdumont@gcc.gnu.org>
+
+       * 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  <danglin@gcc.gnu.org>
 
        * config/abi/post/hppa-linux-gnu/baseline_symbols.txt: Update.
index 588e69c9d4d3e0be9b12ee031e9d52fb49615cd6..0eb58cfb6ed47e2e772dd3a6d52b07fa7d7a19fb 100644 (file)
@@ -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<typename _Key, typename _Value,
@@ -814,20 +820,20 @@ _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)
       {
        auto __nb_elems = __detail::__distance_fw(__f, __l);
-       _M_bucket_count =
+       auto __bkt_count =
          _M_rehash_policy._M_next_bkt(
            std::max(_M_rehash_policy._M_bkt_for_elements(__nb_elems),
                     __bucket_hint));
 
-       _M_buckets = _M_allocate_buckets(_M_bucket_count);
+       if (__bkt_count > _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<typename _Key, typename _Value,
index 606fbabbcdf162ac74b9ab7c7953177f7584912b..74d1bd011cf14c4325d792f1941b79f26ba76ecf 100644 (file)
@@ -460,7 +460,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// smallest prime that keeps the load factor small enough.
   struct _Prime_rehash_policy
   {
-    _Prime_rehash_policy(float __z = 1.0)
+    _Prime_rehash_policy(float __z = 1.0) noexcept
     : _M_max_load_factor(__z), _M_next_resize(0) { }
 
     float
@@ -1071,7 +1071,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef void*                                    __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, 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;
 
index 580aed9cc5cf0f8399e2edb2466f54cc034ea14c..019201d1dcca66e670583b1ec7f9189cfe3fffe0 100644 (file)
@@ -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())
index 3cf248d7d1cd19313e8189fb31d54d1fead8a990..161c6fbbe61e8dddf4d183b07e09688e1e81d2f0 100644 (file)
@@ -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())
index b1596e2907065c13ce309a9c9e8696bc09c27c16..b4ff69cfd8f7f35957b220148e7039add7ad979c 100644 (file)
@@ -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())
index 63a687760849ceb29877d7fd112262b52006cc10..f69f753ae493f4da7c09aa99e5babe3b3fb5243e 100644 (file)
@@ -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())
index 4e03e00997891084f114abbf35b8d9b8e9657294..9b282cfc45c0935d07f5e8b36aabb70e67c51a98 100644 (file)
@@ -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<int, int> test_type;
+  static_assert( noexcept( test_type() ), "Default constructor do not throw" );
+  static_assert( noexcept( test_type(test_type()) ), "Move constructor do not throw" );
+}
index 94cacbc094361f5ce968f168749c996d5977143f..aabf002559f639d233720459b83e4688e1d03702 100644 (file)
@@ -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<int, int> test_type;
+  static_assert( noexcept( test_type() ), "Default constructor do not throw" );
+  static_assert( noexcept( test_type(test_type()) ), "Move constructor do not throw" );
+}
index ecaac98c2ffb5e10f842254b41fa4d87b59192ab..bf5e0e7573f438d14cd6c01ce5ae0f2b7cb264d6 100644 (file)
@@ -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<int> test_type;
+  static_assert( noexcept( test_type() ), "Default constructor do not throw" );
+  static_assert( noexcept( test_type(test_type()) ), "Move constructor do not throw" );
+}
index 68787810fced1204b6a4e5218d77ed3fe0065f02..17c2dfaac162d44d16c704ab3d2347958c4b38a3 100644 (file)
@@ -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<int> test_type;
+  static_assert( noexcept( test_type() ), "Default constructor do not throw" );
+  static_assert( noexcept( test_type(test_type()) ), "Move constructor do not throw" );
+}