hashtable_policy.h

Go to the documentation of this file.
00001 // Internal policy header for unordered_set and unordered_map -*- C++ -*-
00002 
00003 // Copyright (C) 2010 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file bits/hashtable_policy.h
00026  *  This is an internal header file, included by other library headers.
00027  *  You should not attempt to use it directly.
00028  */
00029 
00030 #ifndef _HASHTABLE_POLICY_H
00031 #define _HASHTABLE_POLICY_H 1
00032 
00033 namespace std
00034 {
00035 namespace __detail
00036 {
00037   // Helper function: return distance(first, last) for forward
00038   // iterators, or 0 for input iterators.
00039   template<class _Iterator>
00040     inline typename std::iterator_traits<_Iterator>::difference_type
00041     __distance_fw(_Iterator __first, _Iterator __last,
00042           std::input_iterator_tag)
00043     { return 0; }
00044 
00045   template<class _Iterator>
00046     inline typename std::iterator_traits<_Iterator>::difference_type
00047     __distance_fw(_Iterator __first, _Iterator __last,
00048           std::forward_iterator_tag)
00049     { return std::distance(__first, __last); }
00050 
00051   template<class _Iterator>
00052     inline typename std::iterator_traits<_Iterator>::difference_type
00053     __distance_fw(_Iterator __first, _Iterator __last)
00054     {
00055       typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag;
00056       return __distance_fw(__first, __last, _Tag());
00057     }
00058 
00059   // Auxiliary types used for all instantiations of _Hashtable: nodes
00060   // and iterators.
00061   
00062   // Nodes, used to wrap elements stored in the hash table.  A policy
00063   // template parameter of class template _Hashtable controls whether
00064   // nodes also store a hash code. In some cases (e.g. strings) this
00065   // may be a performance win.
00066   template<typename _Value, bool __cache_hash_code>
00067     struct _Hash_node;
00068 
00069   template<typename _Value>
00070     struct _Hash_node<_Value, true>
00071     {
00072       _Value       _M_v;
00073       std::size_t  _M_hash_code;
00074       _Hash_node*  _M_next;
00075 
00076       template<typename... _Args>
00077         _Hash_node(_Args&&... __args)
00078     : _M_v(std::forward<_Args>(__args)...),
00079       _M_hash_code(), _M_next() { }
00080     };
00081 
00082   template<typename _Value>
00083     struct _Hash_node<_Value, false>
00084     {
00085       _Value       _M_v;
00086       _Hash_node*  _M_next;
00087 
00088       template<typename... _Args>
00089         _Hash_node(_Args&&... __args)
00090     : _M_v(std::forward<_Args>(__args)...),
00091       _M_next() { }
00092     };
00093 
00094   // Local iterators, used to iterate within a bucket but not between
00095   // buckets.
00096   template<typename _Value, bool __cache>
00097     struct _Node_iterator_base
00098     {
00099       _Node_iterator_base(_Hash_node<_Value, __cache>* __p)
00100       : _M_cur(__p) { }
00101       
00102       void
00103       _M_incr()
00104       { _M_cur = _M_cur->_M_next; }
00105 
00106       _Hash_node<_Value, __cache>*  _M_cur;
00107     };
00108 
00109   template<typename _Value, bool __cache>
00110     inline bool
00111     operator==(const _Node_iterator_base<_Value, __cache>& __x,
00112            const _Node_iterator_base<_Value, __cache>& __y)
00113     { return __x._M_cur == __y._M_cur; }
00114 
00115   template<typename _Value, bool __cache>
00116     inline bool
00117     operator!=(const _Node_iterator_base<_Value, __cache>& __x,
00118            const _Node_iterator_base<_Value, __cache>& __y)
00119     { return __x._M_cur != __y._M_cur; }
00120 
00121   template<typename _Value, bool __constant_iterators, bool __cache>
00122     struct _Node_iterator
00123     : public _Node_iterator_base<_Value, __cache>
00124     {
00125       typedef _Value                                   value_type;
00126       typedef typename std::conditional<__constant_iterators,
00127                     const _Value*, _Value*>::type
00128                                                        pointer;
00129       typedef typename std::conditional<__constant_iterators,
00130                     const _Value&, _Value&>::type
00131                                                        reference;
00132       typedef std::ptrdiff_t                           difference_type;
00133       typedef std::forward_iterator_tag                iterator_category;
00134 
00135       _Node_iterator()
00136       : _Node_iterator_base<_Value, __cache>(0) { }
00137 
00138       explicit
00139       _Node_iterator(_Hash_node<_Value, __cache>* __p)
00140       : _Node_iterator_base<_Value, __cache>(__p) { }
00141 
00142       reference
00143       operator*() const
00144       { return this->_M_cur->_M_v; }
00145   
00146       pointer
00147       operator->() const
00148       { return &this->_M_cur->_M_v; }
00149 
00150       _Node_iterator&
00151       operator++()
00152       { 
00153     this->_M_incr();
00154     return *this; 
00155       }
00156   
00157       _Node_iterator
00158       operator++(int)
00159       { 
00160     _Node_iterator __tmp(*this);
00161     this->_M_incr();
00162     return __tmp;
00163       }
00164     };
00165 
00166   template<typename _Value, bool __constant_iterators, bool __cache>
00167     struct _Node_const_iterator
00168     : public _Node_iterator_base<_Value, __cache>
00169     {
00170       typedef _Value                                   value_type;
00171       typedef const _Value*                            pointer;
00172       typedef const _Value&                            reference;
00173       typedef std::ptrdiff_t                           difference_type;
00174       typedef std::forward_iterator_tag                iterator_category;
00175 
00176       _Node_const_iterator()
00177       : _Node_iterator_base<_Value, __cache>(0) { }
00178 
00179       explicit
00180       _Node_const_iterator(_Hash_node<_Value, __cache>* __p)
00181       : _Node_iterator_base<_Value, __cache>(__p) { }
00182 
00183       _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators,
00184                __cache>& __x)
00185       : _Node_iterator_base<_Value, __cache>(__x._M_cur) { }
00186 
00187       reference
00188       operator*() const
00189       { return this->_M_cur->_M_v; }
00190   
00191       pointer
00192       operator->() const
00193       { return &this->_M_cur->_M_v; }
00194 
00195       _Node_const_iterator&
00196       operator++()
00197       { 
00198     this->_M_incr();
00199     return *this; 
00200       }
00201   
00202       _Node_const_iterator
00203       operator++(int)
00204       { 
00205     _Node_const_iterator __tmp(*this);
00206     this->_M_incr();
00207     return __tmp;
00208       }
00209     };
00210 
00211   template<typename _Value, bool __cache>
00212     struct _Hashtable_iterator_base
00213     {
00214       _Hashtable_iterator_base(_Hash_node<_Value, __cache>* __node,
00215                    _Hash_node<_Value, __cache>** __bucket)
00216       : _M_cur_node(__node), _M_cur_bucket(__bucket) { }
00217 
00218       void
00219       _M_incr()
00220       {
00221     _M_cur_node = _M_cur_node->_M_next;
00222     if (!_M_cur_node)
00223       _M_incr_bucket();
00224       }
00225 
00226       void
00227       _M_incr_bucket();
00228 
00229       _Hash_node<_Value, __cache>*   _M_cur_node;
00230       _Hash_node<_Value, __cache>**  _M_cur_bucket;
00231     };
00232 
00233   // Global iterators, used for arbitrary iteration within a hash
00234   // table.  Larger and more expensive than local iterators.
00235   template<typename _Value, bool __cache>
00236     void
00237     _Hashtable_iterator_base<_Value, __cache>::
00238     _M_incr_bucket()
00239     {
00240       ++_M_cur_bucket;
00241 
00242       // This loop requires the bucket array to have a non-null sentinel.
00243       while (!*_M_cur_bucket)
00244     ++_M_cur_bucket;
00245       _M_cur_node = *_M_cur_bucket;
00246     }
00247 
00248   template<typename _Value, bool __cache>
00249     inline bool
00250     operator==(const _Hashtable_iterator_base<_Value, __cache>& __x,
00251            const _Hashtable_iterator_base<_Value, __cache>& __y)
00252     { return __x._M_cur_node == __y._M_cur_node; }
00253 
00254   template<typename _Value, bool __cache>
00255     inline bool
00256     operator!=(const _Hashtable_iterator_base<_Value, __cache>& __x,
00257            const _Hashtable_iterator_base<_Value, __cache>& __y)
00258     { return __x._M_cur_node != __y._M_cur_node; }
00259 
00260   template<typename _Value, bool __constant_iterators, bool __cache>
00261     struct _Hashtable_iterator
00262     : public _Hashtable_iterator_base<_Value, __cache>
00263     {
00264       typedef _Value                                   value_type;
00265       typedef typename std::conditional<__constant_iterators,
00266                     const _Value*, _Value*>::type
00267                                                        pointer;
00268       typedef typename std::conditional<__constant_iterators,
00269                     const _Value&, _Value&>::type
00270                                                        reference;
00271       typedef std::ptrdiff_t                           difference_type;
00272       typedef std::forward_iterator_tag                iterator_category;
00273 
00274       _Hashtable_iterator()
00275       : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
00276 
00277       _Hashtable_iterator(_Hash_node<_Value, __cache>* __p,
00278               _Hash_node<_Value, __cache>** __b)
00279       : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
00280 
00281       explicit
00282       _Hashtable_iterator(_Hash_node<_Value, __cache>** __b)
00283       : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
00284 
00285       reference
00286       operator*() const
00287       { return this->_M_cur_node->_M_v; }
00288   
00289       pointer
00290       operator->() const
00291       { return &this->_M_cur_node->_M_v; }
00292 
00293       _Hashtable_iterator&
00294       operator++()
00295       { 
00296     this->_M_incr();
00297     return *this;
00298       }
00299   
00300       _Hashtable_iterator
00301       operator++(int)
00302       { 
00303     _Hashtable_iterator __tmp(*this);
00304     this->_M_incr();
00305     return __tmp;
00306       }
00307     };
00308 
00309   template<typename _Value, bool __constant_iterators, bool __cache>
00310     struct _Hashtable_const_iterator
00311     : public _Hashtable_iterator_base<_Value, __cache>
00312     {
00313       typedef _Value                                   value_type;
00314       typedef const _Value*                            pointer;
00315       typedef const _Value&                            reference;
00316       typedef std::ptrdiff_t                           difference_type;
00317       typedef std::forward_iterator_tag                iterator_category;
00318 
00319       _Hashtable_const_iterator()
00320       : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
00321 
00322       _Hashtable_const_iterator(_Hash_node<_Value, __cache>* __p,
00323                 _Hash_node<_Value, __cache>** __b)
00324       : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
00325 
00326       explicit
00327       _Hashtable_const_iterator(_Hash_node<_Value, __cache>** __b)
00328       : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
00329 
00330       _Hashtable_const_iterator(const _Hashtable_iterator<_Value,
00331                 __constant_iterators, __cache>& __x)
00332       : _Hashtable_iterator_base<_Value, __cache>(__x._M_cur_node,
00333                           __x._M_cur_bucket) { }
00334 
00335       reference
00336       operator*() const
00337       { return this->_M_cur_node->_M_v; }
00338   
00339       pointer
00340       operator->() const
00341       { return &this->_M_cur_node->_M_v; }
00342 
00343       _Hashtable_const_iterator&
00344       operator++()
00345       { 
00346     this->_M_incr();
00347     return *this;
00348       }
00349   
00350       _Hashtable_const_iterator
00351       operator++(int)
00352       { 
00353     _Hashtable_const_iterator __tmp(*this);
00354     this->_M_incr();
00355     return __tmp;
00356       }
00357     };
00358 
00359 
00360   // Many of class template _Hashtable's template parameters are policy
00361   // classes.  These are defaults for the policies.
00362 
00363   // Default range hashing function: use division to fold a large number
00364   // into the range [0, N).
00365   struct _Mod_range_hashing
00366   {
00367     typedef std::size_t first_argument_type;
00368     typedef std::size_t second_argument_type;
00369     typedef std::size_t result_type;
00370 
00371     result_type
00372     operator()(first_argument_type __num, second_argument_type __den) const
00373     { return __num % __den; }
00374   };
00375 
00376   // Default ranged hash function H.  In principle it should be a
00377   // function object composed from objects of type H1 and H2 such that
00378   // h(k, N) = h2(h1(k), N), but that would mean making extra copies of
00379   // h1 and h2.  So instead we'll just use a tag to tell class template
00380   // hashtable to do that composition.
00381   struct _Default_ranged_hash { };
00382 
00383   // Default value for rehash policy.  Bucket size is (usually) the
00384   // smallest prime that keeps the load factor small enough.
00385   struct _Prime_rehash_policy
00386   {
00387     _Prime_rehash_policy(float __z = 1.0)
00388     : _M_max_load_factor(__z), _M_growth_factor(2.f), _M_next_resize(0) { }
00389 
00390     float
00391     max_load_factor() const
00392     { return _M_max_load_factor; }      
00393 
00394     // Return a bucket size no smaller than n.
00395     std::size_t
00396     _M_next_bkt(std::size_t __n) const;
00397     
00398     // Return a bucket count appropriate for n elements
00399     std::size_t
00400     _M_bkt_for_elements(std::size_t __n) const;
00401     
00402     // __n_bkt is current bucket count, __n_elt is current element count,
00403     // and __n_ins is number of elements to be inserted.  Do we need to
00404     // increase bucket count?  If so, return make_pair(true, n), where n
00405     // is the new bucket count.  If not, return make_pair(false, 0).
00406     std::pair<bool, std::size_t>
00407     _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
00408            std::size_t __n_ins) const;
00409 
00410     enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 };
00411 
00412     float                _M_max_load_factor;
00413     float                _M_growth_factor;
00414     mutable std::size_t  _M_next_resize;
00415   };
00416 
00417   extern const unsigned long __prime_list[];
00418 
00419   // XXX This is a hack.  There's no good reason for any of
00420   // _Prime_rehash_policy's member functions to be inline.  
00421 
00422   // Return a prime no smaller than n.
00423   inline std::size_t
00424   _Prime_rehash_policy::
00425   _M_next_bkt(std::size_t __n) const
00426   {
00427     const unsigned long* __p = std::lower_bound(__prime_list, __prime_list
00428                         + _S_n_primes, __n);
00429     _M_next_resize = 
00430       static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
00431     return *__p;
00432   }
00433 
00434   // Return the smallest prime p such that alpha p >= n, where alpha
00435   // is the load factor.
00436   inline std::size_t
00437   _Prime_rehash_policy::
00438   _M_bkt_for_elements(std::size_t __n) const
00439   {
00440     const float __min_bkts = __n / _M_max_load_factor;
00441     const unsigned long* __p = std::lower_bound(__prime_list, __prime_list
00442                         + _S_n_primes, __min_bkts);
00443     _M_next_resize =
00444       static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
00445     return *__p;
00446   }
00447 
00448   // Finds the smallest prime p such that alpha p > __n_elt + __n_ins.
00449   // If p > __n_bkt, return make_pair(true, p); otherwise return
00450   // make_pair(false, 0).  In principle this isn't very different from 
00451   // _M_bkt_for_elements.
00452 
00453   // The only tricky part is that we're caching the element count at
00454   // which we need to rehash, so we don't have to do a floating-point
00455   // multiply for every insertion.
00456 
00457   inline std::pair<bool, std::size_t>
00458   _Prime_rehash_policy::
00459   _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
00460          std::size_t __n_ins) const
00461   {
00462     if (__n_elt + __n_ins > _M_next_resize)
00463       {
00464     float __min_bkts = ((float(__n_ins) + float(__n_elt))
00465                 / _M_max_load_factor);
00466     if (__min_bkts > __n_bkt)
00467       {
00468         __min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt);
00469         const unsigned long* __p =
00470           std::lower_bound(__prime_list, __prime_list + _S_n_primes,
00471                    __min_bkts);
00472         _M_next_resize = static_cast<std::size_t>
00473           (__builtin_ceil(*__p * _M_max_load_factor));
00474         return std::make_pair(true, *__p);
00475       }
00476     else 
00477       {
00478         _M_next_resize = static_cast<std::size_t>
00479           (__builtin_ceil(__n_bkt * _M_max_load_factor));
00480         return std::make_pair(false, 0);
00481       }
00482       }
00483     else
00484       return std::make_pair(false, 0);
00485   }
00486 
00487   // Base classes for std::_Hashtable.  We define these base classes
00488   // because in some cases we want to do different things depending
00489   // on the value of a policy class.  In some cases the policy class
00490   // affects which member functions and nested typedefs are defined;
00491   // we handle that by specializing base class templates.  Several of
00492   // the base class templates need to access other members of class
00493   // template _Hashtable, so we use the "curiously recurring template
00494   // pattern" for them.
00495 
00496   // class template _Map_base.  If the hashtable has a value type of
00497   // the form pair<T1, T2> and a key extraction policy that returns the
00498   // first part of the pair, the hashtable gets a mapped_type typedef.
00499   // If it satisfies those criteria and also has unique keys, then it
00500   // also gets an operator[].  
00501   template<typename _Key, typename _Value, typename _Ex, bool __unique,
00502        typename _Hashtable>
00503     struct _Map_base { };
00504 
00505   template<typename _Key, typename _Pair, typename _Hashtable>
00506     struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, false, _Hashtable>
00507     {
00508       typedef typename _Pair::second_type mapped_type;
00509     };
00510 
00511   template<typename _Key, typename _Pair, typename _Hashtable>
00512     struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>
00513     {
00514       typedef typename _Pair::second_type mapped_type;
00515 
00516       mapped_type&
00517       operator[](const _Key& __k);
00518 
00519       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00520       // DR 761. unordered_map needs an at() member function.
00521       mapped_type&
00522       at(const _Key& __k);
00523 
00524       const mapped_type&
00525       at(const _Key& __k) const;
00526     };
00527 
00528   template<typename _Key, typename _Pair, typename _Hashtable>
00529     typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
00530                true, _Hashtable>::mapped_type&
00531     _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
00532     operator[](const _Key& __k)
00533     {
00534       _Hashtable* __h = static_cast<_Hashtable*>(this);
00535       typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
00536       std::size_t __n = __h->_M_bucket_index(__k, __code,
00537                          __h->_M_bucket_count);
00538 
00539       typename _Hashtable::_Node* __p =
00540     __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
00541       if (!__p)
00542     return __h->_M_insert_bucket(std::make_pair(__k, mapped_type()),
00543                      __n, __code)->second;
00544       return (__p->_M_v).second;
00545     }
00546 
00547   template<typename _Key, typename _Pair, typename _Hashtable>
00548     typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
00549                true, _Hashtable>::mapped_type&
00550     _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
00551     at(const _Key& __k)
00552     {
00553       _Hashtable* __h = static_cast<_Hashtable*>(this);
00554       typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
00555       std::size_t __n = __h->_M_bucket_index(__k, __code,
00556                          __h->_M_bucket_count);
00557 
00558       typename _Hashtable::_Node* __p =
00559     __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
00560       if (!__p)
00561     __throw_out_of_range(__N("_Map_base::at"));
00562       return (__p->_M_v).second;
00563     }
00564 
00565   template<typename _Key, typename _Pair, typename _Hashtable>
00566     const typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
00567                  true, _Hashtable>::mapped_type&
00568     _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
00569     at(const _Key& __k) const
00570     {
00571       const _Hashtable* __h = static_cast<const _Hashtable*>(this);
00572       typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
00573       std::size_t __n = __h->_M_bucket_index(__k, __code,
00574                          __h->_M_bucket_count);
00575 
00576       typename _Hashtable::_Node* __p =
00577     __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
00578       if (!__p)
00579     __throw_out_of_range(__N("_Map_base::at"));
00580       return (__p->_M_v).second;
00581     }
00582 
00583   // class template _Rehash_base.  Give hashtable the max_load_factor
00584   // functions and reserve iff the rehash policy is _Prime_rehash_policy.
00585   template<typename _RehashPolicy, typename _Hashtable>
00586     struct _Rehash_base { };
00587 
00588   template<typename _Hashtable>
00589     struct _Rehash_base<_Prime_rehash_policy, _Hashtable>
00590     {
00591       float
00592       max_load_factor() const
00593       {
00594     const _Hashtable* __this = static_cast<const _Hashtable*>(this);
00595     return __this->__rehash_policy().max_load_factor();
00596       }
00597 
00598       void
00599       max_load_factor(float __z)
00600       {
00601     _Hashtable* __this = static_cast<_Hashtable*>(this);
00602     __this->__rehash_policy(_Prime_rehash_policy(__z));
00603       }
00604 
00605       void
00606       reserve(std::size_t __n)
00607       {
00608     _Hashtable* __this = static_cast<_Hashtable*>(this);
00609     __this->rehash(__builtin_ceil(__n / max_load_factor()));
00610       }
00611     };
00612 
00613   // Class template _Hash_code_base.  Encapsulates two policy issues that
00614   // aren't quite orthogonal.
00615   //   (1) the difference between using a ranged hash function and using
00616   //       the combination of a hash function and a range-hashing function.
00617   //       In the former case we don't have such things as hash codes, so
00618   //       we have a dummy type as placeholder.
00619   //   (2) Whether or not we cache hash codes.  Caching hash codes is
00620   //       meaningless if we have a ranged hash function.
00621   // We also put the key extraction and equality comparison function 
00622   // objects here, for convenience.
00623   
00624   // Primary template: unused except as a hook for specializations.  
00625   template<typename _Key, typename _Value,
00626        typename _ExtractKey, typename _Equal,
00627        typename _H1, typename _H2, typename _Hash,
00628        bool __cache_hash_code>
00629     struct _Hash_code_base;
00630 
00631   // Specialization: ranged hash function, no caching hash codes.  H1
00632   // and H2 are provided but ignored.  We define a dummy hash code type.
00633   template<typename _Key, typename _Value,
00634        typename _ExtractKey, typename _Equal,
00635        typename _H1, typename _H2, typename _Hash>
00636     struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
00637                _Hash, false>
00638     {
00639     protected:
00640       _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
00641               const _H1&, const _H2&, const _Hash& __h)
00642       : _M_extract(__ex), _M_eq(__eq), _M_ranged_hash(__h) { }
00643 
00644       typedef void* _Hash_code_type;
00645   
00646       _Hash_code_type
00647       _M_hash_code(const _Key& __key) const
00648       { return 0; }
00649   
00650       std::size_t
00651       _M_bucket_index(const _Key& __k, _Hash_code_type,
00652               std::size_t __n) const
00653       { return _M_ranged_hash(__k, __n); }
00654 
00655       std::size_t
00656       _M_bucket_index(const _Hash_node<_Value, false>* __p,
00657               std::size_t __n) const
00658       { return _M_ranged_hash(_M_extract(__p->_M_v), __n); }
00659   
00660       bool
00661       _M_compare(const _Key& __k, _Hash_code_type,
00662          _Hash_node<_Value, false>* __n) const
00663       { return _M_eq(__k, _M_extract(__n->_M_v)); }
00664 
00665       void
00666       _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
00667       { }
00668 
00669       void
00670       _M_copy_code(_Hash_node<_Value, false>*,
00671            const _Hash_node<_Value, false>*) const
00672       { }
00673       
00674       void
00675       _M_swap(_Hash_code_base& __x)
00676       {
00677     std::swap(_M_extract, __x._M_extract);
00678     std::swap(_M_eq, __x._M_eq);
00679     std::swap(_M_ranged_hash, __x._M_ranged_hash);
00680       }
00681 
00682     protected:
00683       _ExtractKey  _M_extract;
00684       _Equal       _M_eq;
00685       _Hash        _M_ranged_hash;
00686     };
00687 
00688 
00689   // No specialization for ranged hash function while caching hash codes.
00690   // That combination is meaningless, and trying to do it is an error.
00691   
00692   
00693   // Specialization: ranged hash function, cache hash codes.  This
00694   // combination is meaningless, so we provide only a declaration
00695   // and no definition.  
00696   template<typename _Key, typename _Value,
00697        typename _ExtractKey, typename _Equal,
00698        typename _H1, typename _H2, typename _Hash>
00699     struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
00700                _Hash, true>;
00701 
00702   // Specialization: hash function and range-hashing function, no
00703   // caching of hash codes.  H is provided but ignored.  Provides
00704   // typedef and accessor required by TR1.  
00705   template<typename _Key, typename _Value,
00706        typename _ExtractKey, typename _Equal,
00707        typename _H1, typename _H2>
00708     struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
00709                _Default_ranged_hash, false>
00710     {
00711       typedef _H1 hasher;
00712 
00713       hasher
00714       hash_function() const
00715       { return _M_h1; }
00716 
00717     protected:
00718       _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
00719               const _H1& __h1, const _H2& __h2,
00720               const _Default_ranged_hash&)
00721       : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
00722 
00723       typedef std::size_t _Hash_code_type;
00724 
00725       _Hash_code_type
00726       _M_hash_code(const _Key& __k) const
00727       { return _M_h1(__k); }
00728       
00729       std::size_t
00730       _M_bucket_index(const _Key&, _Hash_code_type __c,
00731               std::size_t __n) const
00732       { return _M_h2(__c, __n); }
00733 
00734       std::size_t
00735       _M_bucket_index(const _Hash_node<_Value, false>* __p,
00736               std::size_t __n) const
00737       { return _M_h2(_M_h1(_M_extract(__p->_M_v)), __n); }
00738 
00739       bool
00740       _M_compare(const _Key& __k, _Hash_code_type,
00741          _Hash_node<_Value, false>* __n) const
00742       { return _M_eq(__k, _M_extract(__n->_M_v)); }
00743 
00744       void
00745       _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
00746       { }
00747 
00748       void
00749       _M_copy_code(_Hash_node<_Value, false>*,
00750            const _Hash_node<_Value, false>*) const
00751       { }
00752 
00753       void
00754       _M_swap(_Hash_code_base& __x)
00755       {
00756     std::swap(_M_extract, __x._M_extract);
00757     std::swap(_M_eq, __x._M_eq);
00758     std::swap(_M_h1, __x._M_h1);
00759     std::swap(_M_h2, __x._M_h2);
00760       }
00761 
00762     protected:
00763       _ExtractKey  _M_extract;
00764       _Equal       _M_eq;
00765       _H1          _M_h1;
00766       _H2          _M_h2;
00767     };
00768 
00769   // Specialization: hash function and range-hashing function, 
00770   // caching hash codes.  H is provided but ignored.  Provides
00771   // typedef and accessor required by TR1.
00772   template<typename _Key, typename _Value,
00773        typename _ExtractKey, typename _Equal,
00774        typename _H1, typename _H2>
00775     struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
00776                _Default_ranged_hash, true>
00777     {
00778       typedef _H1 hasher;
00779       
00780       hasher
00781       hash_function() const
00782       { return _M_h1; }
00783 
00784     protected:
00785       _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
00786               const _H1& __h1, const _H2& __h2,
00787               const _Default_ranged_hash&)
00788       : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
00789 
00790       typedef std::size_t _Hash_code_type;
00791   
00792       _Hash_code_type
00793       _M_hash_code(const _Key& __k) const
00794       { return _M_h1(__k); }
00795   
00796       std::size_t
00797       _M_bucket_index(const _Key&, _Hash_code_type __c,
00798               std::size_t __n) const
00799       { return _M_h2(__c, __n); }
00800 
00801       std::size_t
00802       _M_bucket_index(const _Hash_node<_Value, true>* __p,
00803               std::size_t __n) const
00804       { return _M_h2(__p->_M_hash_code, __n); }
00805 
00806       bool
00807       _M_compare(const _Key& __k, _Hash_code_type __c,
00808          _Hash_node<_Value, true>* __n) const
00809       { return __c == __n->_M_hash_code && _M_eq(__k, _M_extract(__n->_M_v)); }
00810 
00811       void
00812       _M_store_code(_Hash_node<_Value, true>* __n, _Hash_code_type __c) const
00813       { __n->_M_hash_code = __c; }
00814 
00815       void
00816       _M_copy_code(_Hash_node<_Value, true>* __to,
00817            const _Hash_node<_Value, true>* __from) const
00818       { __to->_M_hash_code = __from->_M_hash_code; }
00819 
00820       void
00821       _M_swap(_Hash_code_base& __x)
00822       {
00823     std::swap(_M_extract, __x._M_extract);
00824     std::swap(_M_eq, __x._M_eq);
00825     std::swap(_M_h1, __x._M_h1);
00826     std::swap(_M_h2, __x._M_h2);
00827       }
00828       
00829     protected:
00830       _ExtractKey  _M_extract;
00831       _Equal       _M_eq;
00832       _H1          _M_h1;
00833       _H2          _M_h2;
00834     };
00835 
00836 
00837   // Class template _Equality_base.  This is for implementing equality
00838   // comparison for unordered containers, per N3068, by John Lakos and
00839   // Pablo Halpern.  Algorithmically, we follow closely the reference
00840   // implementations therein.
00841   template<typename _ExtractKey, bool __unique_keys,
00842        typename _Hashtable>
00843     struct _Equality_base;
00844 
00845   template<typename _ExtractKey, typename _Hashtable>
00846     struct _Equality_base<_ExtractKey, true, _Hashtable>
00847     {
00848       bool _M_equal(const _Hashtable&) const;
00849     };
00850 
00851   template<typename _ExtractKey, typename _Hashtable>
00852     bool
00853     _Equality_base<_ExtractKey, true, _Hashtable>::
00854     _M_equal(const _Hashtable& __other) const
00855     {
00856       const _Hashtable* __this = static_cast<const _Hashtable*>(this);
00857 
00858       if (__this->size() != __other.size())
00859     return false;
00860 
00861       for (auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
00862     {
00863       const auto __ity = __other.find(_ExtractKey()(*__itx));
00864       if (__ity == __other.end() || *__ity != *__itx)
00865         return false;
00866     }
00867       return true;
00868     }
00869 
00870   template<typename _ExtractKey, typename _Hashtable>
00871     struct _Equality_base<_ExtractKey, false, _Hashtable>
00872     {
00873       bool _M_equal(const _Hashtable&) const;
00874 
00875     private:
00876       template<typename _Uiterator>
00877         static bool
00878         _S_is_permutation(_Uiterator, _Uiterator, _Uiterator);
00879     };
00880 
00881   // See std::is_permutation in N3068.
00882   template<typename _ExtractKey, typename _Hashtable>
00883     template<typename _Uiterator>
00884       bool
00885       _Equality_base<_ExtractKey, false, _Hashtable>::
00886       _S_is_permutation(_Uiterator __first1, _Uiterator __last1,
00887             _Uiterator __first2)
00888       {
00889     for (; __first1 != __last1; ++__first1, ++__first2)
00890       if (!(*__first1 == *__first2))
00891         break;
00892 
00893     if (__first1 == __last1)
00894       return true;
00895 
00896     _Uiterator __last2 = __first2;
00897     std::advance(__last2, std::distance(__first1, __last1));
00898 
00899     for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1)
00900       {
00901         _Uiterator __tmp =  __first1;
00902         while (__tmp != __it1 && !(*__tmp == *__it1))
00903           ++__tmp;
00904 
00905         // We've seen this one before.
00906         if (__tmp != __it1)
00907           continue;
00908 
00909         std::ptrdiff_t __n2 = 0;
00910         for (__tmp = __first2; __tmp != __last2; ++__tmp)
00911           if (*__tmp == *__it1)
00912         ++__n2;
00913 
00914         if (!__n2)
00915           return false;
00916 
00917         std::ptrdiff_t __n1 = 0;
00918         for (__tmp = __it1; __tmp != __last1; ++__tmp)
00919           if (*__tmp == *__it1)
00920         ++__n1;
00921 
00922         if (__n1 != __n2)
00923           return false;
00924       }
00925     return true;
00926       }
00927 
00928   template<typename _ExtractKey, typename _Hashtable>
00929     bool
00930     _Equality_base<_ExtractKey, false, _Hashtable>::
00931     _M_equal(const _Hashtable& __other) const
00932     {
00933       const _Hashtable* __this = static_cast<const _Hashtable*>(this);
00934 
00935       if (__this->size() != __other.size())
00936     return false;
00937 
00938       for (auto __itx = __this->begin(); __itx != __this->end();)
00939     {
00940       const auto __xrange = __this->equal_range(_ExtractKey()(*__itx));
00941       const auto __yrange = __other.equal_range(_ExtractKey()(*__itx));
00942 
00943       if (std::distance(__xrange.first, __xrange.second)
00944           != std::distance(__yrange.first, __yrange.second))
00945         return false;
00946 
00947       if (!_S_is_permutation(__xrange.first,
00948                  __xrange.second,
00949                  __yrange.first))
00950         return false;
00951 
00952       __itx = __xrange.second;
00953     }
00954       return true;
00955     }
00956 } // namespace __detail
00957 }
00958 
00959 #endif // _HASHTABLE_POLICY_H