libstdc++
bits/hashtable.h
Go to the documentation of this file.
00001 // hashtable.h header -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /** @file bits/hashtable.h
00027  *  This is an internal header file, included by other library headers.
00028  *  Do not attempt to use it directly. @headername{unordered_map, unordered_set}
00029  */
00030 
00031 #ifndef _HASHTABLE_H
00032 #define _HASHTABLE_H 1
00033 
00034 #pragma GCC system_header
00035 
00036 #include <bits/hashtable_policy.h>
00037 
00038 namespace std _GLIBCXX_VISIBILITY(default)
00039 {
00040 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00041 
00042   // Class template _Hashtable, class definition.
00043 
00044   // Meaning of class template _Hashtable's template parameters
00045 
00046   // _Key and _Value: arbitrary CopyConstructible types.
00047 
00048   // _Allocator: an allocator type ([lib.allocator.requirements]) whose
00049   // value type is Value.  As a conforming extension, we allow for
00050   // value type != Value.
00051 
00052   // _ExtractKey: function object that takes an object of type Value
00053   // and returns a value of type _Key.
00054 
00055   // _Equal: function object that takes two objects of type k and returns
00056   // a bool-like value that is true if the two objects are considered equal.
00057 
00058   // _H1: the hash function.  A unary function object with argument type
00059   // Key and result type size_t.  Return values should be distributed
00060   // over the entire range [0, numeric_limits<size_t>:::max()].
00061 
00062   // _H2: the range-hashing function (in the terminology of Tavori and
00063   // Dreizin).  A binary function object whose argument types and result
00064   // type are all size_t.  Given arguments r and N, the return value is
00065   // in the range [0, N).
00066 
00067   // _Hash: the ranged hash function (Tavori and Dreizin). A binary function
00068   // whose argument types are _Key and size_t and whose result type is
00069   // size_t.  Given arguments k and N, the return value is in the range
00070   // [0, N).  Default: hash(k, N) = h2(h1(k), N).  If _Hash is anything other
00071   // than the default, _H1 and _H2 are ignored.
00072 
00073   // _RehashPolicy: Policy class with three members, all of which govern
00074   // the bucket count. _M_next_bkt(n) returns a bucket count no smaller
00075   // than n.  _M_bkt_for_elements(n) returns a bucket count appropriate
00076   // for an element count of n.  _M_need_rehash(n_bkt, n_elt, n_ins)
00077   // determines whether, if the current bucket count is n_bkt and the
00078   // current element count is n_elt, we need to increase the bucket
00079   // count.  If so, returns make_pair(true, n), where n is the new
00080   // bucket count.  If not, returns make_pair(false, <anything>).
00081 
00082   // __cache_hash_code: bool.  true if we store the value of the hash
00083   // function along with the value.  This is a time-space tradeoff.
00084   // Storing it may improve lookup speed by reducing the number of times
00085   // we need to call the Equal function.
00086 
00087   // __constant_iterators: bool.  true if iterator and const_iterator are
00088   // both constant iterator types.  This is true for unordered_set and
00089   // unordered_multiset, false for unordered_map and unordered_multimap.
00090 
00091   // __unique_keys: bool.  true if the return value of _Hashtable::count(k)
00092   // is always at most one, false if it may be an arbitrary number.  This
00093   // true for unordered_set and unordered_map, false for unordered_multiset
00094   // and unordered_multimap.
00095   /**
00096    * Here's _Hashtable data structure, each _Hashtable has:
00097    * - _Bucket[]       _M_buckets
00098    * - _Hash_node_base _M_before_begin
00099    * - size_type       _M_bucket_count
00100    * - size_type       _M_element_count
00101    *
00102    * with _Bucket being _Hash_node* and _Hash_node containing:
00103    * - _Hash_node*   _M_next
00104    * - Tp            _M_value
00105    * - size_t        _M_hash_code if cache_hash_code is true
00106    *
00107    * In terms of Standard containers the hashtable is like the aggregation of:
00108    * - std::forward_list<_Node> containing the elements
00109    * - std::vector<std::forward_list<_Node>::iterator> representing the buckets
00110    *
00111    * The non-empty buckets contain the node before the first node in the
00112    * bucket. This design makes it possible to implement something like a
00113    * std::forward_list::insert_after on container insertion and
00114    * std::forward_list::erase_after on container erase calls.
00115    * _M_before_begin is equivalent to std::foward_list::before_begin.
00116    * Empty buckets contain nullptr.
00117    * Note that one of the non-empty buckets contains &_M_before_begin which is
00118    * not a dereferenceable node so the node pointer in a bucket shall never be
00119    * dereferenced, only its next node can be.
00120    * 
00121    * Walking through a bucket's nodes requires a check on the hash code to see
00122    * if each node is still in the bucket. Such a design assumes a quite
00123    * efficient hash functor and is one of the reasons it is
00124    * highly advisable to set __cache_hash_code to true.
00125    *
00126    * The container iterators are simply built from nodes. This way incrementing
00127    * the iterator is perfectly efficient independent of how many empty buckets
00128    * there are in the container.
00129    *
00130    * On insert we compute the element's hash code and use it to it find the
00131    * bucket index. If the element must be inserted in an empty bucket we add
00132    * it at the beginning of the singly linked list and make the bucket point to
00133    * _M_before_begin. The bucket that used to point to _M_before_begin, if any,
00134    * is updated to point to its new before begin node.
00135    *
00136    * On erase, the simple iterator design requires using the hash functor to
00137    * get the index of the bucket to update. For this reason, when
00138    * __cache_hash_code is set to false, the hash functor must not throw
00139    * and this is enforced by a statied assertion.
00140    */
00141 
00142   template<typename _Key, typename _Value, typename _Allocator,
00143        typename _ExtractKey, typename _Equal,
00144        typename _H1, typename _H2, typename _Hash,
00145        typename _RehashPolicy,
00146        bool __cache_hash_code,
00147        bool __constant_iterators,
00148        bool __unique_keys>
00149     class _Hashtable
00150     : public __detail::_Rehash_base<_RehashPolicy,
00151                     _Hashtable<_Key, _Value, _Allocator,
00152                            _ExtractKey,
00153                            _Equal, _H1, _H2, _Hash,
00154                            _RehashPolicy,
00155                            __cache_hash_code,
00156                            __constant_iterators,
00157                            __unique_keys> >,
00158       public __detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal,
00159                        _H1, _H2, _Hash, __cache_hash_code>,
00160       public __detail::_Map_base<_Key, _Value, _ExtractKey, __unique_keys,
00161                  _Hashtable<_Key, _Value, _Allocator,
00162                         _ExtractKey,
00163                         _Equal, _H1, _H2, _Hash,
00164                         _RehashPolicy,
00165                         __cache_hash_code,
00166                         __constant_iterators,
00167                         __unique_keys> >,
00168       public __detail::_Equality_base<_ExtractKey, __unique_keys,
00169                       _Hashtable<_Key, _Value, _Allocator,
00170                          _ExtractKey,
00171                          _Equal, _H1, _H2, _Hash,
00172                          _RehashPolicy,
00173                          __cache_hash_code,
00174                          __constant_iterators,
00175                          __unique_keys> >
00176     {
00177       template<typename _Cond>
00178     using __if_hash_code_cached
00179       = __or_<__not_<integral_constant<bool, __cache_hash_code>>, _Cond>;
00180 
00181       template<typename _Cond>
00182     using __if_hash_code_not_cached
00183       = __or_<integral_constant<bool, __cache_hash_code>, _Cond>;
00184 
00185       // When hash codes are not cached the hash functor shall not throw
00186       // because it is used in methods (erase, swap...) that shall not throw.
00187       static_assert(__if_hash_code_not_cached<__detail::__is_noexcept_hash<_Key,
00188                                 _H1>>::value,
00189             "Cache the hash code or qualify your hash functor with noexcept");
00190 
00191       // Following two static assertions are necessary to guarantee that
00192       // swapping two hashtable instances won't invalidate associated local
00193       // iterators.
00194 
00195       // When hash codes are cached local iterator only uses H2 which must then
00196       // be empty.
00197       static_assert(__if_hash_code_cached<is_empty<_H2>>::value,
00198         "Functor used to map hash code to bucket index must be empty");
00199 
00200       typedef __detail::_Hash_code_base<_Key, _Value, _ExtractKey,
00201                     _H1, _H2, _Hash,
00202                         __cache_hash_code> _HCBase;
00203 
00204       // When hash codes are not cached local iterator is going to use _HCBase
00205       // above to compute node bucket index so it has to be empty.
00206       static_assert(__if_hash_code_not_cached<is_empty<_HCBase>>::value,
00207         "Cache the hash code or make functors involved in hash code"
00208         " and bucket index computation empty");
00209 
00210     public:
00211       typedef _Allocator                                  allocator_type;
00212       typedef _Value                                      value_type;
00213       typedef _Key                                        key_type;
00214       typedef _Equal                                      key_equal;
00215       // mapped_type, if present, comes from _Map_base.
00216       // hasher, if present, comes from _Hash_code_base.
00217       typedef typename _Allocator::pointer                pointer;
00218       typedef typename _Allocator::const_pointer          const_pointer;
00219       typedef typename _Allocator::reference              reference;
00220       typedef typename _Allocator::const_reference        const_reference;
00221 
00222       typedef std::size_t                                 size_type;
00223       typedef std::ptrdiff_t                              difference_type;
00224       typedef __detail::_Local_iterator<key_type, value_type, _ExtractKey,
00225                     _H1, _H2, _Hash,
00226                     __constant_iterators,
00227                     __cache_hash_code>
00228                               local_iterator;
00229       typedef __detail::_Local_const_iterator<key_type, value_type, _ExtractKey,
00230                           _H1, _H2, _Hash,
00231                           __constant_iterators,
00232                           __cache_hash_code>
00233                               const_local_iterator;
00234       typedef __detail::_Node_iterator<value_type, __constant_iterators,
00235                        __cache_hash_code>
00236                               iterator;
00237       typedef __detail::_Node_const_iterator<value_type,
00238                          __constant_iterators,
00239                          __cache_hash_code>
00240                               const_iterator;
00241 
00242       template<typename _Key2, typename _Value2, typename _Ex2, bool __unique2,
00243            typename _Hashtable2>
00244     friend struct __detail::_Map_base;
00245 
00246     private:
00247       typedef typename _RehashPolicy::_State _RehashPolicyState;
00248       typedef __detail::_Hash_node<_Value, __cache_hash_code> _Node;
00249       typedef typename _Allocator::template rebind<_Node>::other
00250                             _Node_allocator_type;
00251       typedef __detail::_Hash_node_base _BaseNode;
00252       typedef _BaseNode* _Bucket;
00253       typedef typename _Allocator::template rebind<_Bucket>::other
00254                             _Bucket_allocator_type;
00255 
00256       typedef typename _Allocator::template rebind<_Value>::other
00257                             _Value_allocator_type;
00258 
00259       _Node_allocator_type  _M_node_allocator;
00260       _Bucket*          _M_buckets;
00261       size_type         _M_bucket_count;
00262       _BaseNode         _M_before_begin;
00263       size_type         _M_element_count;
00264       _RehashPolicy     _M_rehash_policy;
00265 
00266       template<typename... _Args>
00267     _Node*
00268     _M_allocate_node(_Args&&... __args);
00269 
00270       void
00271       _M_deallocate_node(_Node* __n);
00272 
00273       // Deallocate the linked list of nodes pointed to by __n
00274       void
00275       _M_deallocate_nodes(_Node* __n);
00276 
00277       _Bucket*
00278       _M_allocate_buckets(size_type __n);
00279 
00280       void
00281       _M_deallocate_buckets(_Bucket*, size_type __n);
00282 
00283       // Gets bucket begin, deals with the fact that non-empty buckets contain
00284       // their before begin node.
00285       _Node*
00286       _M_bucket_begin(size_type __bkt) const;
00287 
00288       _Node*
00289       _M_begin() const
00290       { return static_cast<_Node*>(_M_before_begin._M_nxt); }
00291 
00292     public:
00293       // Constructor, destructor, assignment, swap
00294       _Hashtable(size_type __bucket_hint,
00295          const _H1&, const _H2&, const _Hash&,
00296          const _Equal&, const _ExtractKey&,
00297          const allocator_type&);
00298 
00299       template<typename _InputIterator>
00300     _Hashtable(_InputIterator __first, _InputIterator __last,
00301            size_type __bucket_hint,
00302            const _H1&, const _H2&, const _Hash&,
00303            const _Equal&, const _ExtractKey&,
00304            const allocator_type&);
00305 
00306       _Hashtable(const _Hashtable&);
00307 
00308       _Hashtable(_Hashtable&&);
00309 
00310       _Hashtable&
00311       operator=(const _Hashtable& __ht)
00312       {
00313     _Hashtable __tmp(__ht);
00314     this->swap(__tmp);
00315     return *this;
00316       }
00317 
00318       _Hashtable&
00319       operator=(_Hashtable&& __ht)
00320       {
00321     // NB: DR 1204.
00322     // NB: DR 675.
00323     this->clear();
00324     this->swap(__ht);
00325     return *this;
00326       }
00327 
00328       ~_Hashtable() noexcept;
00329 
00330       void swap(_Hashtable&);
00331 
00332       // Basic container operations
00333       iterator
00334       begin() noexcept
00335       { return iterator(_M_begin()); }
00336 
00337       const_iterator
00338       begin() const noexcept
00339       { return const_iterator(_M_begin()); }
00340 
00341       iterator
00342       end() noexcept
00343       { return iterator(nullptr); }
00344 
00345       const_iterator
00346       end() const noexcept
00347       { return const_iterator(nullptr); }
00348 
00349       const_iterator
00350       cbegin() const noexcept
00351       { return const_iterator(_M_begin()); }
00352 
00353       const_iterator
00354       cend() const noexcept
00355       { return const_iterator(nullptr); }
00356 
00357       size_type
00358       size() const noexcept
00359       { return _M_element_count; }
00360 
00361       bool
00362       empty() const noexcept
00363       { return size() == 0; }
00364 
00365       allocator_type
00366       get_allocator() const noexcept
00367       { return allocator_type(_M_node_allocator); }
00368 
00369       size_type
00370       max_size() const noexcept
00371       { return _M_node_allocator.max_size(); }
00372 
00373       // Observers
00374       key_equal
00375       key_eq() const
00376       { return this->_M_eq(); }
00377 
00378       // hash_function, if present, comes from _Hash_code_base.
00379 
00380       // Bucket operations
00381       size_type
00382       bucket_count() const noexcept
00383       { return _M_bucket_count; }
00384 
00385       size_type
00386       max_bucket_count() const noexcept
00387       { return max_size(); }
00388 
00389       size_type
00390       bucket_size(size_type __n) const
00391       { return std::distance(begin(__n), end(__n)); }
00392 
00393       size_type
00394       bucket(const key_type& __k) const
00395       { return _M_bucket_index(__k, this->_M_hash_code(__k)); }
00396 
00397       local_iterator
00398       begin(size_type __n)
00399       { return local_iterator(_M_bucket_begin(__n), __n,
00400                   _M_bucket_count); }
00401 
00402       local_iterator
00403       end(size_type __n)
00404       { return local_iterator(nullptr, __n, _M_bucket_count); }
00405 
00406       const_local_iterator
00407       begin(size_type __n) const
00408       { return const_local_iterator(_M_bucket_begin(__n), __n,
00409                     _M_bucket_count); }
00410 
00411       const_local_iterator
00412       end(size_type __n) const
00413       { return const_local_iterator(nullptr, __n, _M_bucket_count); }
00414 
00415       // DR 691.
00416       const_local_iterator
00417       cbegin(size_type __n) const
00418       { return const_local_iterator(_M_bucket_begin(__n), __n,
00419                     _M_bucket_count); }
00420 
00421       const_local_iterator
00422       cend(size_type __n) const
00423       { return const_local_iterator(nullptr, __n, _M_bucket_count); }
00424 
00425       float
00426       load_factor() const noexcept
00427       {
00428     return static_cast<float>(size()) / static_cast<float>(bucket_count());
00429       }
00430 
00431       // max_load_factor, if present, comes from _Rehash_base.
00432 
00433       // Generalization of max_load_factor.  Extension, not found in TR1.  Only
00434       // useful if _RehashPolicy is something other than the default.
00435       const _RehashPolicy&
00436       __rehash_policy() const
00437       { return _M_rehash_policy; }
00438 
00439       void
00440       __rehash_policy(const _RehashPolicy&);
00441 
00442       // Lookup.
00443       iterator
00444       find(const key_type& __k);
00445 
00446       const_iterator
00447       find(const key_type& __k) const;
00448 
00449       size_type
00450       count(const key_type& __k) const;
00451 
00452       std::pair<iterator, iterator>
00453       equal_range(const key_type& __k);
00454 
00455       std::pair<const_iterator, const_iterator>
00456       equal_range(const key_type& __k) const;
00457 
00458     private:
00459       // Bucket index computation helpers.
00460       size_type
00461       _M_bucket_index(_Node* __n) const
00462       { return _HCBase::_M_bucket_index(__n, _M_bucket_count); }
00463 
00464       size_type
00465       _M_bucket_index(const key_type& __k,
00466               typename _Hashtable::_Hash_code_type __c) const
00467       { return _HCBase::_M_bucket_index(__k, __c, _M_bucket_count); }
00468 
00469       // Find and insert helper functions and types
00470       // Find the node before the one matching the criteria.
00471       _BaseNode*
00472       _M_find_before_node(size_type, const key_type&,
00473               typename _Hashtable::_Hash_code_type) const;
00474 
00475       _Node*
00476       _M_find_node(size_type __bkt, const key_type& __key,
00477            typename _Hashtable::_Hash_code_type __c) const
00478       {
00479     _BaseNode* __before_n = _M_find_before_node(__bkt, __key, __c);
00480     if (__before_n)
00481       return static_cast<_Node*>(__before_n->_M_nxt);
00482     return nullptr;
00483       }
00484 
00485       // Insert a node at the beginning of a bucket.
00486       void
00487       _M_insert_bucket_begin(size_type, _Node*);
00488 
00489       // Remove the bucket first node
00490       void
00491       _M_remove_bucket_begin(size_type __bkt, _Node* __next_n,
00492                  size_type __next_bkt);
00493 
00494       // Get the node before __n in the bucket __bkt
00495       _BaseNode*
00496       _M_get_previous_node(size_type __bkt, _BaseNode* __n);
00497 
00498       template<typename _Arg>
00499     iterator
00500     _M_insert_bucket(_Arg&&, size_type,
00501              typename _Hashtable::_Hash_code_type);
00502 
00503       typedef typename std::conditional<__unique_keys,
00504                     std::pair<iterator, bool>,
00505                     iterator>::type
00506     _Insert_Return_Type;
00507 
00508       typedef typename std::conditional<__unique_keys,
00509                     std::_Select1st<_Insert_Return_Type>,
00510                     std::_Identity<_Insert_Return_Type>
00511                    >::type
00512     _Insert_Conv_Type;
00513 
00514     protected:
00515       template<typename... _Args>
00516     std::pair<iterator, bool>
00517     _M_emplace(std::true_type, _Args&&... __args);
00518 
00519       template<typename... _Args>
00520     iterator
00521     _M_emplace(std::false_type, _Args&&... __args);
00522 
00523       template<typename _Arg>
00524     std::pair<iterator, bool>
00525     _M_insert(_Arg&&, std::true_type);
00526 
00527       template<typename _Arg>
00528     iterator
00529     _M_insert(_Arg&&, std::false_type);
00530 
00531     public:
00532       // Emplace, insert and erase
00533       template<typename... _Args>
00534     _Insert_Return_Type
00535     emplace(_Args&&... __args)
00536     { return _M_emplace(integral_constant<bool, __unique_keys>(),
00537                 std::forward<_Args>(__args)...); }
00538 
00539       template<typename... _Args>
00540     iterator
00541     emplace_hint(const_iterator, _Args&&... __args)
00542     { return _Insert_Conv_Type()(emplace(std::forward<_Args>(__args)...)); }
00543 
00544       _Insert_Return_Type
00545       insert(const value_type& __v)
00546       { return _M_insert(__v, integral_constant<bool, __unique_keys>()); }
00547 
00548       iterator
00549       insert(const_iterator, const value_type& __v)
00550       { return _Insert_Conv_Type()(insert(__v)); }
00551 
00552       template<typename _Pair, typename = typename
00553     std::enable_if<__and_<integral_constant<bool, !__constant_iterators>,
00554                   std::is_constructible<value_type,
00555                             _Pair&&>>::value>::type>
00556     _Insert_Return_Type
00557     insert(_Pair&& __v)
00558     { return _M_insert(std::forward<_Pair>(__v),
00559                integral_constant<bool, __unique_keys>()); }
00560 
00561       template<typename _Pair, typename = typename
00562         std::enable_if<__and_<integral_constant<bool, !__constant_iterators>,
00563                   std::is_constructible<value_type,
00564                             _Pair&&>>::value>::type>
00565     iterator
00566     insert(const_iterator, _Pair&& __v)
00567     { return _Insert_Conv_Type()(insert(std::forward<_Pair>(__v))); }
00568 
00569       template<typename _InputIterator>
00570     void
00571     insert(_InputIterator __first, _InputIterator __last);
00572 
00573       void
00574       insert(initializer_list<value_type> __l)
00575       { this->insert(__l.begin(), __l.end()); }
00576 
00577       iterator
00578       erase(const_iterator);
00579 
00580       // LWG 2059.
00581       iterator
00582       erase(iterator __it)
00583       { return erase(const_iterator(__it)); }
00584 
00585       size_type
00586       erase(const key_type&);
00587 
00588       iterator
00589       erase(const_iterator, const_iterator);
00590 
00591       void
00592       clear() noexcept;
00593 
00594       // Set number of buckets to be appropriate for container of n element.
00595       void rehash(size_type __n);
00596 
00597       // DR 1189.
00598       // reserve, if present, comes from _Rehash_base.
00599 
00600     private:
00601       // Helper rehash method used when keys are unique.
00602       void _M_rehash_aux(size_type __n, std::true_type);
00603 
00604       // Helper rehash method used when keys can be non-unique.
00605       void _M_rehash_aux(size_type __n, std::false_type);
00606 
00607       // Unconditionally change size of bucket array to n, restore hash policy
00608       // state to __state on exception.
00609       void _M_rehash(size_type __n, const _RehashPolicyState& __state);
00610     };
00611 
00612 
00613   // Definitions of class template _Hashtable's out-of-line member functions.
00614   template<typename _Key, typename _Value,
00615        typename _Allocator, typename _ExtractKey, typename _Equal,
00616        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00617        bool __chc, bool __cit, bool __uk>
00618     template<typename... _Args>
00619       typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00620               _H1, _H2, _Hash, _RehashPolicy,
00621               __chc, __cit, __uk>::_Node*
00622       _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00623          _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00624       _M_allocate_node(_Args&&... __args)
00625       {
00626     _Node* __n = _M_node_allocator.allocate(1);
00627     __try
00628       {
00629         _M_node_allocator.construct(__n, std::forward<_Args>(__args)...);
00630         return __n;
00631       }
00632     __catch(...)
00633       {
00634         _M_node_allocator.deallocate(__n, 1);
00635         __throw_exception_again;
00636       }
00637       }
00638 
00639   template<typename _Key, typename _Value,
00640        typename _Allocator, typename _ExtractKey, typename _Equal,
00641        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00642        bool __chc, bool __cit, bool __uk>
00643     void
00644     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00645            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00646     _M_deallocate_node(_Node* __n)
00647     {
00648       _M_node_allocator.destroy(__n);
00649       _M_node_allocator.deallocate(__n, 1);
00650     }
00651 
00652   template<typename _Key, typename _Value,
00653        typename _Allocator, typename _ExtractKey, typename _Equal,
00654        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00655        bool __chc, bool __cit, bool __uk>
00656     void
00657     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00658            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00659     _M_deallocate_nodes(_Node* __n)
00660     {
00661       while (__n)
00662     {
00663       _Node* __tmp = __n;
00664       __n = __n->_M_next();
00665       _M_deallocate_node(__tmp);
00666     }
00667     }
00668 
00669   template<typename _Key, typename _Value,
00670        typename _Allocator, typename _ExtractKey, typename _Equal,
00671        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00672        bool __chc, bool __cit, bool __uk>
00673     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00674             _H1, _H2, _Hash, _RehashPolicy,
00675             __chc, __cit, __uk>::_Bucket*
00676     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00677            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00678     _M_allocate_buckets(size_type __n)
00679     {
00680       _Bucket_allocator_type __alloc(_M_node_allocator);
00681 
00682       _Bucket* __p = __alloc.allocate(__n);
00683       __builtin_memset(__p, 0, __n * sizeof(_Bucket));
00684       return __p;
00685     }
00686 
00687   template<typename _Key, typename _Value,
00688        typename _Allocator, typename _ExtractKey, typename _Equal,
00689        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00690        bool __chc, bool __cit, bool __uk>
00691     void
00692     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00693            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00694     _M_deallocate_buckets(_Bucket* __p, size_type __n)
00695     {
00696       _Bucket_allocator_type __alloc(_M_node_allocator);
00697       __alloc.deallocate(__p, __n);
00698     }
00699 
00700   template<typename _Key, typename _Value,
00701        typename _Allocator, typename _ExtractKey, typename _Equal,
00702        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00703        bool __chc, bool __cit, bool __uk>
00704     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey,
00705             _Equal, _H1, _H2, _Hash, _RehashPolicy,
00706             __chc, __cit, __uk>::_Node*
00707     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00708            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00709     _M_bucket_begin(size_type __bkt) const
00710     {
00711       _BaseNode* __n = _M_buckets[__bkt];
00712       return __n ? static_cast<_Node*>(__n->_M_nxt) : nullptr;
00713     }
00714 
00715   template<typename _Key, typename _Value,
00716        typename _Allocator, typename _ExtractKey, typename _Equal,
00717        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00718        bool __chc, bool __cit, bool __uk>
00719     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00720            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00721     _Hashtable(size_type __bucket_hint,
00722            const _H1& __h1, const _H2& __h2, const _Hash& __h,
00723            const _Equal& __eq, const _ExtractKey& __exk,
00724            const allocator_type& __a)
00725     : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(),
00726       __detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal,
00727                 _H1, _H2, _Hash, __chc>(__exk, __h1, __h2, __h,
00728                             __eq),
00729       __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(),
00730       _M_node_allocator(__a),
00731       _M_bucket_count(0),
00732       _M_element_count(0),
00733       _M_rehash_policy()
00734     {
00735       _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint);
00736       // We don't want the rehash policy to ask for the hashtable to shrink
00737       // on the first insertion so we need to reset its previous resize level.
00738       _M_rehash_policy._M_prev_resize = 0;
00739       _M_buckets = _M_allocate_buckets(_M_bucket_count);
00740     }
00741 
00742   template<typename _Key, typename _Value,
00743        typename _Allocator, typename _ExtractKey, typename _Equal,
00744        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00745        bool __chc, bool __cit, bool __uk>
00746     template<typename _InputIterator>
00747       _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00748          _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00749       _Hashtable(_InputIterator __f, _InputIterator __l,
00750          size_type __bucket_hint,
00751          const _H1& __h1, const _H2& __h2, const _Hash& __h,
00752          const _Equal& __eq, const _ExtractKey& __exk,
00753          const allocator_type& __a)
00754       : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(),
00755     __detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal,
00756                   _H1, _H2, _Hash, __chc>(__exk, __h1, __h2, __h,
00757                               __eq),
00758     __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(),
00759     _M_node_allocator(__a),
00760     _M_bucket_count(0),
00761     _M_element_count(0),
00762     _M_rehash_policy()
00763       {
00764     _M_bucket_count =
00765       _M_rehash_policy._M_bkt_for_elements(__detail::__distance_fw(__f,
00766                                        __l));
00767     if (_M_bucket_count <= __bucket_hint)
00768       _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint);
00769 
00770         // We don't want the rehash policy to ask for the hashtable to shrink
00771         // on the first insertion so we need to reset its previous resize
00772     // level.
00773     _M_rehash_policy._M_prev_resize = 0;
00774     _M_buckets = _M_allocate_buckets(_M_bucket_count);
00775     __try
00776       {
00777         for (; __f != __l; ++__f)
00778           this->insert(*__f);
00779       }
00780     __catch(...)
00781       {
00782         clear();
00783         _M_deallocate_buckets(_M_buckets, _M_bucket_count);
00784         __throw_exception_again;
00785       }
00786       }
00787 
00788   template<typename _Key, typename _Value,
00789        typename _Allocator, typename _ExtractKey, typename _Equal,
00790        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00791        bool __chc, bool __cit, bool __uk>
00792     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00793            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00794     _Hashtable(const _Hashtable& __ht)
00795     : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(__ht),
00796       __detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal,
00797                 _H1, _H2, _Hash, __chc>(__ht),
00798       __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(__ht),
00799       _M_node_allocator(__ht._M_node_allocator),
00800       _M_bucket_count(__ht._M_bucket_count),
00801       _M_element_count(__ht._M_element_count),
00802       _M_rehash_policy(__ht._M_rehash_policy)
00803     {
00804       _M_buckets = _M_allocate_buckets(_M_bucket_count);
00805       __try
00806     {
00807       if (!__ht._M_before_begin._M_nxt)
00808         return;
00809 
00810       // First deal with the special first node pointed to by
00811       // _M_before_begin.
00812       const _Node* __ht_n = __ht._M_begin();
00813       _Node* __this_n = _M_allocate_node(__ht_n->_M_v);
00814       this->_M_copy_code(__this_n, __ht_n);
00815       _M_before_begin._M_nxt = __this_n;
00816       _M_buckets[_M_bucket_index(__this_n)] = &_M_before_begin;
00817 
00818       // Then deal with other nodes.
00819       _BaseNode* __prev_n = __this_n;
00820       for (__ht_n = __ht_n->_M_next(); __ht_n; __ht_n = __ht_n->_M_next())
00821         {
00822           __this_n = _M_allocate_node(__ht_n->_M_v);
00823           __prev_n->_M_nxt = __this_n;
00824           this->_M_copy_code(__this_n, __ht_n);
00825           size_type __bkt = _M_bucket_index(__this_n);
00826           if (!_M_buckets[__bkt])
00827         _M_buckets[__bkt] = __prev_n;
00828           __prev_n = __this_n;
00829         }
00830     }
00831       __catch(...)
00832     {
00833       clear();
00834       _M_deallocate_buckets(_M_buckets, _M_bucket_count);
00835       __throw_exception_again;
00836     }
00837     }
00838 
00839   template<typename _Key, typename _Value,
00840        typename _Allocator, typename _ExtractKey, typename _Equal,
00841        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00842        bool __chc, bool __cit, bool __uk>
00843     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00844            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00845     _Hashtable(_Hashtable&& __ht)
00846     : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(__ht),
00847       __detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal,
00848                 _H1, _H2, _Hash, __chc>(__ht),
00849       __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(__ht),
00850       _M_node_allocator(std::move(__ht._M_node_allocator)),
00851       _M_buckets(__ht._M_buckets),
00852       _M_bucket_count(__ht._M_bucket_count),
00853       _M_before_begin(__ht._M_before_begin._M_nxt),
00854       _M_element_count(__ht._M_element_count),
00855       _M_rehash_policy(__ht._M_rehash_policy)
00856     {
00857       // Update, if necessary, bucket pointing to before begin that hasn't move.
00858       if (_M_begin())
00859     _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
00860       __ht._M_rehash_policy = _RehashPolicy();
00861       __ht._M_bucket_count = __ht._M_rehash_policy._M_next_bkt(0);
00862       __ht._M_buckets = __ht._M_allocate_buckets(__ht._M_bucket_count);
00863       __ht._M_before_begin._M_nxt = nullptr;
00864       __ht._M_element_count = 0;
00865     }
00866 
00867   template<typename _Key, typename _Value,
00868        typename _Allocator, typename _ExtractKey, typename _Equal,
00869        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00870        bool __chc, bool __cit, bool __uk>
00871     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00872            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00873     ~_Hashtable() noexcept
00874     {
00875       clear();
00876       _M_deallocate_buckets(_M_buckets, _M_bucket_count);
00877     }
00878 
00879   template<typename _Key, typename _Value,
00880        typename _Allocator, typename _ExtractKey, typename _Equal,
00881        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00882        bool __chc, bool __cit, bool __uk>
00883     void
00884     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00885            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00886     swap(_Hashtable& __x)
00887     {
00888       // The only base class with member variables is hash_code_base.  We
00889       // define _Hash_code_base::_M_swap because different specializations
00890       // have different members.
00891       this->_M_swap(__x);
00892 
00893       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00894       // 431. Swapping containers with unequal allocators.
00895       std::__alloc_swap<_Node_allocator_type>::_S_do_it(_M_node_allocator,
00896                             __x._M_node_allocator);
00897 
00898       std::swap(_M_rehash_policy, __x._M_rehash_policy);
00899       std::swap(_M_buckets, __x._M_buckets);
00900       std::swap(_M_bucket_count, __x._M_bucket_count);
00901       std::swap(_M_before_begin._M_nxt, __x._M_before_begin._M_nxt);
00902       std::swap(_M_element_count, __x._M_element_count);
00903       // Fix buckets containing the _M_before_begin pointers that can't be
00904       // swapped.
00905       if (_M_begin())
00906     _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
00907       if (__x._M_begin())
00908     __x._M_buckets[__x._M_bucket_index(__x._M_begin())]
00909       = &(__x._M_before_begin);
00910     }
00911 
00912   template<typename _Key, typename _Value,
00913        typename _Allocator, typename _ExtractKey, typename _Equal,
00914        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00915        bool __chc, bool __cit, bool __uk>
00916     void
00917     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00918            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00919     __rehash_policy(const _RehashPolicy& __pol)
00920     {
00921       size_type __n_bkt = __pol._M_bkt_for_elements(_M_element_count);
00922       if (__n_bkt != _M_bucket_count)
00923     _M_rehash(__n_bkt, _M_rehash_policy._M_state());
00924       _M_rehash_policy = __pol;
00925     }
00926 
00927   template<typename _Key, typename _Value,
00928        typename _Allocator, typename _ExtractKey, typename _Equal,
00929        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00930        bool __chc, bool __cit, bool __uk>
00931     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00932             _H1, _H2, _Hash, _RehashPolicy,
00933             __chc, __cit, __uk>::iterator
00934     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00935            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00936     find(const key_type& __k)
00937     {
00938       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
00939       std::size_t __n = _M_bucket_index(__k, __code);
00940       _Node* __p = _M_find_node(__n, __k, __code);
00941       return __p ? iterator(__p) : this->end();
00942     }
00943 
00944   template<typename _Key, typename _Value,
00945        typename _Allocator, typename _ExtractKey, typename _Equal,
00946        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00947        bool __chc, bool __cit, bool __uk>
00948     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00949             _H1, _H2, _Hash, _RehashPolicy,
00950             __chc, __cit, __uk>::const_iterator
00951     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00952            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00953     find(const key_type& __k) const
00954     {
00955       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
00956       std::size_t __n = _M_bucket_index(__k, __code);
00957       _Node* __p = _M_find_node(__n, __k, __code);
00958       return __p ? const_iterator(__p) : this->end();
00959     }
00960 
00961   template<typename _Key, typename _Value,
00962        typename _Allocator, typename _ExtractKey, typename _Equal,
00963        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00964        bool __chc, bool __cit, bool __uk>
00965     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00966             _H1, _H2, _Hash, _RehashPolicy,
00967             __chc, __cit, __uk>::size_type
00968     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
00969            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
00970     count(const key_type& __k) const
00971     {
00972       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
00973       std::size_t __n = _M_bucket_index(__k, __code);
00974       _Node* __p = _M_bucket_begin(__n);
00975       if (!__p)
00976     return 0;
00977 
00978       std::size_t __result = 0;
00979       for (;; __p = __p->_M_next())
00980     {
00981       if (this->_M_equals(__k, __code, __p))
00982         ++__result;
00983       else if (__result)
00984         // All equivalent values are next to each other, if we found a not
00985         // equivalent value after an equivalent one it means that we won't
00986         // find any more equivalent values.
00987         break;
00988       if (!__p->_M_nxt || _M_bucket_index(__p->_M_next()) != __n)
00989         break;
00990     }
00991       return __result;
00992     }
00993 
00994   template<typename _Key, typename _Value,
00995        typename _Allocator, typename _ExtractKey, typename _Equal,
00996        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
00997        bool __chc, bool __cit, bool __uk>
00998     std::pair<typename _Hashtable<_Key, _Value, _Allocator,
00999                   _ExtractKey, _Equal, _H1,
01000                   _H2, _Hash, _RehashPolicy,
01001                   __chc, __cit, __uk>::iterator,
01002           typename _Hashtable<_Key, _Value, _Allocator,
01003                   _ExtractKey, _Equal, _H1,
01004                   _H2, _Hash, _RehashPolicy,
01005                   __chc, __cit, __uk>::iterator>
01006     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01007            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01008     equal_range(const key_type& __k)
01009     {
01010       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
01011       std::size_t __n = _M_bucket_index(__k, __code);
01012       _Node* __p = _M_find_node(__n, __k, __code);
01013 
01014       if (__p)
01015     {
01016       _Node* __p1 = __p->_M_next();
01017       while (__p1 && _M_bucket_index(__p1) == __n
01018          && this->_M_equals(__k, __code, __p1))
01019         __p1 = __p1->_M_next();
01020 
01021       return std::make_pair(iterator(__p), iterator(__p1));
01022     }
01023       else
01024     return std::make_pair(this->end(), this->end());
01025     }
01026 
01027   template<typename _Key, typename _Value,
01028        typename _Allocator, typename _ExtractKey, typename _Equal,
01029        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01030        bool __chc, bool __cit, bool __uk>
01031     std::pair<typename _Hashtable<_Key, _Value, _Allocator,
01032                   _ExtractKey, _Equal, _H1,
01033                   _H2, _Hash, _RehashPolicy,
01034                   __chc, __cit, __uk>::const_iterator,
01035           typename _Hashtable<_Key, _Value, _Allocator,
01036                   _ExtractKey, _Equal, _H1,
01037                   _H2, _Hash, _RehashPolicy,
01038                   __chc, __cit, __uk>::const_iterator>
01039     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01040            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01041     equal_range(const key_type& __k) const
01042     {
01043       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
01044       std::size_t __n = _M_bucket_index(__k, __code);
01045       _Node* __p = _M_find_node(__n, __k, __code);
01046 
01047       if (__p)
01048     {
01049       _Node* __p1 = __p->_M_next();
01050       while (__p1 && _M_bucket_index(__p1) == __n
01051          && this->_M_equals(__k, __code, __p1))
01052         __p1 = __p1->_M_next();
01053 
01054       return std::make_pair(const_iterator(__p), const_iterator(__p1));
01055     }
01056       else
01057     return std::make_pair(this->end(), this->end());
01058     }
01059 
01060   // Find the node whose key compares equal to k in the bucket n. Return nullptr
01061   // if no node is found.
01062   template<typename _Key, typename _Value,
01063        typename _Allocator, typename _ExtractKey, typename _Equal,
01064        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01065        bool __chc, bool __cit, bool __uk>
01066     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey,
01067             _Equal, _H1, _H2, _Hash, _RehashPolicy,
01068             __chc, __cit, __uk>::_BaseNode*
01069     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01070            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01071     _M_find_before_node(size_type __n, const key_type& __k,
01072             typename _Hashtable::_Hash_code_type __code) const
01073     {
01074       _BaseNode* __prev_p = _M_buckets[__n];
01075       if (!__prev_p)
01076     return nullptr;
01077       _Node* __p = static_cast<_Node*>(__prev_p->_M_nxt);
01078       for (;; __p = __p->_M_next())
01079     {
01080       if (this->_M_equals(__k, __code, __p))
01081         return __prev_p;
01082       if (!(__p->_M_nxt) || _M_bucket_index(__p->_M_next()) != __n)
01083         break;
01084       __prev_p = __p;
01085     }
01086       return nullptr;
01087     }
01088 
01089   template<typename _Key, typename _Value,
01090        typename _Allocator, typename _ExtractKey, typename _Equal,
01091        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01092        bool __chc, bool __cit, bool __uk>
01093     void
01094     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01095            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01096     _M_insert_bucket_begin(size_type __bkt, _Node* __new_node)
01097     {
01098       if (_M_buckets[__bkt])
01099     {
01100       // Bucket is not empty, we just need to insert the new node after the
01101       // bucket before begin.
01102       __new_node->_M_nxt = _M_buckets[__bkt]->_M_nxt;
01103       _M_buckets[__bkt]->_M_nxt = __new_node;
01104     }
01105       else
01106     {
01107       // The bucket is empty, the new node is inserted at the beginning of
01108       // the singly-linked list and the bucket will contain _M_before_begin
01109       // pointer.
01110       __new_node->_M_nxt = _M_before_begin._M_nxt;
01111       _M_before_begin._M_nxt = __new_node;
01112       if (__new_node->_M_nxt)
01113         // We must update former begin bucket that is pointing to
01114         // _M_before_begin.
01115         _M_buckets[_M_bucket_index(__new_node->_M_next())] = __new_node;
01116       _M_buckets[__bkt] = &_M_before_begin;
01117     }
01118     }
01119 
01120   template<typename _Key, typename _Value,
01121        typename _Allocator, typename _ExtractKey, typename _Equal,
01122        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01123        bool __chc, bool __cit, bool __uk>
01124     void
01125     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01126            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01127     _M_remove_bucket_begin(size_type __bkt, _Node* __next, size_type __next_bkt)
01128     {
01129       if (!__next || __next_bkt != __bkt)
01130     {
01131       // Bucket is now empty
01132       // First update next bucket if any
01133       if (__next)
01134         _M_buckets[__next_bkt] = _M_buckets[__bkt];
01135       // Second update before begin node if necessary
01136       if (&_M_before_begin == _M_buckets[__bkt])
01137         _M_before_begin._M_nxt = __next;
01138       _M_buckets[__bkt] = nullptr;
01139     }
01140     }
01141 
01142   template<typename _Key, typename _Value,
01143        typename _Allocator, typename _ExtractKey, typename _Equal,
01144        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01145        bool __chc, bool __cit, bool __uk>
01146     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey,
01147             _Equal, _H1, _H2, _Hash, _RehashPolicy,
01148             __chc, __cit, __uk>::_BaseNode*
01149     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01150            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01151     _M_get_previous_node(size_type __bkt, _BaseNode* __n)
01152     {
01153       _BaseNode* __prev_n = _M_buckets[__bkt];
01154       while (__prev_n->_M_nxt != __n)
01155     __prev_n = __prev_n->_M_nxt;
01156       return __prev_n;
01157     }
01158 
01159   template<typename _Key, typename _Value,
01160        typename _Allocator, typename _ExtractKey, typename _Equal,
01161        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01162        bool __chc, bool __cit, bool __uk>
01163     template<typename... _Args>
01164       std::pair<typename _Hashtable<_Key, _Value, _Allocator,
01165                     _ExtractKey, _Equal, _H1,
01166                     _H2, _Hash, _RehashPolicy,
01167                     __chc, __cit, __uk>::iterator, bool>
01168       _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01169          _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01170       _M_emplace(std::true_type, _Args&&... __args)
01171       {
01172     // First build the node to get access to the hash code
01173     _Node* __new_node = _M_allocate_node(std::forward<_Args>(__args)...);
01174     __try
01175       {
01176         const key_type& __k = this->_M_extract()(__new_node->_M_v);
01177         typename _Hashtable::_Hash_code_type __code
01178           = this->_M_hash_code(__k);
01179         size_type __bkt = _M_bucket_index(__k, __code);
01180 
01181         if (_Node* __p = _M_find_node(__bkt, __k, __code))
01182           {
01183         // There is already an equivalent node, no insertion
01184         _M_deallocate_node(__new_node);
01185         return std::make_pair(iterator(__p), false);
01186           }
01187 
01188         // We are going to insert this node
01189         this->_M_store_code(__new_node, __code);
01190         const _RehashPolicyState& __saved_state
01191           = _M_rehash_policy._M_state();
01192         std::pair<bool, std::size_t> __do_rehash
01193           = _M_rehash_policy._M_need_rehash(_M_bucket_count,
01194                         _M_element_count, 1);
01195 
01196         if (__do_rehash.first)
01197           {
01198         _M_rehash(__do_rehash.second, __saved_state);
01199         __bkt = _M_bucket_index(__k, __code);
01200           }
01201 
01202         _M_insert_bucket_begin(__bkt, __new_node);
01203         ++_M_element_count;
01204         return std::make_pair(iterator(__new_node), true);
01205       }
01206     __catch(...)
01207       {
01208         _M_deallocate_node(__new_node);
01209         __throw_exception_again;
01210       }
01211       }
01212 
01213   template<typename _Key, typename _Value,
01214        typename _Allocator, typename _ExtractKey, typename _Equal,
01215        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01216        bool __chc, bool __cit, bool __uk>
01217     template<typename... _Args>
01218       typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01219               _H1, _H2, _Hash, _RehashPolicy,
01220               __chc, __cit, __uk>::iterator
01221       _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01222          _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01223       _M_emplace(std::false_type, _Args&&... __args)
01224       {
01225     const _RehashPolicyState& __saved_state = _M_rehash_policy._M_state();
01226     std::pair<bool, std::size_t> __do_rehash
01227       = _M_rehash_policy._M_need_rehash(_M_bucket_count,
01228                         _M_element_count, 1);
01229 
01230     // First build the node to get its hash code.
01231     _Node* __new_node = _M_allocate_node(std::forward<_Args>(__args)...);
01232     __try
01233       {
01234         const key_type& __k = this->_M_extract()(__new_node->_M_v);
01235         typename _Hashtable::_Hash_code_type __code
01236           = this->_M_hash_code(__k);
01237         this->_M_store_code(__new_node, __code);
01238 
01239         // Second, do rehash if necessary.
01240         if (__do_rehash.first)
01241         _M_rehash(__do_rehash.second, __saved_state);
01242 
01243         // Third, find the node before an equivalent one.
01244         size_type __bkt = _M_bucket_index(__k, __code);
01245         _BaseNode* __prev = _M_find_before_node(__bkt, __k, __code);
01246         
01247         if (__prev)
01248           {
01249         // Insert after the node before the equivalent one.
01250         __new_node->_M_nxt = __prev->_M_nxt;
01251         __prev->_M_nxt = __new_node;
01252           }
01253         else
01254           // The inserted node has no equivalent in the hashtable. We must
01255           // insert the new node at the beginning of the bucket to preserve
01256           // equivalent elements' relative positions.
01257           _M_insert_bucket_begin(__bkt, __new_node);
01258         ++_M_element_count;
01259         return iterator(__new_node);
01260       }
01261     __catch(...)
01262       {
01263         _M_deallocate_node(__new_node);
01264         __throw_exception_again;
01265       }
01266       }
01267 
01268   // Insert v in bucket n (assumes no element with its key already present).
01269   template<typename _Key, typename _Value,
01270        typename _Allocator, typename _ExtractKey, typename _Equal,
01271        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01272        bool __chc, bool __cit, bool __uk>
01273     template<typename _Arg>
01274       typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01275               _H1, _H2, _Hash, _RehashPolicy,
01276               __chc, __cit, __uk>::iterator
01277       _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01278          _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01279       _M_insert_bucket(_Arg&& __v, size_type __n,
01280                typename _Hashtable::_Hash_code_type __code)
01281       {
01282     const _RehashPolicyState& __saved_state = _M_rehash_policy._M_state();
01283     std::pair<bool, std::size_t> __do_rehash
01284       = _M_rehash_policy._M_need_rehash(_M_bucket_count,
01285                         _M_element_count, 1);
01286 
01287     if (__do_rehash.first)
01288       {
01289         const key_type& __k = this->_M_extract()(__v);
01290         __n = _HCBase::_M_bucket_index(__k, __code, __do_rehash.second);
01291       }
01292 
01293     _Node* __new_node = nullptr;
01294     __try
01295       {
01296         // Allocate the new node before doing the rehash so that we
01297         // don't do a rehash if the allocation throws.
01298         __new_node = _M_allocate_node(std::forward<_Arg>(__v));
01299         this->_M_store_code(__new_node, __code);
01300         if (__do_rehash.first)
01301           _M_rehash(__do_rehash.second, __saved_state);
01302 
01303         _M_insert_bucket_begin(__n, __new_node);
01304         ++_M_element_count;
01305         return iterator(__new_node);
01306       }
01307     __catch(...)
01308       {
01309         if (!__new_node)
01310           _M_rehash_policy._M_reset(__saved_state);
01311         else
01312           _M_deallocate_node(__new_node);
01313         __throw_exception_again;
01314       }
01315       }
01316 
01317   // Insert v if no element with its key is already present.
01318   template<typename _Key, typename _Value,
01319        typename _Allocator, typename _ExtractKey, typename _Equal,
01320        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01321        bool __chc, bool __cit, bool __uk>
01322     template<typename _Arg>
01323       std::pair<typename _Hashtable<_Key, _Value, _Allocator,
01324                     _ExtractKey, _Equal, _H1,
01325                     _H2, _Hash, _RehashPolicy,
01326                     __chc, __cit, __uk>::iterator, bool>
01327       _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01328          _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01329       _M_insert(_Arg&& __v, std::true_type)
01330       {
01331     const key_type& __k = this->_M_extract()(__v);
01332     typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
01333     size_type __n = _M_bucket_index(__k, __code);
01334 
01335     if (_Node* __p = _M_find_node(__n, __k, __code))
01336       return std::make_pair(iterator(__p), false);
01337     return std::make_pair(_M_insert_bucket(std::forward<_Arg>(__v),
01338                   __n, __code), true);
01339       }
01340 
01341   // Insert v unconditionally.
01342   template<typename _Key, typename _Value,
01343        typename _Allocator, typename _ExtractKey, typename _Equal,
01344        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01345        bool __chc, bool __cit, bool __uk>
01346     template<typename _Arg>
01347       typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01348               _H1, _H2, _Hash, _RehashPolicy,
01349               __chc, __cit, __uk>::iterator
01350       _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01351          _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01352       _M_insert(_Arg&& __v, std::false_type)
01353       {
01354     const _RehashPolicyState& __saved_state = _M_rehash_policy._M_state();
01355     std::pair<bool, std::size_t> __do_rehash
01356       = _M_rehash_policy._M_need_rehash(_M_bucket_count,
01357                         _M_element_count, 1);
01358 
01359     // First compute the hash code so that we don't do anything if it throws.
01360     typename _Hashtable::_Hash_code_type __code
01361       = this->_M_hash_code(this->_M_extract()(__v));
01362 
01363     _Node* __new_node = nullptr;
01364     __try
01365       {
01366         // Second allocate new node so that we don't rehash if it throws.
01367         __new_node = _M_allocate_node(std::forward<_Arg>(__v));
01368         this->_M_store_code(__new_node, __code);
01369         if (__do_rehash.first)
01370         _M_rehash(__do_rehash.second, __saved_state);
01371 
01372         // Third, find the node before an equivalent one.
01373         size_type __bkt = _M_bucket_index(__new_node);
01374         _BaseNode* __prev
01375           = _M_find_before_node(__bkt, this->_M_extract()(__new_node->_M_v),
01376                     __code);
01377         if (__prev)
01378           {
01379         // Insert after the node before the equivalent one.
01380         __new_node->_M_nxt = __prev->_M_nxt;
01381         __prev->_M_nxt = __new_node;
01382           }
01383         else
01384           // The inserted node has no equivalent in the hashtable. We must
01385           // insert the new node at the beginning of the bucket to preserve
01386           // equivalent elements relative positions.
01387           _M_insert_bucket_begin(__bkt, __new_node);
01388         ++_M_element_count;
01389         return iterator(__new_node);
01390       }
01391     __catch(...)
01392       {
01393         if (!__new_node)
01394           _M_rehash_policy._M_reset(__saved_state);
01395         else
01396           _M_deallocate_node(__new_node);
01397         __throw_exception_again;
01398       }
01399       }
01400 
01401   template<typename _Key, typename _Value,
01402        typename _Allocator, typename _ExtractKey, typename _Equal,
01403        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01404        bool __chc, bool __cit, bool __uk>
01405     template<typename _InputIterator>
01406       void
01407       _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01408          _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01409       insert(_InputIterator __first, _InputIterator __last)
01410       {
01411     size_type __n_elt = __detail::__distance_fw(__first, __last);
01412     const _RehashPolicyState& __saved_state = _M_rehash_policy._M_state();
01413     std::pair<bool, std::size_t> __do_rehash
01414       = _M_rehash_policy._M_need_rehash(_M_bucket_count,
01415                         _M_element_count, __n_elt);
01416     if (__do_rehash.first)
01417       _M_rehash(__do_rehash.second, __saved_state);
01418 
01419     for (; __first != __last; ++__first)
01420       this->insert(*__first);
01421       }
01422 
01423   template<typename _Key, typename _Value,
01424        typename _Allocator, typename _ExtractKey, typename _Equal,
01425        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01426        bool __chc, bool __cit, bool __uk>
01427     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01428             _H1, _H2, _Hash, _RehashPolicy,
01429             __chc, __cit, __uk>::iterator
01430     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01431            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01432     erase(const_iterator __it)
01433     {
01434       _Node* __n = __it._M_cur;
01435       std::size_t __bkt = _M_bucket_index(__n);
01436 
01437       // Look for previous node to unlink it from the erased one, this is why
01438       // we need buckets to contain the before begin to make this search fast.
01439       _BaseNode* __prev_n = _M_get_previous_node(__bkt, __n);
01440       if (__n == _M_bucket_begin(__bkt))
01441     _M_remove_bucket_begin(__bkt, __n->_M_next(),
01442        __n->_M_nxt ? _M_bucket_index(__n->_M_next()) : 0);
01443       else if (__n->_M_nxt)
01444     {
01445       size_type __next_bkt = _M_bucket_index(__n->_M_next());
01446       if (__next_bkt != __bkt)
01447         _M_buckets[__next_bkt] = __prev_n;
01448     }
01449 
01450       __prev_n->_M_nxt = __n->_M_nxt;
01451       iterator __result(__n->_M_next());
01452       _M_deallocate_node(__n);
01453       --_M_element_count;
01454 
01455       return __result;
01456     }
01457 
01458   template<typename _Key, typename _Value,
01459        typename _Allocator, typename _ExtractKey, typename _Equal,
01460        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01461        bool __chc, bool __cit, bool __uk>
01462     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01463             _H1, _H2, _Hash, _RehashPolicy,
01464             __chc, __cit, __uk>::size_type
01465     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01466            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01467     erase(const key_type& __k)
01468     {
01469       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
01470       std::size_t __bkt = _M_bucket_index(__k, __code);
01471       // Look for the node before the first matching node.
01472       _BaseNode* __prev_n = _M_find_before_node(__bkt, __k, __code);
01473       if (!__prev_n)
01474     return 0;
01475       _Node* __n = static_cast<_Node*>(__prev_n->_M_nxt);
01476       bool __is_bucket_begin = _M_buckets[__bkt] == __prev_n;
01477 
01478       // We found a matching node, start deallocation loop from it
01479       std::size_t __next_bkt = __bkt;
01480       _Node* __next_n = __n;
01481       size_type __result = 0;
01482       _Node* __saved_n = nullptr;
01483       do
01484     {
01485       _Node* __p = __next_n;
01486       __next_n = __p->_M_next();
01487       // _GLIBCXX_RESOLVE_LIB_DEFECTS
01488       // 526. Is it undefined if a function in the standard changes
01489       // in parameters?
01490       if (std::__addressof(this->_M_extract()(__p->_M_v))
01491           != std::__addressof(__k))
01492         _M_deallocate_node(__p);
01493       else
01494         __saved_n = __p;
01495       --_M_element_count;
01496       ++__result;
01497       if (!__next_n)
01498         break;
01499       __next_bkt = _M_bucket_index(__next_n);
01500     }
01501       while (__next_bkt == __bkt && this->_M_equals(__k, __code, __next_n));
01502 
01503       if (__saved_n)
01504     _M_deallocate_node(__saved_n);
01505       if (__is_bucket_begin)
01506     _M_remove_bucket_begin(__bkt, __next_n, __next_bkt);
01507       else if (__next_n && __next_bkt != __bkt)
01508     _M_buckets[__next_bkt] = __prev_n;
01509       if (__prev_n)
01510     __prev_n->_M_nxt = __next_n;
01511       return __result;
01512     }
01513 
01514   template<typename _Key, typename _Value,
01515        typename _Allocator, typename _ExtractKey, typename _Equal,
01516        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01517        bool __chc, bool __cit, bool __uk>
01518     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01519             _H1, _H2, _Hash, _RehashPolicy,
01520             __chc, __cit, __uk>::iterator
01521     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01522            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01523     erase(const_iterator __first, const_iterator __last)
01524     {
01525       _Node* __n = __first._M_cur;
01526       _Node* __last_n = __last._M_cur;
01527       if (__n == __last_n)
01528     return iterator(__n);
01529 
01530       std::size_t __bkt = _M_bucket_index(__n);
01531 
01532       _BaseNode* __prev_n = _M_get_previous_node(__bkt, __n);
01533       bool __is_bucket_begin = __n == _M_bucket_begin(__bkt);
01534       std::size_t __n_bkt = __bkt;
01535       for (;;)
01536     {
01537       do
01538         {
01539           _Node* __tmp = __n;
01540           __n = __n->_M_next();
01541           _M_deallocate_node(__tmp);
01542           --_M_element_count;
01543           if (!__n)
01544         break;
01545           __n_bkt = _M_bucket_index(__n);
01546         }
01547       while (__n != __last_n && __n_bkt == __bkt);
01548       if (__is_bucket_begin)
01549         _M_remove_bucket_begin(__bkt, __n, __n_bkt);
01550       if (__n == __last_n)
01551         break;
01552       __is_bucket_begin = true;
01553       __bkt = __n_bkt;
01554     }
01555 
01556       if (__n && (__n_bkt != __bkt || __is_bucket_begin))
01557     _M_buckets[__n_bkt] = __prev_n;
01558       __prev_n->_M_nxt = __n;
01559       return iterator(__n);
01560     }
01561 
01562   template<typename _Key, typename _Value,
01563        typename _Allocator, typename _ExtractKey, typename _Equal,
01564        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01565        bool __chc, bool __cit, bool __uk>
01566     void
01567     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01568            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01569     clear() noexcept
01570     {
01571       _M_deallocate_nodes(_M_begin());
01572       __builtin_memset(_M_buckets, 0, _M_bucket_count * sizeof(_Bucket));
01573       _M_element_count = 0;
01574       _M_before_begin._M_nxt = nullptr;
01575     }
01576 
01577   template<typename _Key, typename _Value,
01578        typename _Allocator, typename _ExtractKey, typename _Equal,
01579        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01580        bool __chc, bool __cit, bool __uk>
01581     void
01582     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01583            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01584     rehash(size_type __n)
01585     {
01586       const _RehashPolicyState& __saved_state = _M_rehash_policy._M_state();
01587       std::size_t __buckets
01588     = _M_rehash_policy._M_bkt_for_elements(_M_element_count + 1);
01589       if (__buckets <= __n)
01590     __buckets = _M_rehash_policy._M_next_bkt(__n);
01591 
01592       if (__buckets != _M_bucket_count)
01593     {
01594       _M_rehash(__buckets, __saved_state);
01595       
01596       // We don't want the rehash policy to ask for the hashtable to shrink
01597       // on the next insertion so we need to reset its previous resize
01598       // level.
01599       _M_rehash_policy._M_prev_resize = 0;
01600     }
01601       else
01602     // No rehash, restore previous state to keep a consistent state.
01603     _M_rehash_policy._M_reset(__saved_state);
01604     }
01605 
01606   template<typename _Key, typename _Value,
01607        typename _Allocator, typename _ExtractKey, typename _Equal,
01608        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01609        bool __chc, bool __cit, bool __uk>
01610     void
01611     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01612            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01613     _M_rehash(size_type __n, const _RehashPolicyState& __state)
01614     {
01615       __try
01616     {
01617       _M_rehash_aux(__n, integral_constant<bool, __uk>());
01618     }
01619       __catch(...)
01620     {
01621       // A failure here means that buckets allocation failed.  We only
01622       // have to restore hash policy previous state.
01623       _M_rehash_policy._M_reset(__state);
01624       __throw_exception_again;
01625     }
01626     }
01627 
01628   // Rehash when there is no equivalent elements.
01629   template<typename _Key, typename _Value,
01630        typename _Allocator, typename _ExtractKey, typename _Equal,
01631        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01632        bool __chc, bool __cit, bool __uk>
01633     void
01634     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01635            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01636     _M_rehash_aux(size_type __n, std::true_type)
01637     {
01638       _Bucket* __new_buckets = _M_allocate_buckets(__n);
01639       _Node* __p = _M_begin();
01640       _M_before_begin._M_nxt = nullptr;
01641       std::size_t __bbegin_bkt = 0;
01642       while (__p)
01643     {
01644       _Node* __next = __p->_M_next();
01645       std::size_t __bkt = _HCBase::_M_bucket_index(__p, __n);
01646       if (!__new_buckets[__bkt])
01647         {
01648           __p->_M_nxt = _M_before_begin._M_nxt;
01649           _M_before_begin._M_nxt = __p;
01650           __new_buckets[__bkt] = &_M_before_begin;
01651           if (__p->_M_nxt)
01652         __new_buckets[__bbegin_bkt] = __p;
01653           __bbegin_bkt = __bkt;
01654         }
01655       else
01656         {
01657           __p->_M_nxt = __new_buckets[__bkt]->_M_nxt;
01658           __new_buckets[__bkt]->_M_nxt = __p;
01659         }
01660       __p = __next;
01661     }
01662       _M_deallocate_buckets(_M_buckets, _M_bucket_count);
01663       _M_bucket_count = __n;
01664       _M_buckets = __new_buckets;
01665     }
01666 
01667   // Rehash when there can be equivalent elements, preserve their relative
01668   // order.
01669   template<typename _Key, typename _Value,
01670        typename _Allocator, typename _ExtractKey, typename _Equal,
01671        typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
01672        bool __chc, bool __cit, bool __uk>
01673     void
01674     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
01675            _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
01676     _M_rehash_aux(size_type __n, std::false_type)
01677     {
01678       _Bucket* __new_buckets = _M_allocate_buckets(__n);
01679 
01680       _Node* __p = _M_begin();
01681       _M_before_begin._M_nxt = nullptr;
01682       std::size_t __bbegin_bkt = 0;
01683       std::size_t __prev_bkt = 0;
01684       _Node* __prev_p = nullptr;
01685       bool __check_bucket = false;
01686 
01687       while (__p)
01688     {
01689       _Node* __next = __p->_M_next();
01690       std::size_t __bkt = _HCBase::_M_bucket_index(__p, __n);
01691 
01692       if (__prev_p && __prev_bkt == __bkt)
01693         {
01694           // Previous insert was already in this bucket, we insert after
01695           // the previously inserted one to preserve equivalent elements
01696           // relative order.
01697           __p->_M_nxt = __prev_p->_M_nxt;
01698           __prev_p->_M_nxt = __p;
01699           
01700           // Inserting after a node in a bucket require to check that we
01701           // haven't change the bucket last node, in this case next
01702           // bucket containing its before begin node must be updated. We
01703           // schedule a check as soon as we move out of the sequence of
01704           // equivalent nodes to limit the number of checks.
01705           __check_bucket = true;
01706         }
01707       else
01708         {
01709           if (__check_bucket)
01710         {
01711           // Check if we shall update the next bucket because of
01712           // insertions into __prev_bkt bucket.
01713           if (__prev_p->_M_nxt)
01714             {
01715               std::size_t __next_bkt
01716             = _HCBase::_M_bucket_index(__prev_p->_M_next(), __n);
01717               if (__next_bkt != __prev_bkt)
01718             __new_buckets[__next_bkt] = __prev_p;
01719             }
01720           __check_bucket = false;
01721         }
01722           if (!__new_buckets[__bkt])
01723         {
01724           __p->_M_nxt = _M_before_begin._M_nxt;
01725           _M_before_begin._M_nxt = __p;
01726           __new_buckets[__bkt] = &_M_before_begin;
01727           if (__p->_M_nxt)
01728             __new_buckets[__bbegin_bkt] = __p;
01729           __bbegin_bkt = __bkt;
01730         }
01731           else
01732         {
01733           __p->_M_nxt = __new_buckets[__bkt]->_M_nxt;
01734           __new_buckets[__bkt]->_M_nxt = __p;
01735         }
01736         }
01737 
01738       __prev_p = __p;
01739       __prev_bkt = __bkt;
01740       __p = __next;
01741     }
01742 
01743       if (__check_bucket && __prev_p->_M_nxt)
01744     {
01745       std::size_t __next_bkt
01746         = _HCBase::_M_bucket_index(__prev_p->_M_next(), __n);
01747       if (__next_bkt != __prev_bkt)
01748         __new_buckets[__next_bkt] = __prev_p;
01749     }
01750 
01751       _M_deallocate_buckets(_M_buckets, _M_bucket_count);
01752       _M_bucket_count = __n;
01753       _M_buckets = __new_buckets;
01754     }
01755 
01756 _GLIBCXX_END_NAMESPACE_VERSION
01757 } // namespace std
01758 
01759 #endif // _HASHTABLE_H