OSDN Git Service

2005-12-18 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / tr1 / hashtable
1 // Internal header for TR1 unordered_set and unordered_map -*- C++ -*-
2
3 // Copyright (C) 2005 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 
31  *  This is a TR1 C++ Library header. 
32  */
33
34 // This header file defines std::tr1::hashtable, which is used to
35 // implement std::tr1::unordered_set, std::tr1::unordered_map, 
36 // std::tr1::unordered_multiset, and std::tr1::unordered_multimap.
37 // hashtable has many template parameters, partly to accommodate
38 // the differences between those four classes and partly to 
39 // accommodate policy choices that go beyond what TR1 calls for.
40
41 // ??? Arguably this should be Internal::hashtable, not std::tr1::hashtable.
42
43 // Class template hashtable attempts to encapsulate all reasonable
44 // variation among hash tables that use chaining.  It does not handle
45 // open addressing.
46
47 // References: 
48 // M. Austern, "A Proposal to Add Hash Tables to the Standard
49 //    Library (revision 4)," WG21 Document N1456=03-0039, 2003.
50 // D. E. Knuth, The Art of Computer Programming, v. 3, Sorting and Searching.
51 // A. Tavori and V. Dreizin, "Generic Associative Containers", 2004.
52 //    ??? Full citation?
53
54 #ifndef GNU_LIBSTDCXX_TR1_HASHTABLE_
55 #define GNU_LIBSTDCXX_TR1_HASHTABLE_
56
57 #include <utility>              // For std::pair
58 #include <iterator>
59 #include <cstddef>
60 #include <cstdlib>
61 #include <cmath>
62 #include <bits/functexcept.h>
63 #include <tr1/type_traits>      // For true_type and false_type
64
65 //----------------------------------------------------------------------
66 // General utilities
67
68 namespace Internal
69 {
70   template<bool Flag, typename IfTrue, typename IfFalse>
71     struct IF;
72
73   template<typename IfTrue, typename IfFalse>
74     struct IF<true, IfTrue, IfFalse>
75     { typedef IfTrue type; };
76  
77   template <typename IfTrue, typename IfFalse>
78     struct IF<false, IfTrue, IfFalse>
79     { typedef IfFalse type; };
80
81   // Helper function: return distance(first, last) for forward
82   // iterators, or 0 for input iterators.
83   template<class Iterator>
84     inline typename std::iterator_traits<Iterator>::difference_type
85     distance_fw(Iterator first, Iterator last, std::input_iterator_tag)
86     { return 0; }
87
88   template<class Iterator>
89     inline typename std::iterator_traits<Iterator>::difference_type
90     distance_fw(Iterator first, Iterator last, std::forward_iterator_tag)
91     { return std::distance(first, last); }
92
93   template<class Iterator>
94     inline typename std::iterator_traits<Iterator>::difference_type
95     distance_fw(Iterator first, Iterator last)
96     {
97       typedef typename std::iterator_traits<Iterator>::iterator_category tag;
98       return distance_fw(first, last, tag());
99     }
100   
101 } // namespace Internal
102
103 //----------------------------------------------------------------------
104 // Auxiliary types used for all instantiations of hashtable: nodes
105 // and iterators.
106
107 // Nodes, used to wrap elements stored in the hash table.  A policy
108 // template parameter of class template hashtable controls whether
109 // nodes also store a hash code. In some cases (e.g. strings) this may
110 // be a performance win.
111
112 namespace Internal
113 {
114   template<typename Value, bool cache_hash_code>
115     struct hash_node;
116
117   template<typename Value>
118     struct hash_node<Value, true>
119     {
120       Value m_v;
121       std::size_t hash_code;
122       hash_node* m_next;
123     };
124
125   template<typename Value>
126     struct hash_node<Value, false>
127     {
128       Value m_v;
129       hash_node* m_next;
130     };
131
132   // Local iterators, used to iterate within a bucket but not between
133   // buckets.
134
135   template<typename Value, bool cache>
136     struct node_iterator_base
137     {
138       node_iterator_base(hash_node<Value, cache>* p)
139       : m_cur(p) { }
140       
141       void
142       incr()
143       { m_cur = m_cur->m_next; }
144
145       hash_node<Value, cache>* m_cur;
146     };
147
148   template<typename Value, bool cache>
149     inline bool
150     operator==(const node_iterator_base<Value, cache>& x,
151                const node_iterator_base<Value, cache>& y)
152     { return x.m_cur == y.m_cur; }
153
154   template<typename Value, bool cache>
155     inline bool
156     operator!=(const node_iterator_base<Value, cache>& x,
157                const node_iterator_base<Value, cache>& y)
158     { return x.m_cur != y.m_cur; }
159
160   template<typename Value, bool constant_iterators, bool cache>
161     struct node_iterator
162     : public node_iterator_base<Value, cache>
163     {
164       typedef Value                                    value_type;
165       typedef typename IF<constant_iterators, const Value*, Value*>::type
166                                                        pointer;
167       typedef typename IF<constant_iterators, const Value&, Value&>::type
168                                                        reference;
169       typedef std::ptrdiff_t                           difference_type;
170       typedef std::forward_iterator_tag                iterator_category;
171
172       explicit
173       node_iterator(hash_node<Value, cache>* p = 0)
174       : node_iterator_base<Value, cache>(p) { }
175
176       reference
177       operator*() const
178       { return this->m_cur->m_v; }
179   
180       pointer
181       operator->() const
182       { return &this->m_cur->m_v; }
183
184       node_iterator&
185       operator++()
186       { 
187         this->incr(); 
188         return *this; 
189       }
190   
191       node_iterator
192       operator++(int)
193       { 
194         node_iterator tmp(*this);
195         this->incr();
196         return tmp;
197       }
198     };
199
200   template<typename Value, bool constant_iterators, bool cache>
201     struct node_const_iterator
202     : public node_iterator_base<Value, cache>
203     {
204       typedef Value                                    value_type;
205       typedef const Value*                             pointer;
206       typedef const Value&                             reference;
207       typedef std::ptrdiff_t                           difference_type;
208       typedef std::forward_iterator_tag                iterator_category;
209
210       explicit
211       node_const_iterator(hash_node<Value, cache>* p = 0)
212       : node_iterator_base<Value, cache>(p) { }
213
214       node_const_iterator(const node_iterator<Value, constant_iterators,
215                           cache>& x)
216       : node_iterator_base<Value, cache>(x.m_cur) { }
217
218       reference
219       operator*() const
220       { return this->m_cur->m_v; }
221   
222       pointer
223       operator->() const
224       { return &this->m_cur->m_v; }
225
226       node_const_iterator&
227       operator++()
228       { 
229         this->incr(); 
230         return *this; 
231       }
232   
233       node_const_iterator
234       operator++(int)
235       { 
236         node_const_iterator tmp(*this);
237         this->incr();
238         return tmp;
239       }
240     };
241
242   template<typename Value, bool cache>
243     struct hashtable_iterator_base
244     {
245       hashtable_iterator_base(hash_node<Value, cache>* node,
246                               hash_node<Value, cache>** bucket)
247       : m_cur_node(node), m_cur_bucket(bucket)
248       { }
249
250       void
251       incr()
252       {
253         m_cur_node = m_cur_node->m_next;
254         if (!m_cur_node)
255           m_incr_bucket();
256       }
257
258       void
259       m_incr_bucket();
260
261       hash_node<Value, cache>* m_cur_node;
262       hash_node<Value, cache>** m_cur_bucket;
263     };
264
265   // Global iterators, used for arbitrary iteration within a hash
266   // table.  Larger and more expensive than local iterators.
267   template<typename Value, bool cache>
268     void
269     hashtable_iterator_base<Value, cache>::
270     m_incr_bucket()
271     {
272       ++m_cur_bucket;
273
274       // This loop requires the bucket array to have a non-null sentinel.
275       while (!*m_cur_bucket)
276         ++m_cur_bucket;
277       m_cur_node = *m_cur_bucket;
278     }
279
280   template<typename Value, bool cache>
281     inline bool
282     operator==(const hashtable_iterator_base<Value, cache>& x,
283                const hashtable_iterator_base<Value, cache>& y)
284     { return x.m_cur_node == y.m_cur_node; }
285
286   template<typename Value, bool cache>
287     inline bool
288     operator!=(const hashtable_iterator_base<Value, cache>& x,
289                const hashtable_iterator_base<Value, cache>& y)
290     { return x.m_cur_node != y.m_cur_node; }
291
292   template<typename Value, bool constant_iterators, bool cache>
293     struct hashtable_iterator
294     : public hashtable_iterator_base<Value, cache>
295     {
296       typedef Value                                    value_type;
297       typedef typename IF<constant_iterators, const Value*, Value*>::type
298                                                        pointer;
299       typedef typename IF<constant_iterators, const Value&, Value&>::type
300                                                        reference;
301       typedef std::ptrdiff_t                           difference_type;
302       typedef std::forward_iterator_tag                iterator_category;
303
304       hashtable_iterator(hash_node<Value, cache>* p,
305                          hash_node<Value, cache>** b)
306       : hashtable_iterator_base<Value, cache>(p, b) { }
307
308       explicit
309       hashtable_iterator(hash_node<Value, cache>** b)
310       : hashtable_iterator_base<Value, cache>(*b, b) { }
311   
312       reference
313       operator*() const
314       { return this->m_cur_node->m_v; }
315   
316       pointer
317       operator->() const
318       { return &this->m_cur_node->m_v; }
319
320       hashtable_iterator&
321       operator++()
322       { 
323         this->incr();
324         return *this;
325       }
326   
327       hashtable_iterator
328       operator++(int)
329       { 
330         hashtable_iterator tmp(*this);
331         this->incr();
332         return tmp;
333       }
334     };
335
336   template<typename Value, bool constant_iterators, bool cache>
337     struct hashtable_const_iterator
338     : public hashtable_iterator_base<Value, cache>
339     {
340       typedef Value                                    value_type;
341       typedef const Value*                             pointer;
342       typedef const Value&                             reference;
343       typedef std::ptrdiff_t                           difference_type;
344       typedef std::forward_iterator_tag                iterator_category;
345
346       hashtable_const_iterator(hash_node<Value, cache>* p,
347                                hash_node<Value, cache>** b)
348       : hashtable_iterator_base<Value, cache>(p, b) { }
349
350       explicit
351       hashtable_const_iterator(hash_node<Value, cache>** b)
352       : hashtable_iterator_base<Value, cache>(*b, b) { }
353   
354       hashtable_const_iterator(const hashtable_iterator<Value,
355                                constant_iterators, cache>& x)
356       : hashtable_iterator_base<Value, cache>(x.m_cur_node, x.m_cur_bucket) { }
357
358       reference
359       operator*() const
360       { return this->m_cur_node->m_v; }
361   
362       pointer
363       operator->() const
364       { return &this->m_cur_node->m_v; }
365
366       hashtable_const_iterator&
367       operator++()
368       { 
369         this->incr();
370         return *this;
371       }
372   
373       hashtable_const_iterator
374       operator++(int)
375       { 
376         hashtable_const_iterator tmp(*this);
377         this->incr();
378         return tmp;
379       }
380     };
381 } // namespace Internal
382
383 // ----------------------------------------------------------------------
384 // Many of class template hashtable's template parameters are policy
385 // classes.  These are defaults for the policies.
386
387 namespace Internal
388 {
389   // The two key extraction policies used by the *set and *map variants.
390   template<typename T>
391     struct identity
392     {
393       T
394       operator()(const T& t) const
395       { return t; }
396     };
397
398   template<typename Pair>
399     struct extract1st
400     {
401       typename Pair::first_type
402       operator()(const Pair& p) const
403       { return p.first; }
404     };
405
406   // Default range hashing function: use division to fold a large number
407   // into the range [0, N).
408   struct mod_range_hashing
409   {
410     typedef std::size_t first_argument_type;
411     typedef std::size_t second_argument_type;
412     typedef std::size_t result_type;
413
414     result_type
415     operator() (first_argument_type r, second_argument_type N) const
416     { return r % N; }
417   };
418
419   // Default ranged hash function H.  In principle it should be a
420   // function object composed from objects of type H1 and H2 such that
421   // h(k, N) = h2(h1(k), N), but that would mean making extra copies of
422   // h1 and h2.  So instead we'll just use a tag to tell class template
423   // hashtable to do that composition.
424   struct default_ranged_hash { };
425
426   // Default value for rehash policy.  Bucket size is (usually) the
427   // smallest prime that keeps the load factor small enough.
428   struct prime_rehash_policy
429   {
430     prime_rehash_policy(float z = 1.0);
431     
432     float
433     max_load_factor() const;
434
435     // Return a bucket size no smaller than n.
436     std::size_t
437     next_bkt(std::size_t n) const;
438     
439     // Return a bucket count appropriate for n elements
440     std::size_t
441     bkt_for_elements(std::size_t n) const;
442     
443     // n_bkt is current bucket count, n_elt is current element count,
444     // and n_ins is number of elements to be inserted.  Do we need to
445     // increase bucket count?  If so, return make_pair(true, n), where n
446     // is the new bucket count.  If not, return make_pair(false, 0).
447     std::pair<bool, std::size_t>
448     need_rehash(std::size_t n_bkt, std::size_t n_elt, std::size_t n_ins) const;
449     
450     float m_max_load_factor;
451     float m_growth_factor;
452     mutable std::size_t m_next_resize;
453   };
454
455   // XXX This is a hack.  prime_rehash_policy's member functions, and
456   // certainly the list of primes, should be defined in a .cc file.
457   // We're temporarily putting them in a header because we don't have a
458   // place to put TR1 .cc files yet.  There's no good reason for any of
459   // prime_rehash_policy's member functions to be inline, and there's
460   // certainly no good reason for X<> to exist at all.
461   
462   struct lt
463   {
464     template<typename X, typename Y>
465       bool
466       operator()(X x, Y y)
467       { return x < y; }
468   };
469
470   template<int dummy>
471     struct X
472     {
473       static const int n_primes = 256;
474       static const unsigned long primes[n_primes + 1];
475     };
476
477   template<int dummy>
478     const int X<dummy>::n_primes;
479
480   template<int dummy>
481     const unsigned long X<dummy>::primes[n_primes + 1] =
482     {
483       2ul, 3ul, 5ul, 7ul, 11ul, 13ul, 17ul, 19ul, 23ul, 29ul, 31ul,
484       37ul, 41ul, 43ul, 47ul, 53ul, 59ul, 61ul, 67ul, 71ul, 73ul, 79ul,
485       83ul, 89ul, 97ul, 103ul, 109ul, 113ul, 127ul, 137ul, 139ul, 149ul,
486       157ul, 167ul, 179ul, 193ul, 199ul, 211ul, 227ul, 241ul, 257ul,
487       277ul, 293ul, 313ul, 337ul, 359ul, 383ul, 409ul, 439ul, 467ul,
488       503ul, 541ul, 577ul, 619ul, 661ul, 709ul, 761ul, 823ul, 887ul,
489       953ul, 1031ul, 1109ul, 1193ul, 1289ul, 1381ul, 1493ul, 1613ul,
490       1741ul, 1879ul, 2029ul, 2179ul, 2357ul, 2549ul, 2753ul, 2971ul,
491       3209ul, 3469ul, 3739ul, 4027ul, 4349ul, 4703ul, 5087ul, 5503ul,
492       5953ul, 6427ul, 6949ul, 7517ul, 8123ul, 8783ul, 9497ul, 10273ul,
493       11113ul, 12011ul, 12983ul, 14033ul, 15173ul, 16411ul, 17749ul,
494       19183ul, 20753ul, 22447ul, 24281ul, 26267ul, 28411ul, 30727ul,
495       33223ul, 35933ul, 38873ul, 42043ul, 45481ul, 49201ul, 53201ul,
496       57557ul, 62233ul, 67307ul, 72817ul, 78779ul, 85229ul, 92203ul,
497       99733ul, 107897ul, 116731ul, 126271ul, 136607ul, 147793ul,
498       159871ul, 172933ul, 187091ul, 202409ul, 218971ul, 236897ul,
499       256279ul, 277261ul, 299951ul, 324503ul, 351061ul, 379787ul,
500       410857ul, 444487ul, 480881ul, 520241ul, 562841ul, 608903ul,
501       658753ul, 712697ul, 771049ul, 834181ul, 902483ul, 976369ul,
502       1056323ul, 1142821ul, 1236397ul, 1337629ul, 1447153ul, 1565659ul,
503       1693859ul, 1832561ul, 1982627ul, 2144977ul, 2320627ul, 2510653ul,
504       2716249ul, 2938679ul, 3179303ul, 3439651ul, 3721303ul, 4026031ul,
505       4355707ul, 4712381ul, 5098259ul, 5515729ul, 5967347ul, 6456007ul,
506       6984629ul, 7556579ul, 8175383ul, 8844859ul, 9569143ul, 10352717ul,
507       11200489ul, 12117689ul, 13109983ul, 14183539ul, 15345007ul,
508       16601593ul, 17961079ul, 19431899ul, 21023161ul, 22744717ul,
509       24607243ul, 26622317ul, 28802401ul, 31160981ul, 33712729ul,
510       36473443ul, 39460231ul, 42691603ul, 46187573ul, 49969847ul,
511       54061849ul, 58488943ul, 63278561ul, 68460391ul, 74066549ul,
512       80131819ul, 86693767ul, 93793069ul, 101473717ul, 109783337ul,
513       118773397ul, 128499677ul, 139022417ul, 150406843ul, 162723577ul,
514       176048909ul, 190465427ul, 206062531ul, 222936881ul, 241193053ul,
515       260944219ul, 282312799ul, 305431229ul, 330442829ul, 357502601ul,
516       386778277ul, 418451333ul, 452718089ul, 489790921ul, 529899637ul,
517       573292817ul, 620239453ul, 671030513ul, 725980837ul, 785430967ul,
518       849749479ul, 919334987ul, 994618837ul, 1076067617ul, 1164186217ul,
519       1259520799ul, 1362662261ul, 1474249943ul, 1594975441ul,
520       1725587117ul, 1866894511ul, 2019773507ul, 2185171673ul,
521       2364114217ul, 2557710269ul, 2767159799ul, 2993761039ul,
522       3238918481ul, 3504151727ul, 3791104843ul, 4101556399ul,
523       4294967291ul,
524       4294967291ul // sentinel so we don't have to test result of lower_bound
525     };
526
527   inline
528   prime_rehash_policy::
529   prime_rehash_policy(float z)
530   : m_max_load_factor(z), m_growth_factor(2.f), m_next_resize(0)
531   { }
532
533   inline float
534   prime_rehash_policy::
535   max_load_factor() const
536   { return m_max_load_factor; }
537
538   // Return a prime no smaller than n.
539   inline std::size_t
540   prime_rehash_policy::
541   next_bkt(std::size_t n) const
542   {
543     const unsigned long* const last = X<0>::primes + X<0>::n_primes;
544     const unsigned long* p = std::lower_bound (X<0>::primes, last, n);
545     m_next_resize = static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));
546     return *p;
547   }
548
549   // Return the smallest prime p such that alpha p >= n, where alpha
550   // is the load factor.
551   inline std::size_t
552   prime_rehash_policy::
553   bkt_for_elements(std::size_t n) const
554   {
555     const unsigned long* const last = X<0>::primes + X<0>::n_primes;
556     const float min_bkts = n / m_max_load_factor;
557     const unsigned long* p = std::lower_bound (X<0>::primes, last,
558                                                min_bkts, lt());
559     m_next_resize = static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));
560     return *p;
561   }
562
563   // Finds the smallest prime p such that alpha p > n_elt + n_ins.
564   // If p > n_bkt, return make_pair(true, p); otherwise return
565   // make_pair(false, 0).  In principle this isn't very different from 
566   // bkt_for_elements.
567   
568   // The only tricky part is that we're caching the element count at
569   // which we need to rehash, so we don't have to do a floating-point
570   // multiply for every insertion.
571   
572   inline std::pair<bool, std::size_t>
573   prime_rehash_policy::
574   need_rehash(std::size_t n_bkt, std::size_t n_elt, std::size_t n_ins) const
575   {
576     if (n_elt + n_ins > m_next_resize)
577       {
578         float min_bkts = (float(n_ins) + float(n_elt)) / m_max_load_factor;
579         if (min_bkts > n_bkt)
580           {
581             min_bkts = std::max (min_bkts, m_growth_factor * n_bkt);
582             const unsigned long* const last = X<0>::primes + X<0>::n_primes;
583             const unsigned long* p = std::lower_bound (X<0>::primes, last,
584                                                        min_bkts, lt());
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 * m_max_load_factor));
593             return std::make_pair(false, 0);
594           }
595       }
596     else
597       return std::make_pair(false, 0);
598   }
599
600 } // namespace Internal
601
602 //----------------------------------------------------------------------
603 // Base classes for std::tr1::hashtable.  We define these base classes
604 // because in some cases we want to do different things depending on
605 // the value of a policy class.  In some cases the policy class affects
606 // which member functions and nested typedefs are defined; we handle that
607 // by specializing base class templates.  Several of the base class templates
608 // need to access other members of class template hashtable, so we use
609 // the "curiously recurring template pattern" for them.
610
611 namespace Internal
612 {
613   // class template map_base.  If the hashtable has a value type of the
614   // form pair<T1, T2> and a key extraction policy that returns the
615   // first part of the pair, the hashtable gets a mapped_type typedef.
616   // If it satisfies those criteria and also has unique keys, then it
617   // also gets an operator[].
618   
619   template<typename K, typename V, typename Ex, bool unique, typename Hashtable>
620     struct map_base { };
621           
622   template<typename K, typename Pair, typename Hashtable>
623     struct map_base<K, Pair, extract1st<Pair>, false, Hashtable>
624     {
625       typedef typename Pair::second_type mapped_type;
626     };
627
628   template<typename K, typename Pair, typename Hashtable>
629     struct map_base<K, Pair, extract1st<Pair>, true, Hashtable>
630     {
631       typedef typename Pair::second_type mapped_type;
632       
633       mapped_type&
634       operator[](const K& k)
635       {
636         Hashtable* h = static_cast<Hashtable*>(this);
637         typename Hashtable::iterator it = 
638           h->insert(std::make_pair(k, mapped_type())).first;
639         return it->second;
640       }
641     };
642
643   // class template rehash_base.  Give hashtable the max_load_factor
644   // functions iff the rehash policy is prime_rehash_policy.
645   template<typename RehashPolicy, typename Hashtable>
646     struct rehash_base { };
647
648   template<typename Hashtable>
649     struct rehash_base<prime_rehash_policy, Hashtable>
650     {
651       float
652       max_load_factor() const
653       {
654         const Hashtable* This = static_cast<const Hashtable*>(this);
655         return This->rehash_policy()->max_load_factor();
656       }
657
658       void
659       max_load_factor(float z)
660       {
661         Hashtable* This = static_cast<Hashtable*>(this);
662         This->rehash_policy(prime_rehash_policy(z));    
663       }
664     };
665
666   // Class template hash_code_base.  Encapsulates two policy issues that
667   // aren't quite orthogonal.
668   //   (1) the difference between using a ranged hash function and using
669   //       the combination of a hash function and a range-hashing function.
670   //       In the former case we don't have such things as hash codes, so
671   //       we have a dummy type as placeholder.
672   //   (2) Whether or not we cache hash codes.  Caching hash codes is
673   //       meaningless if we have a ranged hash function.
674   // We also put the key extraction and equality comparison function 
675   // objects here, for convenience.
676   
677   // Primary template: unused except as a hook for specializations.
678   
679   template<typename Key, typename Value,
680            typename ExtractKey, typename Equal,
681            typename H1, typename H2, typename H,
682            bool cache_hash_code>
683     struct hash_code_base;
684
685   // Specialization: ranged hash function, no caching hash codes.  H1
686   // and H2 are provided but ignored.  We define a dummy hash code type.
687   template<typename Key, typename Value,
688            typename ExtractKey, typename Equal,
689            typename H1, typename H2, typename H>
690     struct hash_code_base<Key, Value, ExtractKey, Equal, H1, H2, H, false>
691     {
692     protected:
693       hash_code_base(const ExtractKey& ex, const Equal& eq,
694                      const H1&, const H2&, const H& h)
695       : m_extract(ex), m_eq(eq), m_ranged_hash(h) { }
696
697       typedef void* hash_code_t;
698   
699       hash_code_t
700       m_hash_code(const Key& k) const
701       { return 0; }
702   
703       std::size_t
704       bucket_index(const Key& k, hash_code_t, std::size_t N) const
705       { return m_ranged_hash (k, N); }
706
707       std::size_t
708       bucket_index(const hash_node<Value, false>* p, std::size_t N) const
709       { return m_ranged_hash (m_extract (p->m_v), N); }
710   
711       bool
712       compare(const Key& k, hash_code_t, hash_node<Value, false>* n) const
713       { return m_eq (k, m_extract(n->m_v)); }
714
715       void
716       store_code(hash_node<Value, false>*, hash_code_t) const
717       { }
718
719       void
720       copy_code(hash_node<Value, false>*, const hash_node<Value, false>*) const
721       { }
722       
723       void
724       m_swap(hash_code_base& x)
725       {
726         std::swap(m_extract, x.m_extract);
727         std::swap(m_eq, x.m_eq);
728         std::swap(m_ranged_hash, x.m_ranged_hash);
729       }
730
731     protected:
732       ExtractKey m_extract;
733       Equal m_eq;
734       H m_ranged_hash;
735     };
736
737
738   // No specialization for ranged hash function while caching hash codes.
739   // That combination is meaningless, and trying to do it is an error.
740   
741   
742   // Specialization: ranged hash function, cache hash codes.  This
743   // combination is meaningless, so we provide only a declaration
744   // and no definition.
745   
746   template<typename Key, typename Value,
747             typename ExtractKey, typename Equal,
748             typename H1, typename H2, typename H>
749     struct hash_code_base<Key, Value, ExtractKey, Equal, H1, H2, H, true>;
750
751
752   // Specialization: hash function and range-hashing function, no
753   // caching of hash codes.  H is provided but ignored.  Provides
754   // typedef and accessor required by TR1.
755   
756   template<typename Key, typename Value,
757            typename ExtractKey, typename Equal,
758            typename H1, typename H2>
759     struct hash_code_base<Key, Value, ExtractKey, Equal, H1, H2,
760                           default_ranged_hash, false>
761     {
762       typedef H1 hasher;
763       
764       hasher
765       hash_function() const
766       { return m_h1; }
767
768     protected:
769       hash_code_base(const ExtractKey& ex, const Equal& eq,
770                      const H1& h1, const H2& h2, const default_ranged_hash&)
771       : m_extract(ex), m_eq(eq), m_h1(h1), m_h2(h2) { }
772
773       typedef std::size_t hash_code_t;
774       
775       hash_code_t
776       m_hash_code(const Key& k) const
777       { return m_h1(k); }
778       
779       std::size_t
780       bucket_index(const Key&, hash_code_t c, std::size_t N) const
781       { return m_h2 (c, N); }
782
783       std::size_t
784       bucket_index(const hash_node<Value, false>* p, std::size_t N) const
785       { return m_h2 (m_h1 (m_extract (p->m_v)), N); }
786
787       bool
788       compare(const Key& k, hash_code_t, hash_node<Value, false>* n) const
789       { return m_eq (k, m_extract(n->m_v)); }
790
791       void
792       store_code(hash_node<Value, false>*, hash_code_t) const
793       { }
794
795       void
796       copy_code(hash_node<Value, false>*, const hash_node<Value, false>*) const
797       { }
798
799       void
800       m_swap(hash_code_base& x)
801       {
802         std::swap(m_extract, x.m_extract);
803         std::swap(m_eq, x.m_eq);
804         std::swap(m_h1, x.m_h1);
805         std::swap(m_h2, x.m_h2);
806       }
807
808     protected:
809       ExtractKey m_extract;
810       Equal m_eq;
811       H1 m_h1;
812       H2 m_h2;
813     };
814
815   // Specialization: hash function and range-hashing function, 
816   // caching hash codes.  H is provided but ignored.  Provides
817   // typedef and accessor required by TR1.
818   template<typename Key, typename Value,
819            typename ExtractKey, typename Equal,
820            typename H1, typename H2>
821     struct hash_code_base<Key, Value, ExtractKey, Equal, H1, H2,
822                           default_ranged_hash, true>
823     {
824       typedef H1 hasher;
825       
826       hasher
827       hash_function() const
828       { return m_h1; }
829
830     protected:
831       hash_code_base(const ExtractKey& ex, const Equal& eq,
832                      const H1& h1, const H2& h2, const default_ranged_hash&)
833       : m_extract(ex), m_eq(eq), m_h1(h1), m_h2(h2) { }
834
835       typedef std::size_t hash_code_t;
836   
837       hash_code_t
838       m_hash_code (const Key& k) const
839       { return m_h1(k); }
840   
841       std::size_t
842       bucket_index(const Key&, hash_code_t c, std::size_t N) const
843       { return m_h2 (c, N); }
844
845       std::size_t
846       bucket_index(const hash_node<Value, true>* p, std::size_t N) const
847       { return m_h2 (p->hash_code, N); }
848
849       bool
850       compare(const Key& k, hash_code_t c, hash_node<Value, true>* n) const
851       { return c == n->hash_code && m_eq(k, m_extract(n->m_v)); }
852
853       void
854       store_code(hash_node<Value, true>* n, hash_code_t c) const
855       { n->hash_code = c; }
856
857       void
858       copy_code(hash_node<Value, true>* to,
859                 const hash_node<Value, true>* from) const
860       { to->hash_code = from->hash_code; }
861
862       void
863       m_swap(hash_code_base& x)
864       {
865         std::swap(m_extract, x.m_extract);
866         std::swap(m_eq, x.m_eq);
867         std::swap(m_h1, x.m_h1);
868         std::swap(m_h2, x.m_h2);
869       }
870       
871     protected:
872       ExtractKey m_extract;
873       Equal m_eq;
874       H1 m_h1;
875       H2 m_h2;
876     };
877
878 } // namespace internal
879
880 namespace std
881
882 _GLIBCXX_BEGIN_NAMESPACE(tr1)
883
884   //----------------------------------------------------------------------
885   // Class template hashtable, class definition.
886   
887   // Meaning of class template hashtable's template parameters
888   
889   // Key and Value: arbitrary CopyConstructible types.
890   
891   // Allocator: an allocator type ([lib.allocator.requirements]) whose
892   // value type is Value.
893   
894   // ExtractKey: function object that takes a object of type Value
895   // and returns a value of type Key.
896   
897   // Equal: function object that takes two objects of type k and returns
898   // a bool-like value that is true if the two objects are considered equal.
899   
900   // H1: the hash function.  A unary function object with argument type
901   // Key and result type size_t.  Return values should be distributed
902   // over the entire range [0, numeric_limits<size_t>:::max()].
903   
904   // H2: the range-hashing function (in the terminology of Tavori and
905   // Dreizin).  A binary function object whose argument types and result
906   // type are all size_t.  Given arguments r and N, the return value is
907   // in the range [0, N).
908   
909   // H: the ranged hash function (Tavori and Dreizin). A binary function
910   // whose argument types are Key and size_t and whose result type is
911   // size_t.  Given arguments k and N, the return value is in the range
912   // [0, N).  Default: h(k, N) = h2(h1(k), N).  If H is anything other
913   // than the default, H1 and H2 are ignored.
914   
915   // RehashPolicy: Policy class with three members, all of which govern
916   // the bucket count. n_bkt(n) returns a bucket count no smaller
917   // than n.  bkt_for_elements(n) returns a bucket count appropriate
918   // for an element count of n.  need_rehash(n_bkt, n_elt, n_ins)
919   // determines whether, if the current bucket count is n_bkt and the
920   // current element count is n_elt, we need to increase the bucket
921   // count.  If so, returns make_pair(true, n), where n is the new
922   // bucket count.  If not, returns make_pair(false, <anything>).
923   
924   // ??? Right now it is hard-wired that the number of buckets never
925   // shrinks.  Should we allow RehashPolicy to change that?
926   
927   // cache_hash_code: bool.  true if we store the value of the hash
928   // function along with the value.  This is a time-space tradeoff.
929   // Storing it may improve lookup speed by reducing the number of times
930   // we need to call the Equal function.
931   
932   // constant_iterators: bool.  true if iterator and const_iterator are
933   // both constant iterator types.  This is true for unordered_set and
934   // unordered_multiset, false for unordered_map and unordered_multimap.
935   
936   // unique_keys: bool.  true if the return value of hashtable::count(k)
937   // is always at most one, false if it may be an arbitrary number.  This
938   // true for unordered_set and unordered_map, false for unordered_multiset
939   // and unordered_multimap.
940   
941   template<typename Key, typename Value, 
942            typename Allocator,
943            typename ExtractKey, typename Equal,
944            typename H1, typename H2,
945            typename H, typename RehashPolicy,
946            bool cache_hash_code,
947            bool constant_iterators,
948            bool unique_keys>
949     class hashtable
950     : public Internal::rehash_base<RehashPolicy,
951                                    hashtable<Key, Value, Allocator, ExtractKey,
952                                              Equal, H1, H2, H, RehashPolicy,
953                                              cache_hash_code, constant_iterators,
954                                              unique_keys> >,
955       public Internal::hash_code_base<Key, Value, ExtractKey, Equal, H1, H2, H,
956                                       cache_hash_code>,
957       public Internal::map_base<Key, Value, ExtractKey, unique_keys,
958                                 hashtable<Key, Value, Allocator, ExtractKey,
959                                           Equal, H1, H2, H, RehashPolicy,
960                                           cache_hash_code, constant_iterators,
961                                           unique_keys> >
962     {
963     public:
964       typedef Allocator                                      allocator_type;
965       typedef Value                                          value_type;
966       typedef Key                                            key_type;
967       typedef Equal                                          key_equal;
968       // mapped_type, if present, comes from map_base.
969       // hasher, if present, comes from hash_code_base.
970       typedef typename Allocator::difference_type            difference_type;
971       typedef typename Allocator::size_type                  size_type;
972       typedef typename Allocator::reference                  reference;
973       typedef typename Allocator::const_reference            const_reference;
974       
975       typedef Internal::node_iterator<value_type, constant_iterators,
976                                       cache_hash_code>
977         local_iterator;
978       typedef Internal::node_const_iterator<value_type, constant_iterators,
979                                             cache_hash_code>
980         const_local_iterator;
981
982       typedef Internal::hashtable_iterator<value_type, constant_iterators,
983                                            cache_hash_code>
984         iterator;
985       typedef Internal::hashtable_const_iterator<value_type, constant_iterators,
986                                                  cache_hash_code>
987         const_iterator;
988
989     private:
990       typedef Internal::hash_node<Value, cache_hash_code>    node;
991       typedef typename Allocator::template rebind<node>::other
992         node_allocator_t;
993       typedef typename Allocator::template rebind<node*>::other
994         bucket_allocator_t;
995
996     private:
997       node_allocator_t m_node_allocator;
998       node** m_buckets;
999       size_type m_bucket_count;
1000       size_type m_element_count;
1001       RehashPolicy m_rehash_policy;
1002       
1003       node*
1004       m_allocate_node(const value_type& v);
1005   
1006       void
1007       m_deallocate_node(node* n);
1008   
1009       void
1010       m_deallocate_nodes(node**, size_type);
1011
1012       node**
1013       m_allocate_buckets(size_type n);
1014   
1015       void
1016       m_deallocate_buckets(node**, size_type n);
1017
1018     public:                         // Constructor, destructor, assignment, swap
1019       hashtable(size_type bucket_hint,
1020                 const H1&, const H2&, const H&,
1021                 const Equal&, const ExtractKey&,
1022                 const allocator_type&);
1023   
1024       template<typename InIter>
1025         hashtable(InIter first, InIter last,
1026                   size_type bucket_hint,
1027                   const H1&, const H2&, const H&,
1028                   const Equal&, const ExtractKey&,
1029                   const allocator_type&);
1030   
1031       hashtable(const hashtable&);
1032       
1033       hashtable&
1034       operator=(const hashtable&);
1035   
1036       ~hashtable();
1037
1038       void swap(hashtable&);
1039
1040     public:                             // Basic container operations
1041       iterator
1042       begin()
1043       {
1044         iterator i(m_buckets);
1045         if (!i.m_cur_node)
1046           i.m_incr_bucket();
1047         return i;
1048       }
1049
1050       const_iterator
1051       begin() const
1052       {
1053         const_iterator i(m_buckets);
1054         if (!i.m_cur_node)
1055           i.m_incr_bucket();
1056         return i;
1057       }
1058
1059       iterator
1060       end()
1061       { return iterator(m_buckets + m_bucket_count); }
1062
1063       const_iterator
1064       end() const
1065       { return const_iterator(m_buckets + m_bucket_count); }
1066
1067       size_type
1068       size() const
1069       { return m_element_count; }
1070   
1071       bool
1072       empty() const
1073       { return size() == 0; }
1074
1075       allocator_type
1076       get_allocator() const
1077       { return m_node_allocator; }
1078   
1079       size_type
1080       max_size() const
1081       { return m_node_allocator.max_size(); }
1082
1083     public:                             // Bucket operations
1084       size_type
1085       bucket_count() const
1086       { return m_bucket_count; }
1087   
1088       size_type
1089       max_bucket_count() const
1090       { return max_size(); }
1091   
1092       size_type
1093       bucket_size(size_type n) const
1094       { return std::distance(begin(n), end(n)); }
1095   
1096       size_type bucket(const key_type& k) const
1097       { 
1098         return this->bucket_index(k, this->m_hash_code, this->m_bucket_count);
1099       }
1100
1101       local_iterator
1102       begin(size_type n)
1103       { return local_iterator(m_buckets[n]); }
1104   
1105       local_iterator
1106       end(size_type n)
1107       { return local_iterator(0); }
1108   
1109       const_local_iterator
1110       begin(size_type n) const
1111       { return const_local_iterator(m_buckets[n]); }
1112   
1113       const_local_iterator
1114       end(size_type n) const
1115       { return const_local_iterator(0); }
1116
1117       float
1118       load_factor() const
1119       { 
1120         return static_cast<float>(size()) / static_cast<float>(bucket_count());
1121       }
1122       // max_load_factor, if present, comes from rehash_base.
1123
1124       // Generalization of max_load_factor.  Extension, not found in TR1.  Only
1125       // useful if RehashPolicy is something other than the default.
1126       const RehashPolicy&
1127       rehash_policy() const
1128       { return m_rehash_policy; }
1129       
1130       void 
1131       rehash_policy(const RehashPolicy&);
1132
1133     public:                             // lookup
1134       iterator
1135       find(const key_type&);
1136
1137       const_iterator
1138       find(const key_type& k) const;
1139
1140       size_type
1141       count(const key_type& k) const;
1142
1143       std::pair<iterator, iterator>
1144       equal_range(const key_type& k);
1145
1146       std::pair<const_iterator, const_iterator>
1147       equal_range(const key_type& k) const;
1148
1149     private:                    // Insert and erase helper functions
1150       // ??? This dispatching is a workaround for the fact that we don't
1151       // have partial specialization of member templates; it would be
1152       // better to just specialize insert on unique_keys.  There may be a
1153       // cleaner workaround.
1154       typedef typename Internal::IF<unique_keys,
1155                                     std::pair<iterator, bool>, iterator>::type
1156         Insert_Return_Type;
1157
1158       typedef typename Internal::IF<unique_keys,
1159                                     Internal::extract1st<Insert_Return_Type>,
1160                                     Internal::identity<Insert_Return_Type>
1161                                    >::type
1162         Insert_Conv_Type;
1163
1164       node*
1165       find_node(node* p, const key_type& k,
1166                 typename hashtable::hash_code_t c) const;
1167
1168       std::pair<iterator, bool>
1169       insert(const value_type&, std::tr1::true_type);
1170   
1171       iterator
1172       insert(const value_type&, std::tr1::false_type);
1173
1174       void
1175       erase_node(node*, node**);
1176
1177     public:                             // Insert and erase
1178       Insert_Return_Type
1179       insert(const value_type& v) 
1180       { 
1181         return this->insert(v, std::tr1::integral_constant<bool,
1182                             unique_keys>());
1183       }
1184
1185       iterator
1186       insert(iterator, const value_type& v)
1187       { return iterator(Insert_Conv_Type()(this->insert(v))); }
1188       
1189       const_iterator
1190       insert(const_iterator, const value_type& v)
1191       { return const_iterator(Insert_Conv_Type()(this->insert(v))); }
1192
1193       template<typename InIter>
1194         void
1195         insert(InIter first, InIter last);
1196
1197       iterator
1198       erase(iterator);
1199
1200       const_iterator
1201       erase(const_iterator);
1202
1203       size_type
1204       erase(const key_type&);
1205
1206       iterator
1207       erase(iterator, iterator);
1208
1209       const_iterator
1210       erase(const_iterator, const_iterator);
1211
1212       void
1213       clear();
1214
1215     public:
1216       // Set number of buckets to be apropriate for container of n element.
1217       void rehash(size_type n);
1218       
1219     private:
1220       // Unconditionally change size of bucket array to n.
1221       void m_rehash(size_type n);
1222     };
1223
1224   //----------------------------------------------------------------------
1225   // Definitions of class template hashtable's out-of-line member functions.
1226   
1227   template<typename K, typename V, 
1228            typename A, typename Ex, typename Eq,
1229            typename H1, typename H2, typename H, typename RP,
1230            bool c, bool ci, bool u>
1231     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::node*
1232     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1233     m_allocate_node(const value_type& v)
1234     {
1235       node* n = m_node_allocator.allocate(1);
1236       try
1237         {
1238           get_allocator().construct(&n->m_v, v);
1239           n->m_next = 0;
1240           return n;
1241         }
1242       catch(...)
1243         {
1244           m_node_allocator.deallocate(n, 1);
1245           __throw_exception_again;
1246         }
1247     }
1248
1249   template<typename K, typename V, 
1250            typename A, typename Ex, typename Eq,
1251            typename H1, typename H2, typename H, typename RP,
1252            bool c, bool ci, bool u>
1253     void
1254     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1255     m_deallocate_node(node* n)
1256     {
1257       get_allocator().destroy(&n->m_v);
1258       m_node_allocator.deallocate(n, 1);
1259     }
1260
1261   template<typename K, typename V, 
1262            typename A, typename Ex, typename Eq,
1263            typename H1, typename H2, typename H, typename RP,
1264            bool c, bool ci, bool u>
1265     void
1266     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1267     m_deallocate_nodes(node** array, size_type n)
1268     {
1269       for (size_type i = 0; i < n; ++i)
1270         {
1271           node* p = array[i];
1272           while (p)
1273             {
1274               node* tmp = p;
1275               p = p->m_next;
1276               m_deallocate_node (tmp);
1277             }
1278           array[i] = 0;
1279         }
1280     }
1281
1282   template<typename K, typename V, 
1283            typename A, typename Ex, typename Eq,
1284            typename H1, typename H2, typename H, typename RP,
1285            bool c, bool ci, bool u>
1286     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::node**
1287     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1288     m_allocate_buckets(size_type n)
1289     {
1290       bucket_allocator_t alloc(m_node_allocator);
1291
1292       // We allocate one extra bucket to hold a sentinel, an arbitrary
1293       // non-null pointer.  Iterator increment relies on this.
1294       node** p = alloc.allocate(n+1);
1295       std::fill(p, p+n, (node*) 0);
1296       p[n] = reinterpret_cast<node*>(0x1000);
1297       return p;
1298     }
1299
1300   template<typename K, typename V, 
1301            typename A, typename Ex, typename Eq,
1302            typename H1, typename H2, typename H, typename RP,
1303            bool c, bool ci, bool u>
1304     void
1305     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1306     m_deallocate_buckets(node** p, size_type n)
1307     {
1308       bucket_allocator_t alloc(m_node_allocator);
1309       alloc.deallocate(p, n+1);
1310     }
1311
1312   template<typename K, typename V, 
1313            typename A, typename Ex, typename Eq,
1314            typename H1, typename H2, typename H, typename RP,
1315            bool c, bool ci, bool u>
1316     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1317     hashtable(size_type bucket_hint,
1318               const H1& h1, const H2& h2, const H& h,
1319               const Eq& eq, const Ex& exk,
1320               const allocator_type& a)
1321     : Internal::rehash_base<RP,hashtable>(),
1322       Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c>(exk, eq, h1, h2, h),
1323       Internal::map_base<K, V, Ex, u, hashtable>(),
1324       m_node_allocator(a),
1325       m_bucket_count(0),
1326       m_element_count(0),
1327       m_rehash_policy()
1328     {
1329       m_bucket_count = m_rehash_policy.next_bkt(bucket_hint);
1330       m_buckets = m_allocate_buckets(m_bucket_count);
1331     }
1332
1333   template<typename K, typename V, 
1334            typename A, typename Ex, typename Eq,
1335            typename H1, typename H2, typename H, typename RP,
1336            bool c, bool ci, bool u>
1337     template<typename InIter>
1338       hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1339       hashtable(InIter f, InIter l,
1340                 size_type bucket_hint,
1341                 const H1& h1, const H2& h2, const H& h,
1342                 const Eq& eq, const Ex& exk,
1343                 const allocator_type& a)
1344       : Internal::rehash_base<RP,hashtable>(),
1345         Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c> (exk, eq,
1346                                                               h1, h2, h),
1347         Internal::map_base<K,V,Ex,u,hashtable>(),
1348         m_node_allocator(a),
1349         m_bucket_count (0),
1350         m_element_count(0),
1351         m_rehash_policy()
1352       {
1353         m_bucket_count = std::max(m_rehash_policy.next_bkt(bucket_hint),
1354                                   m_rehash_policy.
1355                                   bkt_for_elements(Internal::
1356                                                    distance_fw(f, l)));
1357         m_buckets = m_allocate_buckets(m_bucket_count);
1358         try
1359           {
1360             for (; f != l; ++f)
1361               this->insert(*f);
1362           }
1363         catch(...)
1364           {
1365             clear();
1366             m_deallocate_buckets(m_buckets, m_bucket_count);
1367             __throw_exception_again;
1368           }
1369       }
1370   
1371   template<typename K, typename V, 
1372            typename A, typename Ex, typename Eq,
1373            typename H1, typename H2, typename H, typename RP,
1374            bool c, bool ci, bool u>
1375     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1376     hashtable(const hashtable& ht)
1377     : Internal::rehash_base<RP, hashtable>(ht),
1378       Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c>(ht),
1379       Internal::map_base<K, V, Ex, u, hashtable>(ht),
1380       m_node_allocator(ht.get_allocator()),
1381       m_bucket_count(ht.m_bucket_count),
1382       m_element_count(ht.m_element_count),
1383       m_rehash_policy(ht.m_rehash_policy)
1384     {
1385       m_buckets = m_allocate_buckets (m_bucket_count);
1386       try
1387         {
1388           for (size_t i = 0; i < ht.m_bucket_count; ++i)
1389             {
1390               node* n = ht.m_buckets[i];
1391               node** tail = m_buckets + i;
1392               while (n)
1393                 {
1394                   *tail = m_allocate_node(n->m_v);
1395                   this->copy_code(*tail, n);
1396                   tail = &((*tail)->m_next);
1397                   n = n->m_next;
1398                 }
1399             }
1400         }
1401       catch (...)
1402         {
1403           clear();
1404           m_deallocate_buckets (m_buckets, m_bucket_count);
1405           __throw_exception_again;
1406         }
1407     }
1408
1409   template<typename K, typename V, 
1410            typename A, typename Ex, typename Eq,
1411            typename H1, typename H2, typename H, typename RP,
1412            bool c, bool ci, bool u>
1413     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>&
1414     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1415     operator=(const hashtable& ht)
1416     {
1417       hashtable tmp(ht);
1418       this->swap(tmp);
1419       return *this;
1420     }
1421
1422   template<typename K, typename V, 
1423            typename A, typename Ex, typename Eq,
1424            typename H1, typename H2, typename H, typename RP,
1425            bool c, bool ci, bool u>
1426     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1427     ~hashtable()
1428     {
1429       clear();
1430       m_deallocate_buckets(m_buckets, m_bucket_count);
1431     }
1432
1433   template<typename K, typename V, 
1434            typename A, typename Ex, typename Eq,
1435            typename H1, typename H2, typename H, typename RP,
1436            bool c, bool ci, bool u>
1437     void
1438     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1439     swap(hashtable& x)
1440     {
1441       // The only base class with member variables is hash_code_base.  We
1442       // define hash_code_base::m_swap because different specializations
1443       // have different members.
1444       Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c>::m_swap(x);
1445
1446       // open LWG issue 431
1447       // std::swap(m_node_allocator, x.m_node_allocator);
1448       std::swap(m_rehash_policy, x.m_rehash_policy);
1449       std::swap(m_buckets, x.m_buckets);
1450       std::swap(m_bucket_count, x.m_bucket_count);
1451       std::swap(m_element_count, x.m_element_count);
1452     }
1453
1454   template<typename K, typename V, 
1455            typename A, typename Ex, typename Eq,
1456            typename H1, typename H2, typename H, typename RP,
1457            bool c, bool ci, bool u>
1458     void
1459     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1460     rehash_policy(const RP& pol)
1461     {
1462       m_rehash_policy = pol;
1463       size_type n_bkt = pol.bkt_for_elements(m_element_count);
1464       if (n_bkt > m_bucket_count)
1465         m_rehash (n_bkt);
1466     }
1467
1468   template<typename K, typename V, 
1469            typename A, typename Ex, typename Eq,
1470            typename H1, typename H2, typename H, typename RP,
1471            bool c, bool ci, bool u>
1472     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
1473     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1474     find(const key_type& k)
1475     {
1476       typename hashtable::hash_code_t code = this->m_hash_code (k);
1477       std::size_t n = this->bucket_index(k, code, this->bucket_count());
1478       node* p = find_node (m_buckets[n], k, code);
1479       return p ? iterator(p, m_buckets + n) : this->end();
1480     }
1481   
1482   template<typename K, typename V, 
1483            typename A, typename Ex, typename Eq,
1484            typename H1, typename H2, typename H, typename RP,
1485            bool c, bool ci, bool u>
1486     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::const_iterator
1487     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1488     find(const key_type& k) const
1489     {
1490       typename hashtable::hash_code_t code = this->m_hash_code (k);
1491       std::size_t n = this->bucket_index(k, code, this->bucket_count());
1492       node* p = find_node (m_buckets[n], k, code);
1493       return p ? const_iterator(p, m_buckets + n) : this->end();
1494     }
1495   
1496   template<typename K, typename V, 
1497            typename A, typename Ex, typename Eq,
1498            typename H1, typename H2, typename H, typename RP,
1499            bool c, bool ci, bool u>
1500     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::size_type
1501     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1502     count(const key_type& k) const
1503     {
1504       typename hashtable::hash_code_t code = this->m_hash_code (k);
1505       std::size_t n = this->bucket_index (k, code, this->bucket_count());
1506       size_t result = 0;
1507       for (node* p = m_buckets[n]; p ; p = p->m_next)
1508         if (this->compare (k, code, p))
1509           ++result;
1510       return result;
1511     }
1512
1513   template<typename K, typename V, 
1514            typename A, typename Ex, typename Eq,
1515            typename H1, typename H2, typename H, typename RP,
1516            bool c, bool ci, bool u>
1517     std::pair<typename hashtable<K, V, A, Ex, Eq, H1,
1518                                  H2, H, RP, c, ci, u>::iterator,
1519               typename hashtable<K, V, A, Ex, Eq, H1,
1520                                  H2, H, RP, c, ci, u>::iterator>
1521     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1522     equal_range(const key_type& k)
1523     {
1524       typename hashtable::hash_code_t code = this->m_hash_code (k);
1525       std::size_t n = this->bucket_index(k, code, this->bucket_count());
1526       node** head = m_buckets + n;
1527       node* p = find_node (*head, k, code);
1528       
1529       if (p)
1530         {
1531           node* p1 = p->m_next;
1532           for (; p1 ; p1 = p1->m_next)
1533             if (!this->compare (k, code, p1))
1534               break;
1535
1536           iterator first(p, head);
1537           iterator last(p1, head);
1538           if (!p1)
1539             last.m_incr_bucket();
1540           return std::make_pair(first, last);
1541         }
1542       else
1543         return std::make_pair(this->end(), this->end());
1544     }
1545
1546   template<typename K, typename V, 
1547            typename A, typename Ex, typename Eq,
1548            typename H1, typename H2, typename H, typename RP,
1549            bool c, bool ci, bool u>
1550     std::pair<typename hashtable<K, V, A, Ex, Eq, H1,
1551                                  H2, H, RP, c, ci, u>::const_iterator,
1552               typename hashtable<K, V, A, Ex, Eq, H1,
1553                                  H2, H, RP, c, ci, u>::const_iterator>
1554     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1555     equal_range(const key_type& k) const
1556     {
1557       typename hashtable::hash_code_t code = this->m_hash_code (k);
1558       std::size_t n = this->bucket_index(k, code, this->bucket_count());
1559       node** head = m_buckets + n;
1560       node* p = find_node (*head, k, code);
1561
1562       if (p)
1563         {
1564           node* p1 = p->m_next;
1565           for (; p1 ; p1 = p1->m_next)
1566             if (!this->compare (k, code, p1))
1567               break;
1568
1569           const_iterator first(p, head);
1570           const_iterator last(p1, head);
1571           if (!p1)
1572             last.m_incr_bucket();
1573           return std::make_pair(first, last);
1574         }
1575       else
1576         return std::make_pair(this->end(), this->end());
1577     }
1578
1579   // Find the node whose key compares equal to k, beginning the search
1580   // at p (usually the head of a bucket).  Return nil if no node is found.
1581   template<typename K, typename V, 
1582            typename A, typename Ex, typename Eq,
1583            typename H1, typename H2, typename H, typename RP,
1584            bool c, bool ci, bool u>
1585     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::node* 
1586     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1587     find_node(node* p, const key_type& k,
1588               typename hashtable::hash_code_t code) const
1589     {
1590       for ( ; p ; p = p->m_next)
1591         if (this->compare (k, code, p))
1592           return p;
1593       return false;
1594     }
1595
1596   // Insert v if no element with its key is already present.
1597   template<typename K, typename V, 
1598            typename A, typename Ex, typename Eq,
1599            typename H1, typename H2, typename H, typename RP,
1600            bool c, bool ci, bool u>
1601     std::pair<typename hashtable<K, V, A, Ex, Eq, H1,
1602                                  H2, H, RP, c, ci, u>::iterator, bool>
1603     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1604     insert(const value_type& v, std::tr1::true_type)
1605     {
1606       const key_type& k = this->m_extract(v);
1607       typename hashtable::hash_code_t code = this->m_hash_code (k);
1608       size_type n = this->bucket_index(k, code, m_bucket_count);
1609       
1610       if (node* p = find_node(m_buckets[n], k, code))
1611         return std::make_pair(iterator(p, m_buckets + n), false);
1612
1613       std::pair<bool, size_t> do_rehash
1614         = m_rehash_policy.need_rehash(m_bucket_count, m_element_count, 1);
1615
1616       // Allocate the new node before doing the rehash so that we don't
1617       // do a rehash if the allocation throws.
1618       node* new_node = m_allocate_node (v);
1619       
1620       try
1621         {
1622           if (do_rehash.first)
1623             {
1624               n = this->bucket_index(k, code, do_rehash.second);
1625               m_rehash(do_rehash.second);
1626             }
1627
1628           new_node->m_next = m_buckets[n];
1629           this->store_code(new_node, code);
1630           m_buckets[n] = new_node;
1631           ++m_element_count;
1632           return std::make_pair(iterator(new_node, m_buckets + n), true);
1633         }
1634       catch (...)
1635         {
1636           m_deallocate_node (new_node);
1637           __throw_exception_again;
1638         }
1639     }
1640   
1641   // Insert v unconditionally.
1642   template<typename K, typename V, 
1643            typename A, typename Ex, typename Eq,
1644            typename H1, typename H2, typename H, typename RP,
1645            bool c, bool ci, bool u>
1646     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
1647     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1648     insert(const value_type& v, std::tr1::false_type)
1649     {
1650       std::pair<bool, std::size_t> do_rehash
1651         = m_rehash_policy.need_rehash(m_bucket_count, m_element_count, 1);
1652       if (do_rehash.first)
1653         m_rehash(do_rehash.second);
1654
1655       const key_type& k = this->m_extract(v);
1656       typename hashtable::hash_code_t code = this->m_hash_code (k);
1657       size_type n = this->bucket_index(k, code, m_bucket_count);
1658       
1659       node* new_node = m_allocate_node (v);
1660       node* prev = find_node(m_buckets[n], k, code);
1661       if (prev)
1662         {
1663           new_node->m_next = prev->m_next;
1664           prev->m_next = new_node;
1665         }
1666       else
1667         {
1668           new_node->m_next = m_buckets[n];
1669           m_buckets[n] = new_node;
1670         }
1671       this->store_code(new_node, code);
1672
1673       ++m_element_count;
1674       return iterator(new_node, m_buckets + n);
1675     }
1676
1677   // For erase(iterator) and erase(const_iterator).
1678   template<typename K, typename V, 
1679            typename A, typename Ex, typename Eq,
1680            typename H1, typename H2, typename H, typename RP,
1681            bool c, bool ci, bool u>
1682     void
1683     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1684     erase_node(node* p, node** b)
1685     {
1686       node* cur = *b;
1687       if (cur == p)
1688         *b = cur->m_next;
1689       else
1690         {
1691           node* next = cur->m_next;
1692           while (next != p)
1693             {
1694               cur = next;
1695               next = cur->m_next;
1696             }
1697           cur->m_next = next->m_next;
1698         }
1699
1700       m_deallocate_node (p);
1701       --m_element_count;
1702     }
1703
1704   template<typename K, typename V, 
1705            typename A, typename Ex, typename Eq,
1706            typename H1, typename H2, typename H, typename RP,
1707            bool c, bool ci, bool u>
1708     template<typename InIter>
1709       void 
1710       hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1711       insert(InIter first, InIter last)
1712       {
1713         size_type n_elt = Internal::distance_fw (first, last);
1714         std::pair<bool, std::size_t> do_rehash
1715           = m_rehash_policy.need_rehash(m_bucket_count, m_element_count, n_elt);
1716         if (do_rehash.first)
1717           m_rehash(do_rehash.second);
1718
1719         for (; first != last; ++first)
1720           this->insert (*first);
1721       }
1722
1723   template<typename K, typename V, 
1724            typename A, typename Ex, typename Eq,
1725            typename H1, typename H2, typename H, typename RP,
1726            bool c, bool ci, bool u>
1727     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
1728     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1729     erase(iterator i)
1730     {
1731       iterator result = i;
1732       ++result;
1733       erase_node(i.m_cur_node, i.m_cur_bucket);
1734       return result;
1735     }
1736   
1737   template<typename K, typename V, 
1738            typename A, typename Ex, typename Eq,
1739            typename H1, typename H2, typename H, typename RP,
1740            bool c, bool ci, bool u>
1741     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::const_iterator
1742     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1743     erase(const_iterator i)
1744     {
1745       const_iterator result = i;
1746       ++result;
1747       erase_node(i.m_cur_node, i.m_cur_bucket);
1748       return result;
1749     }
1750
1751   template<typename K, typename V, 
1752            typename A, typename Ex, typename Eq,
1753            typename H1, typename H2, typename H, typename RP,
1754            bool c, bool ci, bool u>
1755     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::size_type
1756     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1757     erase(const key_type& k)
1758     {
1759       typename hashtable::hash_code_t code = this->m_hash_code (k);
1760       size_type n = this->bucket_index(k, code, m_bucket_count);
1761       size_type result = 0;
1762       
1763       node** slot = m_buckets + n;
1764       while (*slot && ! this->compare (k, code, *slot))
1765         slot = &((*slot)->m_next);
1766
1767       while (*slot && this->compare (k, code, *slot))
1768         {
1769           node* n = *slot;
1770           *slot = n->m_next;
1771           m_deallocate_node (n);
1772           --m_element_count;
1773           ++result;
1774         }
1775
1776       return result;
1777     }
1778
1779   // ??? This could be optimized by taking advantage of the bucket
1780   // structure, but it's not clear that it's worth doing.  It probably
1781   // wouldn't even be an optimization unless the load factor is large.
1782   template<typename K, typename V, 
1783            typename A, typename Ex, typename Eq,
1784            typename H1, typename H2, typename H, typename RP,
1785            bool c, bool ci, bool u>
1786     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
1787     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1788     erase(iterator first, iterator last)
1789     {
1790       while (first != last)
1791         first = this->erase(first);
1792       return last;
1793     }
1794   
1795   template<typename K, typename V, 
1796            typename A, typename Ex, typename Eq,
1797            typename H1, typename H2, typename H, typename RP,
1798            bool c, bool ci, bool u>
1799     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::const_iterator
1800     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1801     erase(const_iterator first, const_iterator last)
1802     {
1803       while (first != last)
1804         first = this->erase(first);
1805       return last;
1806     }
1807
1808   template<typename K, typename V, 
1809            typename A, typename Ex, typename Eq,
1810            typename H1, typename H2, typename H, typename RP,
1811            bool c, bool ci, bool u>
1812     void
1813     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1814     clear()
1815     {
1816       m_deallocate_nodes(m_buckets, m_bucket_count);
1817       m_element_count = 0;
1818     }
1819
1820   template<typename K, typename V, 
1821            typename A, typename Ex, typename Eq,
1822            typename H1, typename H2, typename H, typename RP,
1823            bool c, bool ci, bool u>
1824     void
1825     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
1826     m_rehash(size_type N)
1827     {
1828       node** new_array = m_allocate_buckets (N);
1829       try
1830         {
1831           for (size_type i = 0; i < m_bucket_count; ++i)
1832             while (node* p = m_buckets[i])
1833               {
1834                 size_type new_index = this->bucket_index (p, N);
1835                 m_buckets[i] = p->m_next;
1836                 p->m_next = new_array[new_index];
1837                 new_array[new_index] = p;
1838               }
1839           m_deallocate_buckets(m_buckets, m_bucket_count);
1840           m_bucket_count = N;
1841           m_buckets = new_array;
1842         }
1843       catch (...)
1844         {
1845           // A failure here means that a hash function threw an exception.
1846           // We can't restore the previous state without calling the hash
1847           // function again, so the only sensible recovery is to delete
1848           // everything.
1849           m_deallocate_nodes(new_array, N);
1850           m_deallocate_buckets(new_array, N);
1851           m_deallocate_nodes(m_buckets, m_bucket_count);
1852           m_element_count = 0;
1853           __throw_exception_again;
1854         }
1855     }
1856
1857 _GLIBCXX_END_NAMESPACE
1858 }                               // Namespace std::tr1
1859
1860 #endif /* GNU_LIBSTDCXX_TR1_HASHTABLE_ */
1861