]> gcc.gnu.org Git - gcc.git/commitdiff
2013-08-06 Paolo Carlini <paolo.carlini@oracle.com>
authorPaolo Carlini <paolo.carlini@oracle.com>
Tue, 6 Aug 2013 11:11:07 +0000 (11:11 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 6 Aug 2013 11:11:07 +0000 (11:11 +0000)
Revert the last commit.

From-SVN: r201525

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/hashtable.h
libstdc++-v3/include/bits/hashtable_policy.h
libstdc++-v3/python/libstdcxx/v6/printers.py
libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc
libstdc++-v3/testsuite/23_containers/unordered_set/not_default_constructible_hash_neg.cc

index d389929be2c358de3c8a93722dba9d07d5de1fc5..66cbccc2c91e97a2ff23043217a1c4e3553ed12d 100644 (file)
@@ -1,3 +1,7 @@
+2013-08-06  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       Revert the last commit.
+
 2013-08-06  François Dumont  <fdumont@gcc.gnu.org>
 
        * include/bits/hashtable_policy.h (_Hashtable_alloc): New.
index 43c89b1ce515608b1b99d848fa525ff9afa4bd7e..44ce3b30ef8d64f9e07d1328abb8ea9f69afa900 100644 (file)
@@ -103,7 +103,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *  Each _Hashtable data structure has:
    *
    *  - _Bucket[]       _M_buckets
-   *  - _Hash_node_base _M_before_begin
+   *  - _Hash_node_base _M_bbegin
    *  - size_type       _M_bucket_count
    *  - size_type       _M_element_count
    *
@@ -181,26 +181,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       public __detail::_Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
                                    _H1, _H2, _Hash, _RehashPolicy, _Traits>,
       public __detail::_Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
-                                _H1, _H2, _Hash, _RehashPolicy, _Traits>,
-      private __detail::_Hashtable_alloc<
-       typename __alloctr_rebind<_Alloc,
-         __detail::_Hash_node<_Value,
-                              _Traits::__hash_cached::value> >::__type>
+                                _H1, _H2, _Hash, _RehashPolicy, _Traits>
     {
-      using __traits_type = _Traits;
-      using __hash_cached = typename __traits_type::__hash_cached;
-      using __node_type = __detail::_Hash_node<_Value, __hash_cached::value>;
-      using __node_alloc_type =
-       typename __alloctr_rebind<_Alloc, __node_type>::__type;
-
-      using __hashtable_alloc = __detail::_Hashtable_alloc<__node_alloc_type>;
-
-      using __value_alloc_traits =
-       typename __hashtable_alloc::__value_alloc_traits;
-      using __node_alloc_traits =
-       typename __hashtable_alloc::__node_alloc_traits;
-      using __node_base = typename __hashtable_alloc::__node_base;
-      using __bucket_type = typename __hashtable_alloc::__bucket_type;
+      typedef std::allocator_traits<_Alloc> _Alloc_traits;
+      typedef typename _Alloc_traits::template rebind_alloc<_Value>
+                                                       _Value_alloc_type;
+      typedef __gnu_cxx::__alloc_traits<_Value_alloc_type> _Value_alloc_traits;
 
     public:
       typedef _Key                                             key_type;
@@ -210,8 +196,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // mapped_type, if present, comes from _Map_base.
       // hasher, if present, comes from _Hash_code_base/_Hashtable_base.
-      typedef typename __value_alloc_traits::pointer           pointer;
-      typedef typename __value_alloc_traits::const_pointer     const_pointer;
+      typedef typename _Value_alloc_traits::pointer            pointer;
+      typedef typename _Value_alloc_traits::const_pointer      const_pointer;
       typedef value_type&                                      reference;
       typedef const value_type&                                        const_reference;
 
@@ -219,6 +205,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __rehash_type = _RehashPolicy;
       using __rehash_state = typename __rehash_type::_State;
 
+      using __traits_type = _Traits;
+      using __hash_cached = typename __traits_type::__hash_cached;
       using __constant_iterators = typename __traits_type::__constant_iterators;
       using __unique_keys = typename __traits_type::__unique_keys;
 
@@ -233,6 +221,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       using __hash_code_base =  typename __hashtable_base::__hash_code_base;
       using __hash_code =  typename __hashtable_base::__hash_code;
+      using __node_type = typename __hashtable_base::__node_type;
+      using __node_base = typename __hashtable_base::__node_base;
+      using __bucket_type = typename __hashtable_base::__bucket_type;
       using __ireturn_type = typename __hashtable_base::__ireturn_type;
 
       using __map_base = __detail::_Map_base<_Key, _Value, _Alloc, _ExtractKey,
@@ -249,7 +240,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                            _RehashPolicy, _Traits>;
 
       using __reuse_or_alloc_node_type =
-       __detail::_ReuseOrAllocNode<__node_alloc_type>;
+       __detail::_ReuseOrAllocNode<_Key, _Value, _Alloc,
+                                   _ExtractKey, _Equal, _H1, _H2, _Hash,
+                                   _RehashPolicy, _Traits>;
 
       // Metaprogramming for picking apart hash caching.
       template<typename _Cond>
@@ -316,6 +309,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
               bool _Constant_iteratorsa, bool _Unique_keysa>
        friend struct __detail::_Insert;
 
+      template<typename _Keya, typename _Valuea, typename _Alloca,
+              typename _ExtractKeya, typename _Equala,
+              typename _H1a, typename _H2a, typename _Hasha,
+              typename _RehashPolicya, typename _Traitsa>
+       friend struct __detail::_ReuseOrAllocNode;
+
+      template<typename _Keya, typename _Valuea, typename _Alloca,
+              typename _ExtractKeya, typename _Equala,
+              typename _H1a, typename _H2a, typename _Hasha,
+              typename _RehashPolicya, typename _Traitsa>
+       friend struct __detail::_AllocNode;
+
     public:
       using size_type = typename __hashtable_base::size_type;
       using difference_type = typename __hashtable_base::difference_type;
@@ -328,20 +333,60 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                   const_local_iterator;
 
     private:
+      typedef typename _Alloc_traits::template rebind_alloc<__node_type>
+                                                       _Node_alloc_type;
+      // Use __gnu_cxx to benefit from _S_always_equal and al.
+      typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
+
+      typedef
+      typename _Alloc_traits::template rebind_alloc<__bucket_type>
+                                                       _Bucket_alloc_type;
+      typedef std::allocator_traits<_Bucket_alloc_type> _Bucket_alloc_traits;
+
+      using __before_begin = __detail::_Before_begin<_Node_alloc_type>;
+
       __bucket_type*           _M_buckets;
       size_type                        _M_bucket_count;
-      __node_base              _M_before_begin;
+      __before_begin           _M_bbegin;
       size_type                        _M_element_count;
       _RehashPolicy            _M_rehash_policy;
 
-      __hashtable_alloc&
-      _M_base_alloc() { return *this; }
+      _Node_alloc_type&
+      _M_node_allocator()
+      { return _M_bbegin; }
+
+      const _Node_alloc_type&
+      _M_node_allocator() const
+      { return _M_bbegin; }
+
+      __node_base&
+      _M_before_begin()
+      { return _M_bbegin._M_node; }
+
+      const __node_base&
+      _M_before_begin() const
+      { return _M_bbegin._M_node; }
 
-      using __hashtable_alloc::_M_deallocate_buckets;
+      template<typename... _Args>
+       __node_type*
+       _M_allocate_node(_Args&&... __args);
+
+      void
+      _M_deallocate_node(__node_type* __n);
+
+      // Deallocate the linked list of nodes pointed to by __n
+      void
+      _M_deallocate_nodes(__node_type* __n);
+
+      __bucket_type*
+      _M_allocate_buckets(size_type __n);
+
+      void
+      _M_deallocate_buckets(__bucket_type*, size_type __n);
 
       void
       _M_deallocate_buckets()
-      { this->_M_deallocate_buckets(_M_buckets, _M_bucket_count); }
+      { _M_deallocate_buckets(_M_buckets, _M_bucket_count); }
 
       // Gets bucket begin, deals with the fact that non-empty buckets contain
       // their before begin node.
@@ -350,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       __node_type*
       _M_begin() const
-      { return static_cast<__node_type*>(_M_before_begin._M_nxt); }
+      { return static_cast<__node_type*>(_M_before_begin()._M_nxt); }
 
       template<typename _NodeGenerator>
        void
@@ -432,11 +477,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       _Hashtable&
       operator=(_Hashtable&& __ht)
-      noexcept(__node_alloc_traits::_S_nothrow_move())
+      noexcept(_Node_alloc_traits::_S_nothrow_move())
       {
         constexpr bool __move_storage =
-          __node_alloc_traits::_S_propagate_on_move_assign()
-          || __node_alloc_traits::_S_always_equal();
+          _Node_alloc_traits::_S_propagate_on_move_assign()
+          || _Node_alloc_traits::_S_always_equal();
         _M_move_assign(std::move(__ht),
                        integral_constant<bool, __move_storage>());
        return *this;
@@ -446,7 +491,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator=(initializer_list<value_type> __l)
       {
        __reuse_or_alloc_node_type __roan(_M_begin(), *this);
-       _M_before_begin._M_nxt = nullptr;
+       _M_before_begin()._M_nxt = nullptr;
        clear();
        this->_M_insert_range(__l.begin(), __l.end(), __roan);
        return *this;
@@ -456,7 +501,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       void
       swap(_Hashtable&)
-      noexcept(__node_alloc_traits::_S_nothrow_swap());
+      noexcept(_Node_alloc_traits::_S_nothrow_swap());
 
       // Basic container operations
       iterator
@@ -493,11 +538,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       allocator_type
       get_allocator() const noexcept
-      { return allocator_type(this->_M_node_allocator()); }
+      { return allocator_type(_M_node_allocator()); }
 
       size_type
       max_size() const noexcept
-      { return __node_alloc_traits::max_size(this->_M_node_allocator()); }
+      { return _Node_alloc_traits::max_size(_M_node_allocator()); }
 
       // Observers
       key_equal
@@ -758,6 +803,101 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 
   // Definitions of class template _Hashtable's out-of-line member functions.
+  template<typename _Key, typename _Value,
+          typename _Alloc, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          typename _Traits>
+    template<typename... _Args>
+      typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
+                         _H1, _H2, _Hash, _RehashPolicy, _Traits>::__node_type*
+      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
+                _H1, _H2, _Hash, _RehashPolicy, _Traits>::
+      _M_allocate_node(_Args&&... __args)
+      {
+       auto __nptr = _Node_alloc_traits::allocate(_M_node_allocator(), 1);
+       __node_type* __n = std::__addressof(*__nptr);
+       __try
+         {
+           _Value_alloc_type __a(_M_node_allocator());
+           ::new ((void*)__n) __node_type();
+           _Value_alloc_traits::construct(__a, __n->_M_valptr(),
+                                          std::forward<_Args>(__args)...);
+           return __n;
+         }
+       __catch(...)
+         {
+           _Node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
+           __throw_exception_again;
+         }
+      }
+
+  template<typename _Key, typename _Value,
+          typename _Alloc, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          typename _Traits>
+    void
+    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, _Traits>::
+    _M_deallocate_node(__node_type* __n)
+    {
+      typedef typename _Node_alloc_traits::pointer _Ptr;
+      auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__n);
+      _Value_alloc_type __a(_M_node_allocator());
+      _Value_alloc_traits::destroy(__a, __n->_M_valptr());
+      __n->~__node_type();
+      _Node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
+    }
+
+  template<typename _Key, typename _Value,
+          typename _Alloc, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          typename _Traits>
+    void
+    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, _Traits>::
+    _M_deallocate_nodes(__node_type* __n)
+    {
+      while (__n)
+       {
+         __node_type* __tmp = __n;
+         __n = __n->_M_next();
+         _M_deallocate_node(__tmp);
+       }
+    }
+
+  template<typename _Key, typename _Value,
+          typename _Alloc, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          typename _Traits>
+    typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy, _Traits>::__bucket_type*
+    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, _Traits>::
+    _M_allocate_buckets(size_type __n)
+    {
+      _Bucket_alloc_type __alloc(_M_node_allocator());
+
+      auto __ptr = _Bucket_alloc_traits::allocate(__alloc, __n);
+      __bucket_type* __p = std::__addressof(*__ptr);
+      __builtin_memset(__p, 0, __n * sizeof(__bucket_type));
+      return __p;
+    }
+
+  template<typename _Key, typename _Value,
+          typename _Alloc, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          typename _Traits>
+    void
+    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, _Traits>::
+    _M_deallocate_buckets(__bucket_type* __bkts, size_type __n)
+    {
+      typedef typename _Bucket_alloc_traits::pointer _Ptr;
+      auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__bkts);
+      _Bucket_alloc_type __alloc(_M_node_allocator());
+      _Bucket_alloc_traits::deallocate(__alloc, __ptr, __n);
+    }
+
   template<typename _Key, typename _Value,
           typename _Alloc, typename _ExtractKey, typename _Equal,
           typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
@@ -786,12 +926,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     : __hashtable_base(__exk, __h1, __h2, __h, __eq),
       __map_base(),
       __rehash_base(),
-      __hashtable_alloc(__node_alloc_type(__a)),
+      _M_bbegin(__a),
       _M_element_count(0),
       _M_rehash_policy()
     {
       _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint);
-      _M_buckets = this->_M_allocate_buckets(_M_bucket_count);
+      _M_buckets = _M_allocate_buckets(_M_bucket_count);
     }
 
   template<typename _Key, typename _Value,
@@ -809,7 +949,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       : __hashtable_base(__exk, __h1, __h2, __h, __eq),
        __map_base(),
        __rehash_base(),
-       __hashtable_alloc(__node_alloc_type(__a)),
+       _M_bbegin(__a),
        _M_element_count(0),
        _M_rehash_policy()
       {
@@ -819,7 +959,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            std::max(_M_rehash_policy._M_bkt_for_elements(__nb_elems),
                     __bucket_hint));
 
-       _M_buckets = this->_M_allocate_buckets(_M_bucket_count);
+       _M_buckets = _M_allocate_buckets(_M_bucket_count);
        __try
          {
            for (; __f != __l; ++__f)
@@ -847,15 +987,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        if (&__ht == this)
          return *this;
 
-       if (__node_alloc_traits::_S_propagate_on_copy_assign())
+       if (_Node_alloc_traits::_S_propagate_on_copy_assign())
          {
            auto& __this_alloc = this->_M_node_allocator();
            auto& __that_alloc = __ht._M_node_allocator();
-           if (!__node_alloc_traits::_S_always_equal()
+           if (!_Node_alloc_traits::_S_always_equal()
                && __this_alloc != __that_alloc)
              {
                // Replacement allocator cannot free existing storage.
-               this->_M_deallocate_nodes(_M_begin());
+               _M_deallocate_nodes(_M_begin());
                if (__builtin_expect(_M_bucket_count != 0, true))
                  _M_deallocate_buckets();
                _M_reset();
@@ -868,7 +1008,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                  {
                    _M_assign(__ht,
                              [this](const __node_type* __n)
-                             { return this->_M_allocate_node(__n->_M_v()); });
+                             { return _M_allocate_node(__n->_M_v()); });
                  }
                __catch(...)
                  {
@@ -890,7 +1030,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        if (_M_bucket_count != __ht._M_bucket_count)
          {
            __former_buckets = _M_buckets;
-           _M_buckets = this->_M_allocate_buckets(__ht._M_bucket_count);
+           _M_buckets = _M_allocate_buckets(__ht._M_bucket_count);
            _M_bucket_count = __ht._M_bucket_count;
          }
        else
@@ -903,13 +1043,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            _M_element_count = __ht._M_element_count;
            _M_rehash_policy = __ht._M_rehash_policy;
            __reuse_or_alloc_node_type __roan(_M_begin(), *this);
-           _M_before_begin._M_nxt = nullptr;
+           _M_before_begin()._M_nxt = nullptr;
            _M_assign(__ht, 
                      [&__roan](const __node_type* __n)
                      { return __roan(__n->_M_v()); });
            if (__former_buckets)
-             this->_M_deallocate_buckets(__former_buckets,
-                                         __former_bucket_count);
+             _M_deallocate_buckets(__former_buckets, __former_bucket_count);
          }
        __catch(...)
          {
@@ -940,11 +1079,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
        __bucket_type* __buckets = nullptr;
        if (!_M_buckets)
-         _M_buckets = __buckets = this->_M_allocate_buckets(_M_bucket_count);
+         _M_buckets = __buckets = _M_allocate_buckets(_M_bucket_count);
 
        __try
          {
-           if (!__ht._M_before_begin._M_nxt)
+           if (!__ht._M_before_begin()._M_nxt)
              return;
 
            // First deal with the special first node pointed to by
@@ -952,8 +1091,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            __node_type* __ht_n = __ht._M_begin();
            __node_type* __this_n = __node_gen(__ht_n);
            this->_M_copy_code(__this_n, __ht_n);
-           _M_before_begin._M_nxt = __this_n;
-           _M_buckets[_M_bucket_index(__this_n)] = &_M_before_begin;
+           _M_before_begin()._M_nxt = __this_n;
+           _M_buckets[_M_bucket_index(__this_n)] = &_M_before_begin();
 
            // Then deal with other nodes.
            __node_base* __prev_n = __this_n;
@@ -989,7 +1128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rehash_policy._M_reset();
       _M_bucket_count = 0;
       _M_buckets = nullptr;
-      _M_before_begin._M_nxt = nullptr;
+      _M_before_begin()._M_nxt = nullptr;
       _M_element_count = 0;
     }
 
@@ -1002,7 +1141,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
               _H1, _H2, _Hash, _RehashPolicy, _Traits>::
     _M_move_assign(_Hashtable&& __ht, std::true_type)
     {
-      this->_M_deallocate_nodes(_M_begin());
+      _M_deallocate_nodes(_M_begin());
       if (__builtin_expect(_M_bucket_count != 0, true))
        _M_deallocate_buckets();
 
@@ -1010,14 +1149,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rehash_policy = __ht._M_rehash_policy;
       _M_buckets = __ht._M_buckets;
       _M_bucket_count = __ht._M_bucket_count;
-      _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt;
+      _M_before_begin()._M_nxt = __ht._M_before_begin()._M_nxt;
       _M_element_count = __ht._M_element_count;
-      std::__alloc_on_move(this->_M_node_allocator(), __ht._M_node_allocator());
+      std::__alloc_on_move(_M_node_allocator(), __ht._M_node_allocator());
 
       // Fix buckets containing the _M_before_begin pointers that can't be
       // moved.
       if (_M_begin())
-       _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
+       _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin();
       __ht._M_reset();
     }
 
@@ -1030,7 +1169,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
               _H1, _H2, _Hash, _RehashPolicy, _Traits>::
     _M_move_assign(_Hashtable&& __ht, std::false_type)
     {
-      if (__ht._M_node_allocator() == this->_M_node_allocator())
+      if (__ht._M_node_allocator() == _M_node_allocator())
        _M_move_assign(std::move(__ht), std::true_type());
       else
        {
@@ -1042,7 +1181,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          if (_M_bucket_count != __ht._M_bucket_count)
            {
              __former_buckets = _M_buckets;
-             _M_buckets = this->_M_allocate_buckets(__ht._M_bucket_count);
+             _M_buckets = _M_allocate_buckets(__ht._M_bucket_count);
              _M_bucket_count = __ht._M_bucket_count;
            }
          else
@@ -1055,7 +1194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              _M_element_count = __ht._M_element_count;
              _M_rehash_policy = __ht._M_rehash_policy;
              __reuse_or_alloc_node_type __roan(_M_begin(), *this);
-             _M_before_begin._M_nxt = nullptr;
+             _M_before_begin()._M_nxt = nullptr;
              _M_assign(__ht,
                        [&__roan](__node_type* __n)
                        { return __roan(std::move_if_noexcept(__n->_M_v())); });
@@ -1087,16 +1226,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     : __hashtable_base(__ht),
       __map_base(__ht),
       __rehash_base(__ht),
-      __hashtable_alloc(
-       __node_alloc_traits::_S_select_on_copy(__ht._M_node_allocator())),
       _M_buckets(),
       _M_bucket_count(__ht._M_bucket_count),
+      _M_bbegin(_Node_alloc_traits::_S_select_on_copy(
+               __ht._M_node_allocator())),
       _M_element_count(__ht._M_element_count),
       _M_rehash_policy(__ht._M_rehash_policy)
     {
       _M_assign(__ht,
                [this](const __node_type* __n)
-               { return this->_M_allocate_node(__n->_M_v()); });
+               { return _M_allocate_node(__n->_M_v()); });
     }
 
   template<typename _Key, typename _Value,
@@ -1109,17 +1248,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     : __hashtable_base(__ht),
       __map_base(__ht),
       __rehash_base(__ht),
-      __hashtable_alloc(std::move(__ht._M_base_alloc())),
       _M_buckets(__ht._M_buckets),
       _M_bucket_count(__ht._M_bucket_count),
-      _M_before_begin(__ht._M_before_begin._M_nxt),
+      _M_bbegin(std::move(__ht._M_bbegin)),
       _M_element_count(__ht._M_element_count),
       _M_rehash_policy(__ht._M_rehash_policy)
     {
       // Update, if necessary, bucket pointing to before begin that hasn't
       // moved.
       if (_M_begin())
-       _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
+       _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin();
       __ht._M_reset();
     }
 
@@ -1133,15 +1271,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     : __hashtable_base(__ht),
       __map_base(__ht),
       __rehash_base(__ht),
-      __hashtable_alloc(__node_alloc_type(__a)),
       _M_buckets(),
       _M_bucket_count(__ht._M_bucket_count),
+      _M_bbegin(_Node_alloc_type(__a)),
       _M_element_count(__ht._M_element_count),
       _M_rehash_policy(__ht._M_rehash_policy)
     {
       _M_assign(__ht,
                [this](const __node_type* __n)
-               { return this->_M_allocate_node(__n->_M_v()); });
+               { return _M_allocate_node(__n->_M_v()); });
     }
 
   template<typename _Key, typename _Value,
@@ -1154,20 +1292,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     : __hashtable_base(__ht),
       __map_base(__ht),
       __rehash_base(__ht),
-      __hashtable_alloc(__node_alloc_type(__a)),
       _M_buckets(),
       _M_bucket_count(__ht._M_bucket_count),
+      _M_bbegin(_Node_alloc_type(__a)),
       _M_element_count(__ht._M_element_count),
       _M_rehash_policy(__ht._M_rehash_policy)
     {
-      if (__ht._M_node_allocator() == this->_M_node_allocator())
+      if (__ht._M_node_allocator() == _M_node_allocator())
        {
          _M_buckets = __ht._M_buckets;
-         _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt;
+         _M_before_begin()._M_nxt = __ht._M_before_begin()._M_nxt;
          // Update, if necessary, bucket pointing to before begin that hasn't
          // moved.
          if (_M_begin())
-           _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
+           _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin();
          __ht._M_reset();
        }
       else
@@ -1175,7 +1313,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          _M_assign(__ht,
                    [this](__node_type* __n)
                    {
-                     return this->_M_allocate_node(
+                     return _M_allocate_node(
                                        std::move_if_noexcept(__n->_M_v()));
                    });
          __ht.clear();
@@ -1203,27 +1341,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
               _H1, _H2, _Hash, _RehashPolicy, _Traits>::
     swap(_Hashtable& __x)
-    noexcept(__node_alloc_traits::_S_nothrow_swap())
+    noexcept(_Node_alloc_traits::_S_nothrow_swap())
     {
       // The only base class with member variables is hash_code_base.
       // We define _Hash_code_base::_M_swap because different
       // specializations have different members.
       this->_M_swap(__x);
 
-      std::__alloc_on_swap(this->_M_node_allocator(), __x._M_node_allocator());
+      std::__alloc_on_swap(_M_node_allocator(), __x._M_node_allocator());
       std::swap(_M_rehash_policy, __x._M_rehash_policy);
       std::swap(_M_buckets, __x._M_buckets);
       std::swap(_M_bucket_count, __x._M_bucket_count);
-      std::swap(_M_before_begin._M_nxt, __x._M_before_begin._M_nxt);
+      std::swap(_M_before_begin()._M_nxt, __x._M_before_begin()._M_nxt);
       std::swap(_M_element_count, __x._M_element_count);
 
       // Fix buckets containing the _M_before_begin pointers that can't be
       // swapped.
       if (_M_begin())
-       _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
+       _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin();
       if (__x._M_begin())
        __x._M_buckets[__x._M_bucket_index(__x._M_begin())]
-         = &__x._M_before_begin;
+         = &(__x._M_before_begin());
     }
 
   template<typename _Key, typename _Value,
@@ -1442,13 +1580,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          // The bucket is empty, the new node is inserted at the
          // beginning of the singly-linked list and the bucket will
          // contain _M_before_begin pointer.
-         __node->_M_nxt = _M_before_begin._M_nxt;
-         _M_before_begin._M_nxt = __node;
+         __node->_M_nxt = _M_before_begin()._M_nxt;
+         _M_before_begin()._M_nxt = __node;
          if (__node->_M_nxt)
            // We must update former begin bucket that is pointing to
            // _M_before_begin.
            _M_buckets[_M_bucket_index(__node->_M_next())] = __node;
-         _M_buckets[__bkt] = &_M_before_begin;
+         _M_buckets[__bkt] = &_M_before_begin();
        }
     }
 
@@ -1470,8 +1608,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            _M_buckets[__next_bkt] = _M_buckets[__bkt];
 
          // Second update before begin node if necessary
-         if (&_M_before_begin == _M_buckets[__bkt])
-           _M_before_begin._M_nxt = __next;
+         if (&_M_before_begin() == _M_buckets[__bkt])
+           _M_before_begin()._M_nxt = __next;
          _M_buckets[__bkt] = nullptr;
        }
     }
@@ -1507,7 +1645,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_emplace(std::true_type, _Args&&... __args)
       {
        // First build the node to get access to the hash code
-       __node_type* __node = this->_M_allocate_node(std::forward<_Args>(__args)...);
+       __node_type* __node = _M_allocate_node(std::forward<_Args>(__args)...);
        const key_type& __k = this->_M_extract()(__node->_M_v());
        __hash_code __code;
        __try
@@ -1516,7 +1654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          }
        __catch(...)
          {
-           this->_M_deallocate_node(__node);
+           _M_deallocate_node(__node);
            __throw_exception_again;
          }
 
@@ -1524,7 +1662,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        if (__node_type* __p = _M_find_node(__bkt, __k, __code))
          {
            // There is already an equivalent node, no insertion
-           this->_M_deallocate_node(__node);
+           _M_deallocate_node(__node);
            return std::make_pair(iterator(__p), false);
          }
 
@@ -1546,8 +1684,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_emplace(const_iterator __hint, std::false_type, _Args&&... __args)
       {
        // First build the node to get its hash code.
-       __node_type* __node =
-         this->_M_allocate_node(std::forward<_Args>(__args)...);
+       __node_type* __node = _M_allocate_node(std::forward<_Args>(__args)...);
 
        __hash_code __code;
        __try
@@ -1556,7 +1693,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          }
        __catch(...)
          {
-           this->_M_deallocate_node(__node);
+           _M_deallocate_node(__node);
            __throw_exception_again;
          }
 
@@ -1596,7 +1733,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        }
       __catch(...)
        {
-         this->_M_deallocate_node(__node);
+         _M_deallocate_node(__node);
          __throw_exception_again;
        }
     }
@@ -1662,7 +1799,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        }
       __catch(...)
        {
-         this->_M_deallocate_node(__node);
+         _M_deallocate_node(__node);
          __throw_exception_again;
        }
     }
@@ -1762,7 +1899,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       __prev_n->_M_nxt = __n->_M_nxt;
       iterator __result(__n->_M_next());
-      this->_M_deallocate_node(__n);
+      _M_deallocate_node(__n);
       --_M_element_count;
 
       return __result;
@@ -1835,7 +1972,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       do
        {
          __node_type* __p = __n->_M_next();
-         this->_M_deallocate_node(__n);
+         _M_deallocate_node(__n);
          __n = __p;
          ++__result;
          --_M_element_count;
@@ -1877,7 +2014,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            {
              __node_type* __tmp = __n;
              __n = __n->_M_next();
-             this->_M_deallocate_node(__tmp);
+             _M_deallocate_node(__tmp);
              --_M_element_count;
              if (!__n)
                break;
@@ -1907,10 +2044,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
               _H1, _H2, _Hash, _RehashPolicy, _Traits>::
     clear() noexcept
     {
-      this->_M_deallocate_nodes(_M_begin());
+      _M_deallocate_nodes(_M_begin());
       __builtin_memset(_M_buckets, 0, _M_bucket_count * sizeof(__bucket_type));
       _M_element_count = 0;
-      _M_before_begin._M_nxt = nullptr;
+      _M_before_begin()._M_nxt = nullptr;
     }
 
   template<typename _Key, typename _Value,
@@ -1967,9 +2104,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
               _H1, _H2, _Hash, _RehashPolicy, _Traits>::
     _M_rehash_aux(size_type __n, std::true_type)
     {
-      __bucket_type* __new_buckets = this->_M_allocate_buckets(__n);
+      __bucket_type* __new_buckets = _M_allocate_buckets(__n);
       __node_type* __p = _M_begin();
-      _M_before_begin._M_nxt = nullptr;
+      _M_before_begin()._M_nxt = nullptr;
       std::size_t __bbegin_bkt = 0;
       while (__p)
        {
@@ -1977,9 +2114,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          std::size_t __bkt = __hash_code_base::_M_bucket_index(__p, __n);
          if (!__new_buckets[__bkt])
            {
-             __p->_M_nxt = _M_before_begin._M_nxt;
-             _M_before_begin._M_nxt = __p;
-             __new_buckets[__bkt] = &_M_before_begin;
+             __p->_M_nxt = _M_before_begin()._M_nxt;
+             _M_before_begin()._M_nxt = __p;
+             __new_buckets[__bkt] = &_M_before_begin();
              if (__p->_M_nxt)
                __new_buckets[__bbegin_bkt] = __p;
              __bbegin_bkt = __bkt;
@@ -2009,10 +2146,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
               _H1, _H2, _Hash, _RehashPolicy, _Traits>::
     _M_rehash_aux(size_type __n, std::false_type)
     {
-      __bucket_type* __new_buckets = this->_M_allocate_buckets(__n);
+      __bucket_type* __new_buckets = _M_allocate_buckets(__n);
 
       __node_type* __p = _M_begin();
-      _M_before_begin._M_nxt = nullptr;
+      _M_before_begin()._M_nxt = nullptr;
       std::size_t __bbegin_bkt = 0;
       std::size_t __prev_bkt = 0;
       __node_type* __prev_p = nullptr;
@@ -2057,9 +2194,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
              if (!__new_buckets[__bkt])
                {
-                 __p->_M_nxt = _M_before_begin._M_nxt;
-                 _M_before_begin._M_nxt = __p;
-                 __new_buckets[__bkt] = &_M_before_begin;
+                 __p->_M_nxt = _M_before_begin()._M_nxt;
+                 _M_before_begin()._M_nxt = __p;
+                 __new_buckets[__bkt] = &_M_before_begin();
                  if (__p->_M_nxt)
                    __new_buckets[__bbegin_bkt] = __p;
                  __bbegin_bkt = __bkt;
index 61b852f62df43200dd6002016259f6a908893494..a95b8d4f6a545457b33645ff84913efd785d7076 100644 (file)
@@ -102,26 +102,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return std::get<0>(std::forward<_Tp>(__x)); }
   };
 
-  template<typename _NodeAlloc>
-    struct _Hashtable_alloc;
-
   // Functor recycling a pool of nodes and using allocation once the pool is
   // empty.
-  template<typename _NodeAlloc>
+  template<typename _Key, typename _Value, typename _Alloc,
+          typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash,
+          typename _RehashPolicy, typename _Traits>
     struct _ReuseOrAllocNode
     {
     private:
-      using __node_alloc_type = _NodeAlloc;
-      using __hashtable_alloc = _Hashtable_alloc<__node_alloc_type>;
-      using __value_alloc_type = typename __hashtable_alloc::__value_alloc_type;
-      using __value_alloc_traits =
-       typename __hashtable_alloc::__value_alloc_traits;
-      using __node_alloc_traits =
-       typename __hashtable_alloc::__node_alloc_traits;
-      using __node_type = typename __hashtable_alloc::__node_type;
+      using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
+                                    _Equal, _H1, _H2, _Hash,
+                                    _RehashPolicy, _Traits>;
+      using __val_alloc_type = typename __hashtable::_Value_alloc_type;
+      using __val_alloc_traits = typename __hashtable::_Value_alloc_traits;
+      using __node_alloc_traits = typename __hashtable::_Node_alloc_traits;
+      using __node_type = typename __hashtable::__node_type;
 
     public:
-      _ReuseOrAllocNode(__node_type* __nodes, __hashtable_alloc& __h)
+      _ReuseOrAllocNode(__node_type* __nodes, __hashtable& __h)
        : _M_nodes(__nodes), _M_h(__h) { }
       _ReuseOrAllocNode(const _ReuseOrAllocNode&) = delete;
 
@@ -137,12 +136,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              __node_type* __node = _M_nodes;
              _M_nodes = _M_nodes->_M_next();
              __node->_M_nxt = nullptr;
-             __value_alloc_type __a(_M_h._M_node_allocator());
-             __value_alloc_traits::destroy(__a, __node->_M_valptr());
+             __val_alloc_type __a(_M_h._M_node_allocator());
+             __val_alloc_traits::destroy(__a, __node->_M_valptr());
              __try
                {
-                 __value_alloc_traits::construct(__a, __node->_M_valptr(),
-                                                 std::forward<_Arg>(__arg));
+                 __val_alloc_traits::construct(__a, __node->_M_valptr(),
+                                               std::forward<_Arg>(__arg));
                }
              __catch(...)
                {
@@ -158,19 +157,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     private:
       mutable __node_type* _M_nodes;
-      __hashtable_alloc& _M_h;
+      __hashtable& _M_h;
     };
 
   // Functor similar to the previous one but without any pool of node to recycle.
-  template<typename _NodeAlloc>
+  template<typename _Key, typename _Value, typename _Alloc,
+          typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash,
+          typename _RehashPolicy, typename _Traits>
     struct _AllocNode
     {
     private:
-      using __hashtable_alloc = _Hashtable_alloc<_NodeAlloc>;
-      using __node_type = typename __hashtable_alloc::__node_type;
+      using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
+                                    _Equal, _H1, _H2, _Hash,
+                                    _RehashPolicy, _Traits>;
+      using __node_type = typename __hashtable::__node_type;
 
     public:
-      _AllocNode(__hashtable_alloc& __h)
+      _AllocNode(__hashtable& __h)
        : _M_h(__h) { }
 
       template<typename _Arg>
@@ -179,7 +183,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        { return _M_h._M_allocate_node(std::forward<_Arg>(__arg)); }
 
     private:
-      __hashtable_alloc& _M_h;
+      __hashtable& _M_h;
     };
 
   // Auxiliary types used for all instantiations of _Hashtable nodes
@@ -243,8 +247,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Value>
     struct _Hash_node_value_base : _Hash_node_base
     {
-      typedef _Value value_type;
-
       __gnu_cxx::__aligned_buffer<_Value> _M_storage;
 
       _Value*
@@ -334,9 +336,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __node_type = typename __base_type::__node_type;
 
     public:
-      typedef _Value                                   value_type;
-      typedef std::ptrdiff_t                           difference_type;
-      typedef std::forward_iterator_tag                        iterator_category;
+      typedef _Value                                   value_type;
+      typedef std::ptrdiff_t                           difference_type;
+      typedef std::forward_iterator_tag                iterator_category;
 
       using pointer = typename std::conditional<__constant_iterators,
                                                const _Value*, _Value*>::type;
@@ -385,12 +387,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __node_type = typename __base_type::__node_type;
 
     public:
-      typedef _Value                                   value_type;
-      typedef std::ptrdiff_t                           difference_type;
-      typedef std::forward_iterator_tag                        iterator_category;
+      typedef _Value                                   value_type;
+      typedef std::ptrdiff_t                           difference_type;
+      typedef std::forward_iterator_tag                iterator_category;
 
-      typedef const _Value*                            pointer;
-      typedef const _Value&                            reference;
+      typedef const _Value*                            pointer;
+      typedef const _Value&                            reference;
 
       _Node_const_iterator()
       : __base_type(0) { }
@@ -497,8 +499,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     static const std::size_t _S_growth_factor = 2;
 
-    float              _M_max_load_factor;
-    mutable std::size_t        _M_next_resize;
+    float                _M_max_load_factor;
+    mutable std::size_t  _M_next_resize;
   };
 
   // Base classes for std::_Hashtable.  We define these base classes
@@ -695,10 +697,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       using __unique_keys = typename __hashtable_base::__unique_keys;
       using __ireturn_type = typename __hashtable_base::__ireturn_type;
-      using __node_type = _Hash_node<_Value, _Traits::__hash_cached::value>;
-      using __node_alloc_type =
-       typename __alloctr_rebind<_Alloc, __node_type>::__type;
-      using __node_gen_type = _AllocNode<__node_alloc_type>;
+      using __node_gen_type = _AllocNode<_Key, _Value, _Alloc, _ExtractKey,
+                                        _Equal, _H1, _H2, _Hash,
+                                        _RehashPolicy, _Traits>;
 
       __hashtable&
       _M_conjure_hashtable()
@@ -978,10 +979,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       _Hashtable_ebo_helper() = default;
 
-      template<typename _OtherTp>
-       _Hashtable_ebo_helper(_OtherTp&& __tp)
-         : _Tp(std::forward<_OtherTp>(__tp))
-       { }
+      _Hashtable_ebo_helper(const _Tp& __tp) : _Tp(__tp)
+      { }
 
       static const _Tp&
       _S_cget(const _Hashtable_ebo_helper& __eboh)
@@ -998,10 +997,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       _Hashtable_ebo_helper() = default;
 
-      template<typename _OtherTp>
-       _Hashtable_ebo_helper(_OtherTp&& __tp)
-         : _M_tp(std::forward<_OtherTp>(__tp))
-       { }
+      _Hashtable_ebo_helper(const _Tp& __tp) : _M_tp(__tp)
+      { }
 
       static const _Tp&
       _S_cget(const _Hashtable_ebo_helper& __eboh)
@@ -1434,15 +1431,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                               _H1, _H2, _Hash, __cache>;
       using __hash_code_base = typename __base_type::__hash_code_base;
     public:
-      typedef _Value                                   value_type;
+      typedef _Value                                   value_type;
       typedef typename std::conditional<__constant_iterators,
                                        const _Value*, _Value*>::type
                                                       pointer;
       typedef typename std::conditional<__constant_iterators,
                                        const _Value&, _Value&>::type
                                                       reference;
-      typedef std::ptrdiff_t                           difference_type;
-      typedef std::forward_iterator_tag                        iterator_category;
+      typedef std::ptrdiff_t                           difference_type;
+      typedef std::forward_iterator_tag                iterator_category;
 
       _Local_iterator() = default;
 
@@ -1490,11 +1487,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __hash_code_base = typename __base_type::__hash_code_base;
 
     public:
-      typedef _Value                                   value_type;
-      typedef const _Value*                            pointer;
-      typedef const _Value&                            reference;
-      typedef std::ptrdiff_t                           difference_type;
-      typedef std::forward_iterator_tag                        iterator_category;
+      typedef _Value                                   value_type;
+      typedef const _Value*                            pointer;
+      typedef const _Value&                            reference;
+      typedef std::ptrdiff_t                           difference_type;
+      typedef std::forward_iterator_tag                iterator_category;
 
       _Local_const_iterator() = default;
 
@@ -1554,11 +1551,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     private _Hashtable_ebo_helper<0, _Equal>
   {
   public:
-    typedef _Key                                       key_type;
-    typedef _Value                                     value_type;
-    typedef _Equal                                     key_equal;
-    typedef std::size_t                                        size_type;
-    typedef std::ptrdiff_t                             difference_type;
+    typedef _Key                                    key_type;
+    typedef _Value                                  value_type;
+    typedef _Equal                                  key_equal;
+    typedef std::size_t                             size_type;
+    typedef std::ptrdiff_t                          difference_type;
 
     using __traits_type = _Traits;
     using __hash_cached = typename __traits_type::__hash_cached;
@@ -1600,6 +1597,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                        __hash_code, __hash_cached::value>;
 
   protected:
+    using __node_base = __detail::_Hash_node_base;
+    using __bucket_type = __node_base*;
+
     _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)
@@ -1787,136 +1787,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
   /**
-   * This type deals with all allocation and keeps an allocator instance through
-   * inheritance to benefit from EBO when possible.
+   * This type is to combine a _Hash_node_base instance with an allocator
+   * instance through inheritance to benefit from EBO when possible.
    */
   template<typename _NodeAlloc>
-    struct _Hashtable_alloc : private _Hashtable_ebo_helper<0, _NodeAlloc>
+    struct _Before_begin : public _NodeAlloc
     {
-    private:
-      using __ebo_node_alloc = _Hashtable_ebo_helper<0, _NodeAlloc>;
-    public:
-      using __node_type = typename _NodeAlloc::value_type;
-      using __node_alloc_type = _NodeAlloc;
-      // Use __gnu_cxx to benefit from _S_always_equal and al.
-      using __node_alloc_traits = __gnu_cxx::__alloc_traits<__node_alloc_type>;
-
-      using __value_type = typename __node_type::value_type;
-      using __value_alloc_type =
-       typename __alloctr_rebind<__node_alloc_type, __value_type>::__type;
-      using __value_alloc_traits = std::allocator_traits<__value_alloc_type>;
+      _Hash_node_base _M_node;
 
-      using __node_base = __detail::_Hash_node_base;
-      using __bucket_type = __node_base*;      
-      using __bucket_alloc_type =
-       typename __alloctr_rebind<__node_alloc_type, __bucket_type>::__type;
-      using __bucket_alloc_traits = std::allocator_traits<__bucket_alloc_type>;
-
-      _Hashtable_alloc(const _Hashtable_alloc&) = default;
-      _Hashtable_alloc(_Hashtable_alloc&&) = default;
+      _Before_begin(const _Before_begin&) = default;
+      _Before_begin(_Before_begin&&) = default;
 
       template<typename _Alloc>
-       _Hashtable_alloc(_Alloc&& __a)
-         : __ebo_node_alloc(std::forward<_Alloc>(__a))
+       _Before_begin(_Alloc&& __a)
+         : _NodeAlloc(std::forward<_Alloc>(__a))
        { }
-
-      __node_alloc_type&
-      _M_node_allocator()
-      { return __ebo_node_alloc::_S_get(*this); }
-
-      const __node_alloc_type&
-      _M_node_allocator() const
-      { return __ebo_node_alloc::_S_cget(*this); }
-
-      template<typename... _Args>
-       __node_type*
-       _M_allocate_node(_Args&&... __args);
-
-      void
-      _M_deallocate_node(__node_type* __n);
-
-      // Deallocate the linked list of nodes pointed to by __n
-      void
-      _M_deallocate_nodes(__node_type* __n);
-
-      __bucket_type*
-      _M_allocate_buckets(std::size_t __n);
-
-      void
-      _M_deallocate_buckets(__bucket_type*, std::size_t __n);
     };
 
-  // Definitions of class template _Hashtable_alloc's out-of-line member
-  // functions.
-  template<typename _NodeAlloc>
-    template<typename... _Args>
-      typename _Hashtable_alloc<_NodeAlloc>::__node_type*
-      _Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&&... __args)
-      {
-       auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1);
-       __node_type* __n = std::__addressof(*__nptr);
-       __try
-         {
-           __value_alloc_type __a(_M_node_allocator());
-           ::new ((void*)__n) __node_type();
-           __value_alloc_traits::construct(__a, __n->_M_valptr(),
-                                           std::forward<_Args>(__args)...);
-           return __n;
-         }
-       __catch(...)
-         {
-           __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
-           __throw_exception_again;
-         }
-      }
-
-  template<typename _NodeAlloc>
-    void
-    _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(__node_type* __n)
-    {
-      typedef typename __node_alloc_traits::pointer _Ptr;
-      auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__n);
-      __value_alloc_type __a(_M_node_allocator());
-      __value_alloc_traits::destroy(__a, __n->_M_valptr());
-      __n->~__node_type();
-      __node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
-    }
-
-  template<typename _NodeAlloc>
-    void
-    _Hashtable_alloc<_NodeAlloc>::_M_deallocate_nodes(__node_type* __n)
-    {
-      while (__n)
-       {
-         __node_type* __tmp = __n;
-         __n = __n->_M_next();
-         _M_deallocate_node(__tmp);
-       }
-    }
-
-  template<typename _NodeAlloc>
-    typename _Hashtable_alloc<_NodeAlloc>::__bucket_type*
-    _Hashtable_alloc<_NodeAlloc>::_M_allocate_buckets(std::size_t __n)
-    {
-      __bucket_alloc_type __alloc(_M_node_allocator());
-
-      auto __ptr = __bucket_alloc_traits::allocate(__alloc, __n);
-      __bucket_type* __p = std::__addressof(*__ptr);
-      __builtin_memset(__p, 0, __n * sizeof(__bucket_type));
-      return __p;
-    }
-
-  template<typename _NodeAlloc>
-    void
-    _Hashtable_alloc<_NodeAlloc>::_M_deallocate_buckets(__bucket_type* __bkts,
-                                                       std::size_t __n)
-    {
-      typedef typename __bucket_alloc_traits::pointer _Ptr;
-      auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__bkts);
-      __bucket_alloc_type __alloc(_M_node_allocator());
-      __bucket_alloc_traits::deallocate(__alloc, __ptr, __n);
-    }
-
  //@} hashtable-detail
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace __detail
index de50d1e05ece47d6c422da5d0e9a96441d2aeda8..a3a8b1e2fd71c24496fad1bc8b54bb5b80f97c00 100644 (file)
@@ -652,7 +652,7 @@ class Tr1HashtableIterator:
 
 class StdHashtableIterator:
     def __init__(self, hash):
-        self.node = hash['_M_before_begin']['_M_nxt']
+        self.node = hash['_M_bbegin']['_M_node']['_M_nxt']
         self.node_type = find_type(hash.type, '__node_type').pointer()
 
     def __iter__(self):
index 6aad5561392bf1341ade8cbc93475c4f68e569e0..ff0c832dd88d680564fa95135f14410a8548e85b 100644 (file)
@@ -19,7 +19,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-error "with noexcept" "" { target *-*-* } 265 }
+// { dg-error "with noexcept" "" { target *-*-* } 258 }
 
 #include <unordered_set>
 
index 3332cc593cdf280b09b162858cdb4270bac1f629..be5b1201edd4d429f21a0b6a0ecb1d93e64b975d 100644 (file)
@@ -19,7 +19,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-error "default constructible" "" { target *-*-* } 283 }
+// { dg-error "default constructible" "" { target *-*-* } 276 }
 
 #include <unordered_set>
 
This page took 0.10436 seconds and 5 git commands to generate.