Home | History | Annotate | Download | only in tr1
      1 // TR1 hashtable.h header -*- C++ -*-
      2 
      3 // Copyright (C) 2007-2013 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file tr1/hashtable.h
     26  *  This is an internal header file, included by other library headers.
     27  *  Do not attempt to use it directly.
     28  *  @headername{tr1/unordered_set, tr1/unordered_map}
     29  */
     30 
     31 #ifndef _GLIBCXX_TR1_HASHTABLE_H
     32 #define _GLIBCXX_TR1_HASHTABLE_H 1
     33 
     34 #pragma GCC system_header
     35 
     36 #include <tr1/hashtable_policy.h>
     37 
     38 namespace std _GLIBCXX_VISIBILITY(default)
     39 {
     40 namespace tr1
     41 {
     42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     43 
     44   // Class template _Hashtable, class definition.
     45 
     46   // Meaning of class template _Hashtable's template parameters
     47 
     48   // _Key and _Value: arbitrary CopyConstructible types.
     49 
     50   // _Allocator: an allocator type ([lib.allocator.requirements]) whose
     51   // value type is Value.  As a conforming extension, we allow for
     52   // value type != Value.
     53 
     54   // _ExtractKey: function object that takes a object of type Value
     55   // and returns a value of type _Key.
     56 
     57   // _Equal: function object that takes two objects of type k and returns
     58   // a bool-like value that is true if the two objects are considered equal.
     59 
     60   // _H1: the hash function.  A unary function object with argument type
     61   // Key and result type size_t.  Return values should be distributed
     62   // over the entire range [0, numeric_limits<size_t>:::max()].
     63 
     64   // _H2: the range-hashing function (in the terminology of Tavori and
     65   // Dreizin).  A binary function object whose argument types and result
     66   // type are all size_t.  Given arguments r and N, the return value is
     67   // in the range [0, N).
     68 
     69   // _Hash: the ranged hash function (Tavori and Dreizin). A binary function
     70   // whose argument types are _Key and size_t and whose result type is
     71   // size_t.  Given arguments k and N, the return value is in the range
     72   // [0, N).  Default: hash(k, N) = h2(h1(k), N).  If _Hash is anything other
     73   // than the default, _H1 and _H2 are ignored.
     74 
     75   // _RehashPolicy: Policy class with three members, all of which govern
     76   // the bucket count. _M_next_bkt(n) returns a bucket count no smaller
     77   // than n.  _M_bkt_for_elements(n) returns a bucket count appropriate
     78   // for an element count of n.  _M_need_rehash(n_bkt, n_elt, n_ins)
     79   // determines whether, if the current bucket count is n_bkt and the
     80   // current element count is n_elt, we need to increase the bucket
     81   // count.  If so, returns make_pair(true, n), where n is the new
     82   // bucket count.  If not, returns make_pair(false, <anything>).
     83 
     84   // ??? Right now it is hard-wired that the number of buckets never
     85   // shrinks.  Should we allow _RehashPolicy to change that?
     86 
     87   // __cache_hash_code: bool.  true if we store the value of the hash
     88   // function along with the value.  This is a time-space tradeoff.
     89   // Storing it may improve lookup speed by reducing the number of times
     90   // we need to call the Equal function.
     91 
     92   // __constant_iterators: bool.  true if iterator and const_iterator are
     93   // both constant iterator types.  This is true for unordered_set and
     94   // unordered_multiset, false for unordered_map and unordered_multimap.
     95 
     96   // __unique_keys: bool.  true if the return value of _Hashtable::count(k)
     97   // is always at most one, false if it may be an arbitrary number.  This
     98   // true for unordered_set and unordered_map, false for unordered_multiset
     99   // and unordered_multimap.
    100 
    101   template<typename _Key, typename _Value, typename _Allocator,
    102 	   typename _ExtractKey, typename _Equal,
    103 	   typename _H1, typename _H2, typename _Hash,
    104 	   typename _RehashPolicy,
    105 	   bool __cache_hash_code,
    106 	   bool __constant_iterators,
    107 	   bool __unique_keys>
    108     class _Hashtable
    109     : public __detail::_Rehash_base<_RehashPolicy,
    110 				    _Hashtable<_Key, _Value, _Allocator,
    111 					       _ExtractKey,
    112 					       _Equal, _H1, _H2, _Hash,
    113 					       _RehashPolicy,
    114 					       __cache_hash_code,
    115 					       __constant_iterators,
    116 					       __unique_keys> >,
    117       public __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
    118 				       _H1, _H2, _Hash, __cache_hash_code>,
    119       public __detail::_Map_base<_Key, _Value, _ExtractKey, __unique_keys,
    120 				 _Hashtable<_Key, _Value, _Allocator,
    121 					    _ExtractKey,
    122 					    _Equal, _H1, _H2, _Hash,
    123 					    _RehashPolicy,
    124 					    __cache_hash_code,
    125 					    __constant_iterators,
    126 					    __unique_keys> >
    127     {
    128     public:
    129       typedef _Allocator                                  allocator_type;
    130       typedef _Value                                      value_type;
    131       typedef _Key                                        key_type;
    132       typedef _Equal                                      key_equal;
    133       // mapped_type, if present, comes from _Map_base.
    134       // hasher, if present, comes from _Hash_code_base.
    135       typedef typename _Allocator::difference_type        difference_type;
    136       typedef typename _Allocator::size_type              size_type;
    137       typedef typename _Allocator::pointer                pointer;
    138       typedef typename _Allocator::const_pointer          const_pointer;
    139       typedef typename _Allocator::reference              reference;
    140       typedef typename _Allocator::const_reference        const_reference;
    141 
    142       typedef __detail::_Node_iterator<value_type, __constant_iterators,
    143 				       __cache_hash_code>
    144 							  local_iterator;
    145       typedef __detail::_Node_const_iterator<value_type,
    146 					     __constant_iterators,
    147 					     __cache_hash_code>
    148 							  const_local_iterator;
    149 
    150       typedef __detail::_Hashtable_iterator<value_type, __constant_iterators,
    151 					    __cache_hash_code>
    152 							  iterator;
    153       typedef __detail::_Hashtable_const_iterator<value_type,
    154 						  __constant_iterators,
    155 						  __cache_hash_code>
    156 							  const_iterator;
    157 
    158       template<typename _Key2, typename _Value2, typename _Ex2, bool __unique2,
    159 	       typename _Hashtable2>
    160 	friend struct __detail::_Map_base;
    161 
    162     private:
    163       typedef __detail::_Hash_node<_Value, __cache_hash_code> _Node;
    164       typedef typename _Allocator::template rebind<_Node>::other
    165 							_Node_allocator_type;
    166       typedef typename _Allocator::template rebind<_Node*>::other
    167 							_Bucket_allocator_type;
    168 
    169       typedef typename _Allocator::template rebind<_Value>::other
    170 							_Value_allocator_type;
    171 
    172       _Node_allocator_type   _M_node_allocator;
    173       _Node**                _M_buckets;
    174       size_type              _M_bucket_count;
    175       size_type              _M_element_count;
    176       _RehashPolicy          _M_rehash_policy;
    177 
    178       _Node*
    179       _M_allocate_node(const value_type& __v);
    180 
    181       void
    182       _M_deallocate_node(_Node* __n);
    183 
    184       void
    185       _M_deallocate_nodes(_Node**, size_type);
    186 
    187       _Node**
    188       _M_allocate_buckets(size_type __n);
    189 
    190       void
    191       _M_deallocate_buckets(_Node**, size_type __n);
    192 
    193     public:
    194       // Constructor, destructor, assignment, swap
    195       _Hashtable(size_type __bucket_hint,
    196 		 const _H1&, const _H2&, const _Hash&,
    197 		 const _Equal&, const _ExtractKey&,
    198 		 const allocator_type&);
    199 
    200       template<typename _InputIterator>
    201 	_Hashtable(_InputIterator __first, _InputIterator __last,
    202 		   size_type __bucket_hint,
    203 		   const _H1&, const _H2&, const _Hash&,
    204 		   const _Equal&, const _ExtractKey&,
    205 		   const allocator_type&);
    206 
    207       _Hashtable(const _Hashtable&);
    208 
    209       _Hashtable&
    210       operator=(const _Hashtable&);
    211 
    212       ~_Hashtable();
    213 
    214       void swap(_Hashtable&);
    215 
    216       // Basic container operations
    217       iterator
    218       begin()
    219       {
    220 	iterator __i(_M_buckets);
    221 	if (!__i._M_cur_node)
    222 	  __i._M_incr_bucket();
    223 	return __i;
    224       }
    225 
    226       const_iterator
    227       begin() const
    228       {
    229 	const_iterator __i(_M_buckets);
    230 	if (!__i._M_cur_node)
    231 	  __i._M_incr_bucket();
    232 	return __i;
    233       }
    234 
    235       iterator
    236       end()
    237       { return iterator(_M_buckets + _M_bucket_count); }
    238 
    239       const_iterator
    240       end() const
    241       { return const_iterator(_M_buckets + _M_bucket_count); }
    242 
    243       size_type
    244       size() const
    245       { return _M_element_count; }
    246 
    247       bool
    248       empty() const
    249       { return size() == 0; }
    250 
    251       allocator_type
    252       get_allocator() const
    253       { return allocator_type(_M_node_allocator); }
    254 
    255       _Value_allocator_type
    256       _M_get_Value_allocator() const
    257       { return _Value_allocator_type(_M_node_allocator); }
    258 
    259       size_type
    260       max_size() const
    261       { return _M_node_allocator.max_size(); }
    262 
    263       // Observers
    264       key_equal
    265       key_eq() const
    266       { return this->_M_eq; }
    267 
    268       // hash_function, if present, comes from _Hash_code_base.
    269 
    270       // Bucket operations
    271       size_type
    272       bucket_count() const
    273       { return _M_bucket_count; }
    274 
    275       size_type
    276       max_bucket_count() const
    277       { return max_size(); }
    278 
    279       size_type
    280       bucket_size(size_type __n) const
    281       { return std::distance(begin(__n), end(__n)); }
    282 
    283       size_type
    284       bucket(const key_type& __k) const
    285       {
    286 	return this->_M_bucket_index(__k, this->_M_hash_code(__k),
    287 				     bucket_count());
    288       }
    289 
    290       local_iterator
    291       begin(size_type __n)
    292       { return local_iterator(_M_buckets[__n]); }
    293 
    294       local_iterator
    295       end(size_type)
    296       { return local_iterator(0); }
    297 
    298       const_local_iterator
    299       begin(size_type __n) const
    300       { return const_local_iterator(_M_buckets[__n]); }
    301 
    302       const_local_iterator
    303       end(size_type) const
    304       { return const_local_iterator(0); }
    305 
    306       float
    307       load_factor() const
    308       {
    309 	return static_cast<float>(size()) / static_cast<float>(bucket_count());
    310       }
    311 
    312       // max_load_factor, if present, comes from _Rehash_base.
    313 
    314       // Generalization of max_load_factor.  Extension, not found in TR1.  Only
    315       // useful if _RehashPolicy is something other than the default.
    316       const _RehashPolicy&
    317       __rehash_policy() const
    318       { return _M_rehash_policy; }
    319 
    320       void
    321       __rehash_policy(const _RehashPolicy&);
    322 
    323       // Lookup.
    324       iterator
    325       find(const key_type& __k);
    326 
    327       const_iterator
    328       find(const key_type& __k) const;
    329 
    330       size_type
    331       count(const key_type& __k) const;
    332 
    333       std::pair<iterator, iterator>
    334       equal_range(const key_type& __k);
    335 
    336       std::pair<const_iterator, const_iterator>
    337       equal_range(const key_type& __k) const;
    338 
    339     private:			// Find, insert and erase helper functions
    340       // ??? This dispatching is a workaround for the fact that we don't
    341       // have partial specialization of member templates; it would be
    342       // better to just specialize insert on __unique_keys.  There may be a
    343       // cleaner workaround.
    344       typedef typename __gnu_cxx::__conditional_type<__unique_keys,
    345 		       	    std::pair<iterator, bool>, iterator>::__type
    346 	_Insert_Return_Type;
    347 
    348       typedef typename __gnu_cxx::__conditional_type<__unique_keys,
    349 					  std::_Select1st<_Insert_Return_Type>,
    350 				  	  std::_Identity<_Insert_Return_Type>
    351 				   >::__type
    352 	_Insert_Conv_Type;
    353 
    354       _Node*
    355       _M_find_node(_Node*, const key_type&,
    356 		   typename _Hashtable::_Hash_code_type) const;
    357 
    358       iterator
    359       _M_insert_bucket(const value_type&, size_type,
    360 		       typename _Hashtable::_Hash_code_type);
    361 
    362       std::pair<iterator, bool>
    363       _M_insert(const value_type&, std::tr1::true_type);
    364 
    365       iterator
    366       _M_insert(const value_type&, std::tr1::false_type);
    367 
    368       void
    369       _M_erase_node(_Node*, _Node**);
    370 
    371     public:
    372       // Insert and erase
    373       _Insert_Return_Type
    374       insert(const value_type& __v)
    375       { return _M_insert(__v, std::tr1::integral_constant<bool,
    376 			 __unique_keys>()); }
    377 
    378       iterator
    379       insert(iterator, const value_type& __v)
    380       { return iterator(_Insert_Conv_Type()(this->insert(__v))); }
    381 
    382       const_iterator
    383       insert(const_iterator, const value_type& __v)
    384       { return const_iterator(_Insert_Conv_Type()(this->insert(__v))); }
    385 
    386       template<typename _InputIterator>
    387 	void
    388 	insert(_InputIterator __first, _InputIterator __last);
    389 
    390       iterator
    391       erase(iterator);
    392 
    393       const_iterator
    394       erase(const_iterator);
    395 
    396       size_type
    397       erase(const key_type&);
    398 
    399       iterator
    400       erase(iterator, iterator);
    401 
    402       const_iterator
    403       erase(const_iterator, const_iterator);
    404 
    405       void
    406       clear();
    407 
    408       // Set number of buckets to be appropriate for container of n element.
    409       void rehash(size_type __n);
    410 
    411     private:
    412       // Unconditionally change size of bucket array to n.
    413       void _M_rehash(size_type __n);
    414     };
    415 
    416 
    417   // Definitions of class template _Hashtable's out-of-line member functions.
    418   template<typename _Key, typename _Value,
    419 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    420 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    421 	   bool __chc, bool __cit, bool __uk>
    422     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    423 			_H1, _H2, _Hash, _RehashPolicy,
    424 			__chc, __cit, __uk>::_Node*
    425     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    426 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    427     _M_allocate_node(const value_type& __v)
    428     {
    429       _Node* __n = _M_node_allocator.allocate(1);
    430       __try
    431 	{
    432 	  _M_get_Value_allocator().construct(&__n->_M_v, __v);
    433 	  __n->_M_next = 0;
    434 	  return __n;
    435 	}
    436       __catch(...)
    437 	{
    438 	  _M_node_allocator.deallocate(__n, 1);
    439 	  __throw_exception_again;
    440 	}
    441     }
    442 
    443   template<typename _Key, typename _Value,
    444 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    445 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    446 	   bool __chc, bool __cit, bool __uk>
    447     void
    448     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    449 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    450     _M_deallocate_node(_Node* __n)
    451     {
    452       _M_get_Value_allocator().destroy(&__n->_M_v);
    453       _M_node_allocator.deallocate(__n, 1);
    454     }
    455 
    456   template<typename _Key, typename _Value,
    457 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    458 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    459 	   bool __chc, bool __cit, bool __uk>
    460     void
    461     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    462 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    463     _M_deallocate_nodes(_Node** __array, size_type __n)
    464     {
    465       for (size_type __i = 0; __i < __n; ++__i)
    466 	{
    467 	  _Node* __p = __array[__i];
    468 	  while (__p)
    469 	    {
    470 	      _Node* __tmp = __p;
    471 	      __p = __p->_M_next;
    472 	      _M_deallocate_node(__tmp);
    473 	    }
    474 	  __array[__i] = 0;
    475 	}
    476     }
    477 
    478   template<typename _Key, typename _Value,
    479 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    480 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    481 	   bool __chc, bool __cit, bool __uk>
    482     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    483 			_H1, _H2, _Hash, _RehashPolicy,
    484 			__chc, __cit, __uk>::_Node**
    485     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    486 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    487     _M_allocate_buckets(size_type __n)
    488     {
    489       _Bucket_allocator_type __alloc(_M_node_allocator);
    490 
    491       // We allocate one extra bucket to hold a sentinel, an arbitrary
    492       // non-null pointer.  Iterator increment relies on this.
    493       _Node** __p = __alloc.allocate(__n + 1);
    494       std::fill(__p, __p + __n, (_Node*) 0);
    495       __p[__n] = reinterpret_cast<_Node*>(0x1000);
    496       return __p;
    497     }
    498 
    499   template<typename _Key, typename _Value,
    500 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    501 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    502 	   bool __chc, bool __cit, bool __uk>
    503     void
    504     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    505 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    506     _M_deallocate_buckets(_Node** __p, size_type __n)
    507     {
    508       _Bucket_allocator_type __alloc(_M_node_allocator);
    509       __alloc.deallocate(__p, __n + 1);
    510     }
    511 
    512   template<typename _Key, typename _Value,
    513 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    514 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    515 	   bool __chc, bool __cit, bool __uk>
    516     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    517 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    518     _Hashtable(size_type __bucket_hint,
    519 	       const _H1& __h1, const _H2& __h2, const _Hash& __h,
    520 	       const _Equal& __eq, const _ExtractKey& __exk,
    521 	       const allocator_type& __a)
    522     : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(),
    523       __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
    524 				_H1, _H2, _Hash, __chc>(__exk, __eq,
    525 							__h1, __h2, __h),
    526       __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(),
    527       _M_node_allocator(__a),
    528       _M_bucket_count(0),
    529       _M_element_count(0),
    530       _M_rehash_policy()
    531     {
    532       _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint);
    533       _M_buckets = _M_allocate_buckets(_M_bucket_count);
    534     }
    535 
    536   template<typename _Key, typename _Value,
    537 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    538 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    539 	   bool __chc, bool __cit, bool __uk>
    540     template<typename _InputIterator>
    541       _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    542 		 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    543       _Hashtable(_InputIterator __f, _InputIterator __l,
    544 		 size_type __bucket_hint,
    545 		 const _H1& __h1, const _H2& __h2, const _Hash& __h,
    546 		 const _Equal& __eq, const _ExtractKey& __exk,
    547 		 const allocator_type& __a)
    548       : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(),
    549 	__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
    550 				  _H1, _H2, _Hash, __chc>(__exk, __eq,
    551 							  __h1, __h2, __h),
    552 	__detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(),
    553 	_M_node_allocator(__a),
    554 	_M_bucket_count(0),
    555 	_M_element_count(0),
    556 	_M_rehash_policy()
    557       {
    558 	_M_bucket_count = std::max(_M_rehash_policy._M_next_bkt(__bucket_hint),
    559 				   _M_rehash_policy.
    560 				   _M_bkt_for_elements(__detail::
    561 						       __distance_fw(__f,
    562 								     __l)));
    563 	_M_buckets = _M_allocate_buckets(_M_bucket_count);
    564 	__try
    565 	  {
    566 	    for (; __f != __l; ++__f)
    567 	      this->insert(*__f);
    568 	  }
    569 	__catch(...)
    570 	  {
    571 	    clear();
    572 	    _M_deallocate_buckets(_M_buckets, _M_bucket_count);
    573 	    __throw_exception_again;
    574 	  }
    575       }
    576 
    577   template<typename _Key, typename _Value,
    578 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    579 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    580 	   bool __chc, bool __cit, bool __uk>
    581     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    582 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    583     _Hashtable(const _Hashtable& __ht)
    584     : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(__ht),
    585       __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
    586 				_H1, _H2, _Hash, __chc>(__ht),
    587       __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(__ht),
    588       _M_node_allocator(__ht._M_node_allocator),
    589       _M_bucket_count(__ht._M_bucket_count),
    590       _M_element_count(__ht._M_element_count),
    591       _M_rehash_policy(__ht._M_rehash_policy)
    592     {
    593       _M_buckets = _M_allocate_buckets(_M_bucket_count);
    594       __try
    595 	{
    596 	  for (size_type __i = 0; __i < __ht._M_bucket_count; ++__i)
    597 	    {
    598 	      _Node* __n = __ht._M_buckets[__i];
    599 	      _Node** __tail = _M_buckets + __i;
    600 	      while (__n)
    601 		{
    602 		  *__tail = _M_allocate_node(__n->_M_v);
    603 		  this->_M_copy_code(*__tail, __n);
    604 		  __tail = &((*__tail)->_M_next);
    605 		  __n = __n->_M_next;
    606 		}
    607 	    }
    608 	}
    609       __catch(...)
    610 	{
    611 	  clear();
    612 	  _M_deallocate_buckets(_M_buckets, _M_bucket_count);
    613 	  __throw_exception_again;
    614 	}
    615     }
    616 
    617   template<typename _Key, typename _Value,
    618 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    619 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    620 	   bool __chc, bool __cit, bool __uk>
    621     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    622 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>&
    623     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    624 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    625     operator=(const _Hashtable& __ht)
    626     {
    627       _Hashtable __tmp(__ht);
    628       this->swap(__tmp);
    629       return *this;
    630     }
    631 
    632   template<typename _Key, typename _Value,
    633 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    634 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    635 	   bool __chc, bool __cit, bool __uk>
    636     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    637 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    638     ~_Hashtable()
    639     {
    640       clear();
    641       _M_deallocate_buckets(_M_buckets, _M_bucket_count);
    642     }
    643 
    644   template<typename _Key, typename _Value,
    645 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    646 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    647 	   bool __chc, bool __cit, bool __uk>
    648     void
    649     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    650 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    651     swap(_Hashtable& __x)
    652     {
    653       // The only base class with member variables is hash_code_base.  We
    654       // define _Hash_code_base::_M_swap because different specializations
    655       // have different members.
    656       __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
    657 	_H1, _H2, _Hash, __chc>::_M_swap(__x);
    658 
    659       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    660       // 431. Swapping containers with unequal allocators.
    661       std::__alloc_swap<_Node_allocator_type>::_S_do_it(_M_node_allocator,
    662 							__x._M_node_allocator);
    663 
    664       std::swap(_M_rehash_policy, __x._M_rehash_policy);
    665       std::swap(_M_buckets, __x._M_buckets);
    666       std::swap(_M_bucket_count, __x._M_bucket_count);
    667       std::swap(_M_element_count, __x._M_element_count);
    668     }
    669 
    670   template<typename _Key, typename _Value,
    671 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    672 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    673 	   bool __chc, bool __cit, bool __uk>
    674     void
    675     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    676 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    677     __rehash_policy(const _RehashPolicy& __pol)
    678     {
    679       _M_rehash_policy = __pol;
    680       size_type __n_bkt = __pol._M_bkt_for_elements(_M_element_count);
    681       if (__n_bkt > _M_bucket_count)
    682 	_M_rehash(__n_bkt);
    683     }
    684 
    685   template<typename _Key, typename _Value,
    686 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    687 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    688 	   bool __chc, bool __cit, bool __uk>
    689     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    690 			_H1, _H2, _Hash, _RehashPolicy,
    691 			__chc, __cit, __uk>::iterator
    692     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    693 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    694     find(const key_type& __k)
    695     {
    696       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
    697       std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
    698       _Node* __p = _M_find_node(_M_buckets[__n], __k, __code);
    699       return __p ? iterator(__p, _M_buckets + __n) : this->end();
    700     }
    701 
    702   template<typename _Key, typename _Value,
    703 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    704 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    705 	   bool __chc, bool __cit, bool __uk>
    706     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    707 			_H1, _H2, _Hash, _RehashPolicy,
    708 			__chc, __cit, __uk>::const_iterator
    709     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    710 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    711     find(const key_type& __k) const
    712     {
    713       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
    714       std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
    715       _Node* __p = _M_find_node(_M_buckets[__n], __k, __code);
    716       return __p ? const_iterator(__p, _M_buckets + __n) : this->end();
    717     }
    718 
    719   template<typename _Key, typename _Value,
    720 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    721 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    722 	   bool __chc, bool __cit, bool __uk>
    723     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    724 			_H1, _H2, _Hash, _RehashPolicy,
    725 			__chc, __cit, __uk>::size_type
    726     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    727 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    728     count(const key_type& __k) const
    729     {
    730       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
    731       std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
    732       std::size_t __result = 0;
    733       for (_Node* __p = _M_buckets[__n]; __p; __p = __p->_M_next)
    734 	if (this->_M_compare(__k, __code, __p))
    735 	  ++__result;
    736       return __result;
    737     }
    738 
    739   template<typename _Key, typename _Value,
    740 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    741 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    742 	   bool __chc, bool __cit, bool __uk>
    743     std::pair<typename _Hashtable<_Key, _Value, _Allocator,
    744 				  _ExtractKey, _Equal, _H1,
    745 				  _H2, _Hash, _RehashPolicy,
    746 				  __chc, __cit, __uk>::iterator,
    747 	      typename _Hashtable<_Key, _Value, _Allocator,
    748 				  _ExtractKey, _Equal, _H1,
    749 				  _H2, _Hash, _RehashPolicy,
    750 				  __chc, __cit, __uk>::iterator>
    751     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    752 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    753     equal_range(const key_type& __k)
    754     {
    755       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
    756       std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
    757       _Node** __head = _M_buckets + __n;
    758       _Node* __p = _M_find_node(*__head, __k, __code);
    759 
    760       if (__p)
    761 	{
    762 	  _Node* __p1 = __p->_M_next;
    763 	  for (; __p1; __p1 = __p1->_M_next)
    764 	    if (!this->_M_compare(__k, __code, __p1))
    765 	      break;
    766 
    767 	  iterator __first(__p, __head);
    768 	  iterator __last(__p1, __head);
    769 	  if (!__p1)
    770 	    __last._M_incr_bucket();
    771 	  return std::make_pair(__first, __last);
    772 	}
    773       else
    774 	return std::make_pair(this->end(), this->end());
    775     }
    776 
    777   template<typename _Key, typename _Value,
    778 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    779 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    780 	   bool __chc, bool __cit, bool __uk>
    781     std::pair<typename _Hashtable<_Key, _Value, _Allocator,
    782 				  _ExtractKey, _Equal, _H1,
    783 				  _H2, _Hash, _RehashPolicy,
    784 				  __chc, __cit, __uk>::const_iterator,
    785 	      typename _Hashtable<_Key, _Value, _Allocator,
    786 				  _ExtractKey, _Equal, _H1,
    787 				  _H2, _Hash, _RehashPolicy,
    788 				  __chc, __cit, __uk>::const_iterator>
    789     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    790 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    791     equal_range(const key_type& __k) const
    792     {
    793       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
    794       std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
    795       _Node** __head = _M_buckets + __n;
    796       _Node* __p = _M_find_node(*__head, __k, __code);
    797 
    798       if (__p)
    799 	{
    800 	  _Node* __p1 = __p->_M_next;
    801 	  for (; __p1; __p1 = __p1->_M_next)
    802 	    if (!this->_M_compare(__k, __code, __p1))
    803 	      break;
    804 
    805 	  const_iterator __first(__p, __head);
    806 	  const_iterator __last(__p1, __head);
    807 	  if (!__p1)
    808 	    __last._M_incr_bucket();
    809 	  return std::make_pair(__first, __last);
    810 	}
    811       else
    812 	return std::make_pair(this->end(), this->end());
    813     }
    814 
    815   // Find the node whose key compares equal to k, beginning the search
    816   // at p (usually the head of a bucket).  Return zero if no node is found.
    817   template<typename _Key, typename _Value,
    818 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    819 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    820 	   bool __chc, bool __cit, bool __uk>
    821     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey,
    822 			_Equal, _H1, _H2, _Hash, _RehashPolicy,
    823 			__chc, __cit, __uk>::_Node*
    824     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    825 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    826     _M_find_node(_Node* __p, const key_type& __k,
    827 		typename _Hashtable::_Hash_code_type __code) const
    828     {
    829       for (; __p; __p = __p->_M_next)
    830 	if (this->_M_compare(__k, __code, __p))
    831 	  return __p;
    832       return 0;
    833     }
    834 
    835   // Insert v in bucket n (assumes no element with its key already present).
    836   template<typename _Key, typename _Value,
    837 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    838 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    839 	   bool __chc, bool __cit, bool __uk>
    840     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    841 			_H1, _H2, _Hash, _RehashPolicy,
    842 			__chc, __cit, __uk>::iterator
    843     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    844 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    845     _M_insert_bucket(const value_type& __v, size_type __n,
    846 		    typename _Hashtable::_Hash_code_type __code)
    847     {
    848       std::pair<bool, std::size_t> __do_rehash
    849 	= _M_rehash_policy._M_need_rehash(_M_bucket_count,
    850 					  _M_element_count, 1);
    851 
    852       // Allocate the new node before doing the rehash so that we don't
    853       // do a rehash if the allocation throws.
    854       _Node* __new_node = _M_allocate_node(__v);
    855 
    856       __try
    857 	{
    858 	  if (__do_rehash.first)
    859 	    {
    860 	      const key_type& __k = this->_M_extract(__v);
    861 	      __n = this->_M_bucket_index(__k, __code, __do_rehash.second);
    862 	      _M_rehash(__do_rehash.second);
    863 	    }
    864 
    865 	  __new_node->_M_next = _M_buckets[__n];
    866 	  this->_M_store_code(__new_node, __code);
    867 	  _M_buckets[__n] = __new_node;
    868 	  ++_M_element_count;
    869 	  return iterator(__new_node, _M_buckets + __n);
    870 	}
    871       __catch(...)
    872 	{
    873 	  _M_deallocate_node(__new_node);
    874 	  __throw_exception_again;
    875 	}
    876     }
    877 
    878   // Insert v if no element with its key is already present.
    879   template<typename _Key, typename _Value,
    880 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    881 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    882 	   bool __chc, bool __cit, bool __uk>
    883     std::pair<typename _Hashtable<_Key, _Value, _Allocator,
    884 				  _ExtractKey, _Equal, _H1,
    885 				  _H2, _Hash, _RehashPolicy,
    886 				  __chc, __cit, __uk>::iterator, bool>
    887     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    888 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    889   _M_insert(const value_type& __v, std::tr1::true_type)
    890     {
    891       const key_type& __k = this->_M_extract(__v);
    892       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
    893       size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
    894 
    895       if (_Node* __p = _M_find_node(_M_buckets[__n], __k, __code))
    896 	return std::make_pair(iterator(__p, _M_buckets + __n), false);
    897       return std::make_pair(_M_insert_bucket(__v, __n, __code), true);
    898     }
    899 
    900   // Insert v unconditionally.
    901   template<typename _Key, typename _Value,
    902 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    903 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    904 	   bool __chc, bool __cit, bool __uk>
    905     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    906 			_H1, _H2, _Hash, _RehashPolicy,
    907 			__chc, __cit, __uk>::iterator
    908     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    909 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    910     _M_insert(const value_type& __v, std::tr1::false_type)
    911     {
    912       std::pair<bool, std::size_t> __do_rehash
    913 	= _M_rehash_policy._M_need_rehash(_M_bucket_count,
    914 					  _M_element_count, 1);
    915       if (__do_rehash.first)
    916 	_M_rehash(__do_rehash.second);
    917 
    918       const key_type& __k = this->_M_extract(__v);
    919       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
    920       size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
    921 
    922       // First find the node, avoid leaking new_node if compare throws.
    923       _Node* __prev = _M_find_node(_M_buckets[__n], __k, __code);
    924       _Node* __new_node = _M_allocate_node(__v);
    925 
    926       if (__prev)
    927 	{
    928 	  __new_node->_M_next = __prev->_M_next;
    929 	  __prev->_M_next = __new_node;
    930 	}
    931       else
    932 	{
    933 	  __new_node->_M_next = _M_buckets[__n];
    934 	  _M_buckets[__n] = __new_node;
    935 	}
    936       this->_M_store_code(__new_node, __code);
    937 
    938       ++_M_element_count;
    939       return iterator(__new_node, _M_buckets + __n);
    940     }
    941 
    942   // For erase(iterator) and erase(const_iterator).
    943   template<typename _Key, typename _Value,
    944 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    945 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    946 	   bool __chc, bool __cit, bool __uk>
    947     void
    948     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    949 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    950     _M_erase_node(_Node* __p, _Node** __b)
    951     {
    952       _Node* __cur = *__b;
    953       if (__cur == __p)
    954 	*__b = __cur->_M_next;
    955       else
    956 	{
    957 	  _Node* __next = __cur->_M_next;
    958 	  while (__next != __p)
    959 	    {
    960 	      __cur = __next;
    961 	      __next = __cur->_M_next;
    962 	    }
    963 	  __cur->_M_next = __next->_M_next;
    964 	}
    965 
    966       _M_deallocate_node(__p);
    967       --_M_element_count;
    968     }
    969 
    970   template<typename _Key, typename _Value,
    971 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    972 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    973 	   bool __chc, bool __cit, bool __uk>
    974     template<typename _InputIterator>
    975       void
    976       _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    977 		 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
    978       insert(_InputIterator __first, _InputIterator __last)
    979       {
    980 	size_type __n_elt = __detail::__distance_fw(__first, __last);
    981 	std::pair<bool, std::size_t> __do_rehash
    982 	  = _M_rehash_policy._M_need_rehash(_M_bucket_count,
    983 					    _M_element_count, __n_elt);
    984 	if (__do_rehash.first)
    985 	  _M_rehash(__do_rehash.second);
    986 
    987 	for (; __first != __last; ++__first)
    988 	  this->insert(*__first);
    989       }
    990 
    991   template<typename _Key, typename _Value,
    992 	   typename _Allocator, typename _ExtractKey, typename _Equal,
    993 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
    994 	   bool __chc, bool __cit, bool __uk>
    995     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    996 			_H1, _H2, _Hash, _RehashPolicy,
    997 			__chc, __cit, __uk>::iterator
    998     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
    999 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
   1000     erase(iterator __it)
   1001     {
   1002       iterator __result = __it;
   1003       ++__result;
   1004       _M_erase_node(__it._M_cur_node, __it._M_cur_bucket);
   1005       return __result;
   1006     }
   1007 
   1008   template<typename _Key, typename _Value,
   1009 	   typename _Allocator, typename _ExtractKey, typename _Equal,
   1010 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
   1011 	   bool __chc, bool __cit, bool __uk>
   1012     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1013 			_H1, _H2, _Hash, _RehashPolicy,
   1014 			__chc, __cit, __uk>::const_iterator
   1015     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1016 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
   1017     erase(const_iterator __it)
   1018     {
   1019       const_iterator __result = __it;
   1020       ++__result;
   1021       _M_erase_node(__it._M_cur_node, __it._M_cur_bucket);
   1022       return __result;
   1023     }
   1024 
   1025   template<typename _Key, typename _Value,
   1026 	   typename _Allocator, typename _ExtractKey, typename _Equal,
   1027 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
   1028 	   bool __chc, bool __cit, bool __uk>
   1029     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1030 			_H1, _H2, _Hash, _RehashPolicy,
   1031 			__chc, __cit, __uk>::size_type
   1032     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1033 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
   1034     erase(const key_type& __k)
   1035     {
   1036       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
   1037       std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
   1038       size_type __result = 0;
   1039 
   1040       _Node** __slot = _M_buckets + __n;
   1041       while (*__slot && !this->_M_compare(__k, __code, *__slot))
   1042 	__slot = &((*__slot)->_M_next);
   1043 
   1044       _Node** __saved_slot = 0;
   1045       while (*__slot && this->_M_compare(__k, __code, *__slot))
   1046 	{
   1047 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
   1048 	  // 526. Is it undefined if a function in the standard changes
   1049 	  // in parameters?
   1050 	  if (&this->_M_extract((*__slot)->_M_v) != &__k)
   1051 	    {
   1052 	      _Node* __p = *__slot;
   1053 	      *__slot = __p->_M_next;
   1054 	      _M_deallocate_node(__p);
   1055 	      --_M_element_count;
   1056 	      ++__result;
   1057 	    }
   1058 	  else
   1059 	    {
   1060 	      __saved_slot = __slot;
   1061 	      __slot = &((*__slot)->_M_next);
   1062 	    }
   1063 	}
   1064 
   1065       if (__saved_slot)
   1066 	{
   1067 	  _Node* __p = *__saved_slot;
   1068 	  *__saved_slot = __p->_M_next;
   1069 	  _M_deallocate_node(__p);
   1070 	  --_M_element_count;
   1071 	  ++__result;
   1072 	}
   1073 
   1074       return __result;
   1075     }
   1076 
   1077   // ??? This could be optimized by taking advantage of the bucket
   1078   // structure, but it's not clear that it's worth doing.  It probably
   1079   // wouldn't even be an optimization unless the load factor is large.
   1080   template<typename _Key, typename _Value,
   1081 	   typename _Allocator, typename _ExtractKey, typename _Equal,
   1082 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
   1083 	   bool __chc, bool __cit, bool __uk>
   1084     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1085 			_H1, _H2, _Hash, _RehashPolicy,
   1086 			__chc, __cit, __uk>::iterator
   1087     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1088 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
   1089     erase(iterator __first, iterator __last)
   1090     {
   1091       while (__first != __last)
   1092 	__first = this->erase(__first);
   1093       return __last;
   1094     }
   1095 
   1096   template<typename _Key, typename _Value,
   1097 	   typename _Allocator, typename _ExtractKey, typename _Equal,
   1098 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
   1099 	   bool __chc, bool __cit, bool __uk>
   1100     typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1101 			_H1, _H2, _Hash, _RehashPolicy,
   1102 			__chc, __cit, __uk>::const_iterator
   1103     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1104 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
   1105     erase(const_iterator __first, const_iterator __last)
   1106     {
   1107       while (__first != __last)
   1108 	__first = this->erase(__first);
   1109       return __last;
   1110     }
   1111 
   1112   template<typename _Key, typename _Value,
   1113 	   typename _Allocator, typename _ExtractKey, typename _Equal,
   1114 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
   1115 	   bool __chc, bool __cit, bool __uk>
   1116     void
   1117     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1118 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
   1119     clear()
   1120     {
   1121       _M_deallocate_nodes(_M_buckets, _M_bucket_count);
   1122       _M_element_count = 0;
   1123     }
   1124 
   1125   template<typename _Key, typename _Value,
   1126 	   typename _Allocator, typename _ExtractKey, typename _Equal,
   1127 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
   1128 	   bool __chc, bool __cit, bool __uk>
   1129     void
   1130     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1131 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
   1132     rehash(size_type __n)
   1133     {
   1134       _M_rehash(std::max(_M_rehash_policy._M_next_bkt(__n),
   1135 			 _M_rehash_policy._M_bkt_for_elements(_M_element_count
   1136 							      + 1)));
   1137     }
   1138 
   1139   template<typename _Key, typename _Value,
   1140 	   typename _Allocator, typename _ExtractKey, typename _Equal,
   1141 	   typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
   1142 	   bool __chc, bool __cit, bool __uk>
   1143     void
   1144     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
   1145 	       _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
   1146     _M_rehash(size_type __n)
   1147     {
   1148       _Node** __new_array = _M_allocate_buckets(__n);
   1149       __try
   1150 	{
   1151 	  for (size_type __i = 0; __i < _M_bucket_count; ++__i)
   1152 	    while (_Node* __p = _M_buckets[__i])
   1153 	      {
   1154 		std::size_t __new_index = this->_M_bucket_index(__p, __n);
   1155 		_M_buckets[__i] = __p->_M_next;
   1156 		__p->_M_next = __new_array[__new_index];
   1157 		__new_array[__new_index] = __p;
   1158 	      }
   1159 	  _M_deallocate_buckets(_M_buckets, _M_bucket_count);
   1160 	  _M_bucket_count = __n;
   1161 	  _M_buckets = __new_array;
   1162 	}
   1163       __catch(...)
   1164 	{
   1165 	  // A failure here means that a hash function threw an exception.
   1166 	  // We can't restore the previous state without calling the hash
   1167 	  // function again, so the only sensible recovery is to delete
   1168 	  // everything.
   1169 	  _M_deallocate_nodes(__new_array, __n);
   1170 	  _M_deallocate_buckets(__new_array, __n);
   1171 	  _M_deallocate_nodes(_M_buckets, _M_bucket_count);
   1172 	  _M_element_count = 0;
   1173 	  __throw_exception_again;
   1174 	}
   1175     }
   1176 
   1177 _GLIBCXX_END_NAMESPACE_VERSION
   1178 } // namespace tr1
   1179 } // namespace std
   1180 
   1181 #endif // _GLIBCXX_TR1_HASHTABLE_H
   1182