1// Internal policy header for TR1 unordered_set and unordered_map -*- C++ -*-
2
3// Copyright (C) 2005, 2006 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 2, 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// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING.  If not, write to the Free
18// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19// USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction.  Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License.  This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30/** @file tr1/hashtable_policy.h
31 *  This is a TR1 C++ Library header.
32 */
33
34#ifndef _TR1_HASHTABLE_POLICY_H
35#define _TR1_HASHTABLE_POLICY_H 1
36
37#include <functional> // _Identity, _Select1st
38#include <tr1/utility>
39#include <ext/type_traits.h>
40
41namespace std
42{
43_GLIBCXX_BEGIN_NAMESPACE(tr1)
44namespace __detail
45{
46  // Helper function: return distance(first, last) for forward
47  // iterators, or 0 for input iterators.
48  template<class _Iterator>
49    inline typename std::iterator_traits<_Iterator>::difference_type
50    __distance_fw(_Iterator __first, _Iterator __last,
51		  std::input_iterator_tag)
52    { return 0; }
53
54  template<class _Iterator>
55    inline typename std::iterator_traits<_Iterator>::difference_type
56    __distance_fw(_Iterator __first, _Iterator __last,
57		  std::forward_iterator_tag)
58    { return std::distance(__first, __last); }
59
60  template<class _Iterator>
61    inline typename std::iterator_traits<_Iterator>::difference_type
62    __distance_fw(_Iterator __first, _Iterator __last)
63    {
64      typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag;
65      return __distance_fw(__first, __last, _Tag());
66    }
67
68  // XXX This is a hack.  _Prime_rehash_policy's member functions, and
69  // certainly the list of primes, should be defined in a .cc file.
70  // We're temporarily putting them in a header because we don't have a
71  // place to put TR1 .cc files yet.  There's no good reason for any of
72  // _Prime_rehash_policy's member functions to be inline, and there's
73  // certainly no good reason for _Primes<> to exist at all.
74  struct _LessThan
75  {
76    template<typename _Tp, typename _Up>
77      bool
78      operator()(_Tp __x, _Up __y)
79      { return __x < __y; }
80  };
81
82  template<int __ulongsize = sizeof(unsigned long)>
83    struct _Primes
84    {
85      static const int __n_primes = __ulongsize != 8 ? 256 : 256 + 48;
86      static const unsigned long __primes[256 + 48 + 1];
87    };
88
89  template<int __ulongsize>
90    const int _Primes<__ulongsize>::__n_primes;
91
92  template<int __ulongsize>
93    const unsigned long _Primes<__ulongsize>::__primes[256 + 48 + 1] =
94    {
95      2ul, 3ul, 5ul, 7ul, 11ul, 13ul, 17ul, 19ul, 23ul, 29ul, 31ul,
96      37ul, 41ul, 43ul, 47ul, 53ul, 59ul, 61ul, 67ul, 71ul, 73ul, 79ul,
97      83ul, 89ul, 97ul, 103ul, 109ul, 113ul, 127ul, 137ul, 139ul, 149ul,
98      157ul, 167ul, 179ul, 193ul, 199ul, 211ul, 227ul, 241ul, 257ul,
99      277ul, 293ul, 313ul, 337ul, 359ul, 383ul, 409ul, 439ul, 467ul,
100      503ul, 541ul, 577ul, 619ul, 661ul, 709ul, 761ul, 823ul, 887ul,
101      953ul, 1031ul, 1109ul, 1193ul, 1289ul, 1381ul, 1493ul, 1613ul,
102      1741ul, 1879ul, 2029ul, 2179ul, 2357ul, 2549ul, 2753ul, 2971ul,
103      3209ul, 3469ul, 3739ul, 4027ul, 4349ul, 4703ul, 5087ul, 5503ul,
104      5953ul, 6427ul, 6949ul, 7517ul, 8123ul, 8783ul, 9497ul, 10273ul,
105      11113ul, 12011ul, 12983ul, 14033ul, 15173ul, 16411ul, 17749ul,
106      19183ul, 20753ul, 22447ul, 24281ul, 26267ul, 28411ul, 30727ul,
107      33223ul, 35933ul, 38873ul, 42043ul, 45481ul, 49201ul, 53201ul,
108      57557ul, 62233ul, 67307ul, 72817ul, 78779ul, 85229ul, 92203ul,
109      99733ul, 107897ul, 116731ul, 126271ul, 136607ul, 147793ul,
110      159871ul, 172933ul, 187091ul, 202409ul, 218971ul, 236897ul,
111      256279ul, 277261ul, 299951ul, 324503ul, 351061ul, 379787ul,
112      410857ul, 444487ul, 480881ul, 520241ul, 562841ul, 608903ul,
113      658753ul, 712697ul, 771049ul, 834181ul, 902483ul, 976369ul,
114      1056323ul, 1142821ul, 1236397ul, 1337629ul, 1447153ul, 1565659ul,
115      1693859ul, 1832561ul, 1982627ul, 2144977ul, 2320627ul, 2510653ul,
116      2716249ul, 2938679ul, 3179303ul, 3439651ul, 3721303ul, 4026031ul,
117      4355707ul, 4712381ul, 5098259ul, 5515729ul, 5967347ul, 6456007ul,
118      6984629ul, 7556579ul, 8175383ul, 8844859ul, 9569143ul, 10352717ul,
119      11200489ul, 12117689ul, 13109983ul, 14183539ul, 15345007ul,
120      16601593ul, 17961079ul, 19431899ul, 21023161ul, 22744717ul,
121      24607243ul, 26622317ul, 28802401ul, 31160981ul, 33712729ul,
122      36473443ul, 39460231ul, 42691603ul, 46187573ul, 49969847ul,
123      54061849ul, 58488943ul, 63278561ul, 68460391ul, 74066549ul,
124      80131819ul, 86693767ul, 93793069ul, 101473717ul, 109783337ul,
125      118773397ul, 128499677ul, 139022417ul, 150406843ul, 162723577ul,
126      176048909ul, 190465427ul, 206062531ul, 222936881ul, 241193053ul,
127      260944219ul, 282312799ul, 305431229ul, 330442829ul, 357502601ul,
128      386778277ul, 418451333ul, 452718089ul, 489790921ul, 529899637ul,
129      573292817ul, 620239453ul, 671030513ul, 725980837ul, 785430967ul,
130      849749479ul, 919334987ul, 994618837ul, 1076067617ul, 1164186217ul,
131      1259520799ul, 1362662261ul, 1474249943ul, 1594975441ul,
132      1725587117ul, 1866894511ul, 2019773507ul, 2185171673ul,
133      2364114217ul, 2557710269ul, 2767159799ul, 2993761039ul,
134      3238918481ul, 3504151727ul, 3791104843ul, 4101556399ul,
135      4294967291ul,
136      // Sentinel, so we don't have to test the result of lower_bound,
137      // or, on 64-bit machines, rest of the table.
138      __ulongsize != 8 ? 4294967291ul : (unsigned long)6442450933ull,
139      (unsigned long)8589934583ull,
140      (unsigned long)12884901857ull, (unsigned long)17179869143ull,
141      (unsigned long)25769803693ull, (unsigned long)34359738337ull,
142      (unsigned long)51539607367ull, (unsigned long)68719476731ull,
143      (unsigned long)103079215087ull, (unsigned long)137438953447ull,
144      (unsigned long)206158430123ull, (unsigned long)274877906899ull,
145      (unsigned long)412316860387ull, (unsigned long)549755813881ull,
146      (unsigned long)824633720731ull, (unsigned long)1099511627689ull,
147      (unsigned long)1649267441579ull, (unsigned long)2199023255531ull,
148      (unsigned long)3298534883309ull, (unsigned long)4398046511093ull,
149      (unsigned long)6597069766607ull, (unsigned long)8796093022151ull,
150      (unsigned long)13194139533241ull, (unsigned long)17592186044399ull,
151      (unsigned long)26388279066581ull, (unsigned long)35184372088777ull,
152      (unsigned long)52776558133177ull, (unsigned long)70368744177643ull,
153      (unsigned long)105553116266399ull, (unsigned long)140737488355213ull,
154      (unsigned long)211106232532861ull, (unsigned long)281474976710597ull,
155      (unsigned long)562949953421231ull, (unsigned long)1125899906842597ull,
156      (unsigned long)2251799813685119ull, (unsigned long)4503599627370449ull,
157      (unsigned long)9007199254740881ull, (unsigned long)18014398509481951ull,
158      (unsigned long)36028797018963913ull, (unsigned long)72057594037927931ull,
159      (unsigned long)144115188075855859ull,
160      (unsigned long)288230376151711717ull,
161      (unsigned long)576460752303423433ull,
162      (unsigned long)1152921504606846883ull,
163      (unsigned long)2305843009213693951ull,
164      (unsigned long)4611686018427387847ull,
165      (unsigned long)9223372036854775783ull,
166      (unsigned long)18446744073709551557ull,
167      (unsigned long)18446744073709551557ull
168    };
169
170  // Auxiliary types used for all instantiations of _Hashtable: nodes
171  // and iterators.
172
173  // Nodes, used to wrap elements stored in the hash table.  A policy
174  // template parameter of class template _Hashtable controls whether
175  // nodes also store a hash code. In some cases (e.g. strings) this
176  // may be a performance win.
177  template<typename _Value, bool __cache_hash_code>
178    struct _Hash_node;
179
180  template<typename _Value>
181    struct _Hash_node<_Value, true>
182    {
183      _Value       _M_v;
184      std::size_t  _M_hash_code;
185      _Hash_node*  _M_next;
186    };
187
188  template<typename _Value>
189    struct _Hash_node<_Value, false>
190    {
191      _Value       _M_v;
192      _Hash_node*  _M_next;
193    };
194
195  // Local iterators, used to iterate within a bucket but not between
196  // buckets.
197  template<typename _Value, bool __cache>
198    struct _Node_iterator_base
199    {
200      _Node_iterator_base(_Hash_node<_Value, __cache>* __p)
201      : _M_cur(__p) { }
202
203      void
204      _M_incr()
205      { _M_cur = _M_cur->_M_next; }
206
207      _Hash_node<_Value, __cache>*  _M_cur;
208    };
209
210  template<typename _Value, bool __cache>
211    inline bool
212    operator==(const _Node_iterator_base<_Value, __cache>& __x,
213	       const _Node_iterator_base<_Value, __cache>& __y)
214    { return __x._M_cur == __y._M_cur; }
215
216  template<typename _Value, bool __cache>
217    inline bool
218    operator!=(const _Node_iterator_base<_Value, __cache>& __x,
219	       const _Node_iterator_base<_Value, __cache>& __y)
220    { return __x._M_cur != __y._M_cur; }
221
222  template<typename _Value, bool __constant_iterators, bool __cache>
223    struct _Node_iterator
224    : public _Node_iterator_base<_Value, __cache>
225    {
226      typedef _Value                                   value_type;
227      typedef typename
228      __gnu_cxx::__conditional_type<__constant_iterators,
229				    const _Value*, _Value*>::__type
230                                                       pointer;
231      typedef typename
232      __gnu_cxx::__conditional_type<__constant_iterators,
233				    const _Value&, _Value&>::__type
234                                                       reference;
235      typedef std::ptrdiff_t                           difference_type;
236      typedef std::forward_iterator_tag                iterator_category;
237
238      _Node_iterator()
239      : _Node_iterator_base<_Value, __cache>(0) { }
240
241      explicit
242      _Node_iterator(_Hash_node<_Value, __cache>* __p)
243      : _Node_iterator_base<_Value, __cache>(__p) { }
244
245      reference
246      operator*() const
247      { return this->_M_cur->_M_v; }
248
249      pointer
250      operator->() const
251      { return &this->_M_cur->_M_v; }
252
253      _Node_iterator&
254      operator++()
255      {
256	this->_M_incr();
257	return *this;
258      }
259
260      _Node_iterator
261      operator++(int)
262      {
263	_Node_iterator __tmp(*this);
264	this->_M_incr();
265	return __tmp;
266      }
267    };
268
269  template<typename _Value, bool __constant_iterators, bool __cache>
270    struct _Node_const_iterator
271    : public _Node_iterator_base<_Value, __cache>
272    {
273      typedef _Value                                   value_type;
274      typedef const _Value*                            pointer;
275      typedef const _Value&                            reference;
276      typedef std::ptrdiff_t                           difference_type;
277      typedef std::forward_iterator_tag                iterator_category;
278
279      _Node_const_iterator()
280      : _Node_iterator_base<_Value, __cache>(0) { }
281
282      explicit
283      _Node_const_iterator(_Hash_node<_Value, __cache>* __p)
284      : _Node_iterator_base<_Value, __cache>(__p) { }
285
286      _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators,
287			   __cache>& __x)
288      : _Node_iterator_base<_Value, __cache>(__x._M_cur) { }
289
290      reference
291      operator*() const
292      { return this->_M_cur->_M_v; }
293
294      pointer
295      operator->() const
296      { return &this->_M_cur->_M_v; }
297
298      _Node_const_iterator&
299      operator++()
300      {
301	this->_M_incr();
302	return *this;
303      }
304
305      _Node_const_iterator
306      operator++(int)
307      {
308	_Node_const_iterator __tmp(*this);
309	this->_M_incr();
310	return __tmp;
311      }
312    };
313
314  template<typename _Value, bool __cache>
315    struct _Hashtable_iterator_base
316    {
317      _Hashtable_iterator_base(_Hash_node<_Value, __cache>* __node,
318			       _Hash_node<_Value, __cache>** __bucket)
319      : _M_cur_node(__node), _M_cur_bucket(__bucket) { }
320
321      void
322      _M_incr()
323      {
324	_M_cur_node = _M_cur_node->_M_next;
325	if (!_M_cur_node)
326	  _M_incr_bucket();
327      }
328
329      void
330      _M_incr_bucket();
331
332      _Hash_node<_Value, __cache>*   _M_cur_node;
333      _Hash_node<_Value, __cache>**  _M_cur_bucket;
334    };
335
336  // Global iterators, used for arbitrary iteration within a hash
337  // table.  Larger and more expensive than local iterators.
338  template<typename _Value, bool __cache>
339    void
340    _Hashtable_iterator_base<_Value, __cache>::
341    _M_incr_bucket()
342    {
343      ++_M_cur_bucket;
344
345      // This loop requires the bucket array to have a non-null sentinel.
346      while (!*_M_cur_bucket)
347	++_M_cur_bucket;
348      _M_cur_node = *_M_cur_bucket;
349    }
350
351  template<typename _Value, bool __cache>
352    inline bool
353    operator==(const _Hashtable_iterator_base<_Value, __cache>& __x,
354	       const _Hashtable_iterator_base<_Value, __cache>& __y)
355    { return __x._M_cur_node == __y._M_cur_node; }
356
357  template<typename _Value, bool __cache>
358    inline bool
359    operator!=(const _Hashtable_iterator_base<_Value, __cache>& __x,
360	       const _Hashtable_iterator_base<_Value, __cache>& __y)
361    { return __x._M_cur_node != __y._M_cur_node; }
362
363  template<typename _Value, bool __constant_iterators, bool __cache>
364    struct _Hashtable_iterator
365    : public _Hashtable_iterator_base<_Value, __cache>
366    {
367      typedef _Value                                   value_type;
368      typedef typename
369      __gnu_cxx::__conditional_type<__constant_iterators,
370				    const _Value*, _Value*>::__type
371                                                       pointer;
372      typedef typename
373      __gnu_cxx::__conditional_type<__constant_iterators,
374				    const _Value&, _Value&>::__type
375                                                       reference;
376      typedef std::ptrdiff_t                           difference_type;
377      typedef std::forward_iterator_tag                iterator_category;
378
379      _Hashtable_iterator()
380      : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
381
382      _Hashtable_iterator(_Hash_node<_Value, __cache>* __p,
383			  _Hash_node<_Value, __cache>** __b)
384      : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
385
386      explicit
387      _Hashtable_iterator(_Hash_node<_Value, __cache>** __b)
388      : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
389
390      reference
391      operator*() const
392      { return this->_M_cur_node->_M_v; }
393
394      pointer
395      operator->() const
396      { return &this->_M_cur_node->_M_v; }
397
398      _Hashtable_iterator&
399      operator++()
400      {
401	this->_M_incr();
402	return *this;
403      }
404
405      _Hashtable_iterator
406      operator++(int)
407      {
408	_Hashtable_iterator __tmp(*this);
409	this->_M_incr();
410	return __tmp;
411      }
412    };
413
414  template<typename _Value, bool __constant_iterators, bool __cache>
415    struct _Hashtable_const_iterator
416    : public _Hashtable_iterator_base<_Value, __cache>
417    {
418      typedef _Value                                   value_type;
419      typedef const _Value*                            pointer;
420      typedef const _Value&                            reference;
421      typedef std::ptrdiff_t                           difference_type;
422      typedef std::forward_iterator_tag                iterator_category;
423
424      _Hashtable_const_iterator()
425      : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
426
427      _Hashtable_const_iterator(_Hash_node<_Value, __cache>* __p,
428				_Hash_node<_Value, __cache>** __b)
429      : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
430
431      explicit
432      _Hashtable_const_iterator(_Hash_node<_Value, __cache>** __b)
433      : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
434
435      _Hashtable_const_iterator(const _Hashtable_iterator<_Value,
436				__constant_iterators, __cache>& __x)
437      : _Hashtable_iterator_base<_Value, __cache>(__x._M_cur_node,
438						  __x._M_cur_bucket) { }
439
440      reference
441      operator*() const
442      { return this->_M_cur_node->_M_v; }
443
444      pointer
445      operator->() const
446      { return &this->_M_cur_node->_M_v; }
447
448      _Hashtable_const_iterator&
449      operator++()
450      {
451	this->_M_incr();
452	return *this;
453      }
454
455      _Hashtable_const_iterator
456      operator++(int)
457      {
458	_Hashtable_const_iterator __tmp(*this);
459	this->_M_incr();
460	return __tmp;
461      }
462    };
463
464
465  // Many of class template _Hashtable's template parameters are policy
466  // classes.  These are defaults for the policies.
467
468  // Default range hashing function: use division to fold a large number
469  // into the range [0, N).
470  struct _Mod_range_hashing
471  {
472    typedef std::size_t first_argument_type;
473    typedef std::size_t second_argument_type;
474    typedef std::size_t result_type;
475
476    result_type
477    operator()(first_argument_type __num, second_argument_type __den) const
478    { return __num % __den; }
479  };
480
481  // Default ranged hash function H.  In principle it should be a
482  // function object composed from objects of type H1 and H2 such that
483  // h(k, N) = h2(h1(k), N), but that would mean making extra copies of
484  // h1 and h2.  So instead we'll just use a tag to tell class template
485  // hashtable to do that composition.
486  struct _Default_ranged_hash { };
487
488  // Default value for rehash policy.  Bucket size is (usually) the
489  // smallest prime that keeps the load factor small enough.
490  struct _Prime_rehash_policy
491  {
492    _Prime_rehash_policy(float __z = 1.0);
493
494    float
495    max_load_factor() const;
496
497    // Return a bucket size no smaller than n.
498    std::size_t
499    _M_next_bkt(std::size_t __n) const;
500
501    // Return a bucket count appropriate for n elements
502    std::size_t
503    _M_bkt_for_elements(std::size_t __n) const;
504
505    // __n_bkt is current bucket count, __n_elt is current element count,
506    // and __n_ins is number of elements to be inserted.  Do we need to
507    // increase bucket count?  If so, return make_pair(true, n), where n
508    // is the new bucket count.  If not, return make_pair(false, 0).
509    std::pair<bool, std::size_t>
510    _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
511		   std::size_t __n_ins) const;
512
513    float                _M_max_load_factor;
514    float                _M_growth_factor;
515    mutable std::size_t  _M_next_resize;
516  };
517
518  inline
519  _Prime_rehash_policy::
520  _Prime_rehash_policy(float __z)
521  : _M_max_load_factor(__z), _M_growth_factor(2.f), _M_next_resize(0)
522  { }
523
524  inline float
525  _Prime_rehash_policy::
526  max_load_factor() const
527  { return _M_max_load_factor; }
528
529  // Return a prime no smaller than n.
530  inline std::size_t
531  _Prime_rehash_policy::
532  _M_next_bkt(std::size_t __n) const
533  {
534    const unsigned long* const __last = (_Primes<>::__primes
535					 + _Primes<>::__n_primes);
536    const unsigned long* __p = std::lower_bound(_Primes<>::__primes, __last,
537						__n);
538    _M_next_resize = static_cast<std::size_t>(std::ceil(*__p
539							* _M_max_load_factor));
540    return *__p;
541  }
542
543  // Return the smallest prime p such that alpha p >= n, where alpha
544  // is the load factor.
545  inline std::size_t
546  _Prime_rehash_policy::
547  _M_bkt_for_elements(std::size_t __n) const
548  {
549    const unsigned long* const __last = (_Primes<>::__primes
550					 + _Primes<>::__n_primes);
551    const float __min_bkts = __n / _M_max_load_factor;
552    const unsigned long* __p = std::lower_bound(_Primes<>::__primes, __last,
553						__min_bkts, _LessThan());
554    _M_next_resize = static_cast<std::size_t>(std::ceil(*__p
555							* _M_max_load_factor));
556    return *__p;
557  }
558
559  // Finds the smallest prime p such that alpha p > __n_elt + __n_ins.
560  // If p > __n_bkt, return make_pair(true, p); otherwise return
561  // make_pair(false, 0).  In principle this isn't very different from
562  // _M_bkt_for_elements.
563
564  // The only tricky part is that we're caching the element count at
565  // which we need to rehash, so we don't have to do a floating-point
566  // multiply for every insertion.
567
568  inline std::pair<bool, std::size_t>
569  _Prime_rehash_policy::
570  _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
571		 std::size_t __n_ins) const
572  {
573    if (__n_elt + __n_ins > _M_next_resize)
574      {
575	float __min_bkts = ((float(__n_ins) + float(__n_elt))
576			    / _M_max_load_factor);
577	if (__min_bkts > __n_bkt)
578	  {
579	    __min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt);
580	    const unsigned long* const __last = (_Primes<>::__primes
581						 + _Primes<>::__n_primes);
582	    const unsigned long* __p = std::lower_bound(_Primes<>::__primes,
583							__last, __min_bkts,
584							_LessThan());
585	    _M_next_resize =
586	      static_cast<std::size_t>(std::ceil(*__p * _M_max_load_factor));
587	    return std::make_pair(true, *__p);
588	  }
589	else
590	  {
591	    _M_next_resize =
592	      static_cast<std::size_t>(std::ceil(__n_bkt
593						 * _M_max_load_factor));
594	    return std::make_pair(false, 0);
595	  }
596      }
597    else
598      return std::make_pair(false, 0);
599  }
600
601  // Base classes for std::tr1::_Hashtable.  We define these base
602  // classes because in some cases we want to do different things
603  // depending on the value of a policy class.  In some cases the
604  // policy class affects which member functions and nested typedefs
605  // are defined; we handle that by specializing base class templates.
606  // Several of the base class templates need to access other members
607  // of class template _Hashtable, so we use the "curiously recurring
608  // template pattern" for them.
609
610  // class template _Map_base.  If the hashtable has a value type of the
611  // form pair<T1, T2> and a key extraction policy that returns the
612  // first part of the pair, the hashtable gets a mapped_type typedef.
613  // If it satisfies those criteria and also has unique keys, then it
614  // also gets an operator[].
615  template<typename _Key, typename _Value, typename _Ex, bool __unique,
616	   typename _Hashtable>
617    struct _Map_base { };
618
619  template<typename _Key, typename _Pair, typename _Hashtable>
620    struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, false, _Hashtable>
621    {
622      typedef typename _Pair::second_type mapped_type;
623    };
624
625  template<typename _Key, typename _Pair, typename _Hashtable>
626  struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>
627    {
628      typedef typename _Pair::second_type mapped_type;
629
630      mapped_type&
631      operator[](const _Key& __k);
632    };
633
634  template<typename _Key, typename _Pair, typename _Hashtable>
635    typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
636		       true, _Hashtable>::mapped_type&
637    _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
638    operator[](const _Key& __k)
639    {
640      _Hashtable* __h = static_cast<_Hashtable*>(this);
641      typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
642      std::size_t __n = __h->_M_bucket_index(__k, __code,
643					     __h->_M_bucket_count);
644
645      typename _Hashtable::_Node* __p =
646	__h->_M_find_node(__h->_M_buckets[__n], __k, __code);
647      if (!__p)
648	return __h->_M_insert_bucket(std::make_pair(__k, mapped_type()),
649				     __n, __code)->second;
650      return (__p->_M_v).second;
651    }
652
653  // class template _Rehash_base.  Give hashtable the max_load_factor
654  // functions iff the rehash policy is _Prime_rehash_policy.
655  template<typename _RehashPolicy, typename _Hashtable>
656    struct _Rehash_base { };
657
658  template<typename _Hashtable>
659    struct _Rehash_base<_Prime_rehash_policy, _Hashtable>
660    {
661      float
662      max_load_factor() const
663      {
664	const _Hashtable* __this = static_cast<const _Hashtable*>(this);
665	return __this->__rehash_policy().max_load_factor();
666      }
667
668      void
669      max_load_factor(float __z)
670      {
671	_Hashtable* __this = static_cast<_Hashtable*>(this);
672	__this->__rehash_policy(_Prime_rehash_policy(__z));
673      }
674    };
675
676  // Class template _Hash_code_base.  Encapsulates two policy issues that
677  // aren't quite orthogonal.
678  //   (1) the difference between using a ranged hash function and using
679  //       the combination of a hash function and a range-hashing function.
680  //       In the former case we don't have such things as hash codes, so
681  //       we have a dummy type as placeholder.
682  //   (2) Whether or not we cache hash codes.  Caching hash codes is
683  //       meaningless if we have a ranged hash function.
684  // We also put the key extraction and equality comparison function
685  // objects here, for convenience.
686
687  // Primary template: unused except as a hook for specializations.
688  template<typename _Key, typename _Value,
689	   typename _ExtractKey, typename _Equal,
690	   typename _H1, typename _H2, typename _Hash,
691	   bool __cache_hash_code>
692    struct _Hash_code_base;
693
694  // Specialization: ranged hash function, no caching hash codes.  H1
695  // and H2 are provided but ignored.  We define a dummy hash code type.
696  template<typename _Key, typename _Value,
697	   typename _ExtractKey, typename _Equal,
698	   typename _H1, typename _H2, typename _Hash>
699    struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
700			   _Hash, false>
701    {
702    protected:
703      _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
704		      const _H1&, const _H2&, const _Hash& __h)
705      : _M_extract(__ex), _M_eq(__eq), _M_ranged_hash(__h) { }
706
707      typedef void* _Hash_code_type;
708
709      _Hash_code_type
710      _M_hash_code(const _Key& __key) const
711      { return 0; }
712
713      std::size_t
714      _M_bucket_index(const _Key& __k, _Hash_code_type,
715		      std::size_t __n) const
716      { return _M_ranged_hash(__k, __n); }
717
718      std::size_t
719      _M_bucket_index(const _Hash_node<_Value, false>* __p,
720		      std::size_t __n) const
721      { return _M_ranged_hash(_M_extract(__p->_M_v), __n); }
722
723      bool
724      _M_compare(const _Key& __k, _Hash_code_type,
725		 _Hash_node<_Value, false>* __n) const
726      { return _M_eq(__k, _M_extract(__n->_M_v)); }
727
728      void
729      _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
730      { }
731
732      void
733      _M_copy_code(_Hash_node<_Value, false>*,
734		   const _Hash_node<_Value, false>*) const
735      { }
736
737      void
738      _M_swap(_Hash_code_base& __x)
739      {
740	std::swap(_M_extract, __x._M_extract);
741	std::swap(_M_eq, __x._M_eq);
742	std::swap(_M_ranged_hash, __x._M_ranged_hash);
743      }
744
745    protected:
746      _ExtractKey  _M_extract;
747      _Equal       _M_eq;
748      _Hash        _M_ranged_hash;
749    };
750
751
752  // No specialization for ranged hash function while caching hash codes.
753  // That combination is meaningless, and trying to do it is an error.
754
755
756  // Specialization: ranged hash function, cache hash codes.  This
757  // combination is meaningless, so we provide only a declaration
758  // and no definition.
759  template<typename _Key, typename _Value,
760	   typename _ExtractKey, typename _Equal,
761	   typename _H1, typename _H2, typename _Hash>
762    struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
763			   _Hash, true>;
764
765  // Specialization: hash function and range-hashing function, no
766  // caching of hash codes.  H is provided but ignored.  Provides
767  // typedef and accessor required by TR1.
768  template<typename _Key, typename _Value,
769	   typename _ExtractKey, typename _Equal,
770	   typename _H1, typename _H2>
771    struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
772			   _Default_ranged_hash, false>
773    {
774      typedef _H1 hasher;
775
776      hasher
777      hash_function() const
778      { return _M_h1; }
779
780    protected:
781      _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
782		      const _H1& __h1, const _H2& __h2,
783		      const _Default_ranged_hash&)
784      : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
785
786      typedef std::size_t _Hash_code_type;
787
788      _Hash_code_type
789      _M_hash_code(const _Key& __k) const
790      { return _M_h1(__k); }
791
792      std::size_t
793      _M_bucket_index(const _Key&, _Hash_code_type __c,
794		      std::size_t __n) const
795      { return _M_h2(__c, __n); }
796
797      std::size_t
798      _M_bucket_index(const _Hash_node<_Value, false>* __p,
799		      std::size_t __n) const
800      { return _M_h2(_M_h1(_M_extract(__p->_M_v)), __n); }
801
802      bool
803      _M_compare(const _Key& __k, _Hash_code_type,
804		 _Hash_node<_Value, false>* __n) const
805      { return _M_eq(__k, _M_extract(__n->_M_v)); }
806
807      void
808      _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
809      { }
810
811      void
812      _M_copy_code(_Hash_node<_Value, false>*,
813		   const _Hash_node<_Value, false>*) const
814      { }
815
816      void
817      _M_swap(_Hash_code_base& __x)
818      {
819	std::swap(_M_extract, __x._M_extract);
820	std::swap(_M_eq, __x._M_eq);
821	std::swap(_M_h1, __x._M_h1);
822	std::swap(_M_h2, __x._M_h2);
823      }
824
825    protected:
826      _ExtractKey  _M_extract;
827      _Equal       _M_eq;
828      _H1          _M_h1;
829      _H2          _M_h2;
830    };
831
832  // Specialization: hash function and range-hashing function,
833  // caching hash codes.  H is provided but ignored.  Provides
834  // typedef and accessor required by TR1.
835  template<typename _Key, typename _Value,
836	   typename _ExtractKey, typename _Equal,
837	   typename _H1, typename _H2>
838    struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
839			   _Default_ranged_hash, true>
840    {
841      typedef _H1 hasher;
842
843      hasher
844      hash_function() const
845      { return _M_h1; }
846
847    protected:
848      _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
849		      const _H1& __h1, const _H2& __h2,
850		      const _Default_ranged_hash&)
851      : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
852
853      typedef std::size_t _Hash_code_type;
854
855      _Hash_code_type
856      _M_hash_code(const _Key& __k) const
857      { return _M_h1(__k); }
858
859      std::size_t
860      _M_bucket_index(const _Key&, _Hash_code_type __c,
861		      std::size_t __n) const
862      { return _M_h2(__c, __n); }
863
864      std::size_t
865      _M_bucket_index(const _Hash_node<_Value, true>* __p,
866		      std::size_t __n) const
867      { return _M_h2(__p->_M_hash_code, __n); }
868
869      bool
870      _M_compare(const _Key& __k, _Hash_code_type __c,
871		 _Hash_node<_Value, true>* __n) const
872      { return __c == __n->_M_hash_code && _M_eq(__k, _M_extract(__n->_M_v)); }
873
874      void
875      _M_store_code(_Hash_node<_Value, true>* __n, _Hash_code_type __c) const
876      { __n->_M_hash_code = __c; }
877
878      void
879      _M_copy_code(_Hash_node<_Value, true>* __to,
880		   const _Hash_node<_Value, true>* __from) const
881      { __to->_M_hash_code = __from->_M_hash_code; }
882
883      void
884      _M_swap(_Hash_code_base& __x)
885      {
886	std::swap(_M_extract, __x._M_extract);
887	std::swap(_M_eq, __x._M_eq);
888	std::swap(_M_h1, __x._M_h1);
889	std::swap(_M_h2, __x._M_h2);
890      }
891
892    protected:
893      _ExtractKey  _M_extract;
894      _Equal       _M_eq;
895      _H1          _M_h1;
896      _H2          _M_h2;
897    };
898} // namespace __detail
899_GLIBCXX_END_NAMESPACE
900} // namespace std::tr1
901
902#endif // _TR1_HASHTABLE_POLICY_H
903
904