OSDN Git Service

projects clean up 1
[pinoc/pinoc.git] / test / Standart_startup / lib / include / c++ / 4.5-GNUH8_v10.03 / bits / hashtable_policy.h
1 // Internal policy header for unordered_set and unordered_map -*- C++ -*-
2
3 // Copyright (C) 2010 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /** @file bits/hashtable_policy.h
26  *  This is an internal header file, included by other library headers.
27  *  You should not attempt to use it directly.
28  */
29
30 #ifndef _HASHTABLE_POLICY_H
31 #define _HASHTABLE_POLICY_H 1
32
33 namespace std
34 {
35 namespace __detail
36 {
37   // Helper function: return distance(first, last) for forward
38   // iterators, or 0 for input iterators.
39   template<class _Iterator>
40     inline typename std::iterator_traits<_Iterator>::difference_type
41     __distance_fw(_Iterator __first, _Iterator __last,
42                   std::input_iterator_tag)
43     { return 0; }
44
45   template<class _Iterator>
46     inline typename std::iterator_traits<_Iterator>::difference_type
47     __distance_fw(_Iterator __first, _Iterator __last,
48                   std::forward_iterator_tag)
49     { return std::distance(__first, __last); }
50
51   template<class _Iterator>
52     inline typename std::iterator_traits<_Iterator>::difference_type
53     __distance_fw(_Iterator __first, _Iterator __last)
54     {
55       typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag;
56       return __distance_fw(__first, __last, _Tag());
57     }
58
59   // Auxiliary types used for all instantiations of _Hashtable: nodes
60   // and iterators.
61   
62   // Nodes, used to wrap elements stored in the hash table.  A policy
63   // template parameter of class template _Hashtable controls whether
64   // nodes also store a hash code. In some cases (e.g. strings) this
65   // may be a performance win.
66   template<typename _Value, bool __cache_hash_code>
67     struct _Hash_node;
68
69   template<typename _Value>
70     struct _Hash_node<_Value, true>
71     {
72       _Value       _M_v;
73       std::size_t  _M_hash_code;
74       _Hash_node*  _M_next;
75
76       template<typename... _Args>
77         _Hash_node(_Args&&... __args)
78         : _M_v(std::forward<_Args>(__args)...),
79           _M_hash_code(), _M_next() { }
80     };
81
82   template<typename _Value>
83     struct _Hash_node<_Value, false>
84     {
85       _Value       _M_v;
86       _Hash_node*  _M_next;
87
88       template<typename... _Args>
89         _Hash_node(_Args&&... __args)
90         : _M_v(std::forward<_Args>(__args)...),
91           _M_next() { }
92     };
93
94   // Local iterators, used to iterate within a bucket but not between
95   // buckets.
96   template<typename _Value, bool __cache>
97     struct _Node_iterator_base
98     {
99       _Node_iterator_base(_Hash_node<_Value, __cache>* __p)
100       : _M_cur(__p) { }
101       
102       void
103       _M_incr()
104       { _M_cur = _M_cur->_M_next; }
105
106       _Hash_node<_Value, __cache>*  _M_cur;
107     };
108
109   template<typename _Value, bool __cache>
110     inline bool
111     operator==(const _Node_iterator_base<_Value, __cache>& __x,
112                const _Node_iterator_base<_Value, __cache>& __y)
113     { return __x._M_cur == __y._M_cur; }
114
115   template<typename _Value, bool __cache>
116     inline bool
117     operator!=(const _Node_iterator_base<_Value, __cache>& __x,
118                const _Node_iterator_base<_Value, __cache>& __y)
119     { return __x._M_cur != __y._M_cur; }
120
121   template<typename _Value, bool __constant_iterators, bool __cache>
122     struct _Node_iterator
123     : public _Node_iterator_base<_Value, __cache>
124     {
125       typedef _Value                                   value_type;
126       typedef typename std::conditional<__constant_iterators,
127                                         const _Value*, _Value*>::type
128                                                        pointer;
129       typedef typename std::conditional<__constant_iterators,
130                                         const _Value&, _Value&>::type
131                                                        reference;
132       typedef std::ptrdiff_t                           difference_type;
133       typedef std::forward_iterator_tag                iterator_category;
134
135       _Node_iterator()
136       : _Node_iterator_base<_Value, __cache>(0) { }
137
138       explicit
139       _Node_iterator(_Hash_node<_Value, __cache>* __p)
140       : _Node_iterator_base<_Value, __cache>(__p) { }
141
142       reference
143       operator*() const
144       { return this->_M_cur->_M_v; }
145   
146       pointer
147       operator->() const
148       { return &this->_M_cur->_M_v; }
149
150       _Node_iterator&
151       operator++()
152       { 
153         this->_M_incr();
154         return *this; 
155       }
156   
157       _Node_iterator
158       operator++(int)
159       { 
160         _Node_iterator __tmp(*this);
161         this->_M_incr();
162         return __tmp;
163       }
164     };
165
166   template<typename _Value, bool __constant_iterators, bool __cache>
167     struct _Node_const_iterator
168     : public _Node_iterator_base<_Value, __cache>
169     {
170       typedef _Value                                   value_type;
171       typedef const _Value*                            pointer;
172       typedef const _Value&                            reference;
173       typedef std::ptrdiff_t                           difference_type;
174       typedef std::forward_iterator_tag                iterator_category;
175
176       _Node_const_iterator()
177       : _Node_iterator_base<_Value, __cache>(0) { }
178
179       explicit
180       _Node_const_iterator(_Hash_node<_Value, __cache>* __p)
181       : _Node_iterator_base<_Value, __cache>(__p) { }
182
183       _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators,
184                            __cache>& __x)
185       : _Node_iterator_base<_Value, __cache>(__x._M_cur) { }
186
187       reference
188       operator*() const
189       { return this->_M_cur->_M_v; }
190   
191       pointer
192       operator->() const
193       { return &this->_M_cur->_M_v; }
194
195       _Node_const_iterator&
196       operator++()
197       { 
198         this->_M_incr();
199         return *this; 
200       }
201   
202       _Node_const_iterator
203       operator++(int)
204       { 
205         _Node_const_iterator __tmp(*this);
206         this->_M_incr();
207         return __tmp;
208       }
209     };
210
211   template<typename _Value, bool __cache>
212     struct _Hashtable_iterator_base
213     {
214       _Hashtable_iterator_base(_Hash_node<_Value, __cache>* __node,
215                                _Hash_node<_Value, __cache>** __bucket)
216       : _M_cur_node(__node), _M_cur_bucket(__bucket) { }
217
218       void
219       _M_incr()
220       {
221         _M_cur_node = _M_cur_node->_M_next;
222         if (!_M_cur_node)
223           _M_incr_bucket();
224       }
225
226       void
227       _M_incr_bucket();
228
229       _Hash_node<_Value, __cache>*   _M_cur_node;
230       _Hash_node<_Value, __cache>**  _M_cur_bucket;
231     };
232
233   // Global iterators, used for arbitrary iteration within a hash
234   // table.  Larger and more expensive than local iterators.
235   template<typename _Value, bool __cache>
236     void
237     _Hashtable_iterator_base<_Value, __cache>::
238     _M_incr_bucket()
239     {
240       ++_M_cur_bucket;
241
242       // This loop requires the bucket array to have a non-null sentinel.
243       while (!*_M_cur_bucket)
244         ++_M_cur_bucket;
245       _M_cur_node = *_M_cur_bucket;
246     }
247
248   template<typename _Value, bool __cache>
249     inline bool
250     operator==(const _Hashtable_iterator_base<_Value, __cache>& __x,
251                const _Hashtable_iterator_base<_Value, __cache>& __y)
252     { return __x._M_cur_node == __y._M_cur_node; }
253
254   template<typename _Value, bool __cache>
255     inline bool
256     operator!=(const _Hashtable_iterator_base<_Value, __cache>& __x,
257                const _Hashtable_iterator_base<_Value, __cache>& __y)
258     { return __x._M_cur_node != __y._M_cur_node; }
259
260   template<typename _Value, bool __constant_iterators, bool __cache>
261     struct _Hashtable_iterator
262     : public _Hashtable_iterator_base<_Value, __cache>
263     {
264       typedef _Value                                   value_type;
265       typedef typename std::conditional<__constant_iterators,
266                                         const _Value*, _Value*>::type
267                                                        pointer;
268       typedef typename std::conditional<__constant_iterators,
269                                         const _Value&, _Value&>::type
270                                                        reference;
271       typedef std::ptrdiff_t                           difference_type;
272       typedef std::forward_iterator_tag                iterator_category;
273
274       _Hashtable_iterator()
275       : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
276
277       _Hashtable_iterator(_Hash_node<_Value, __cache>* __p,
278                           _Hash_node<_Value, __cache>** __b)
279       : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
280
281       explicit
282       _Hashtable_iterator(_Hash_node<_Value, __cache>** __b)
283       : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
284
285       reference
286       operator*() const
287       { return this->_M_cur_node->_M_v; }
288   
289       pointer
290       operator->() const
291       { return &this->_M_cur_node->_M_v; }
292
293       _Hashtable_iterator&
294       operator++()
295       { 
296         this->_M_incr();
297         return *this;
298       }
299   
300       _Hashtable_iterator
301       operator++(int)
302       { 
303         _Hashtable_iterator __tmp(*this);
304         this->_M_incr();
305         return __tmp;
306       }
307     };
308
309   template<typename _Value, bool __constant_iterators, bool __cache>
310     struct _Hashtable_const_iterator
311     : public _Hashtable_iterator_base<_Value, __cache>
312     {
313       typedef _Value                                   value_type;
314       typedef const _Value*                            pointer;
315       typedef const _Value&                            reference;
316       typedef std::ptrdiff_t                           difference_type;
317       typedef std::forward_iterator_tag                iterator_category;
318
319       _Hashtable_const_iterator()
320       : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
321
322       _Hashtable_const_iterator(_Hash_node<_Value, __cache>* __p,
323                                 _Hash_node<_Value, __cache>** __b)
324       : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
325
326       explicit
327       _Hashtable_const_iterator(_Hash_node<_Value, __cache>** __b)
328       : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
329
330       _Hashtable_const_iterator(const _Hashtable_iterator<_Value,
331                                 __constant_iterators, __cache>& __x)
332       : _Hashtable_iterator_base<_Value, __cache>(__x._M_cur_node,
333                                                   __x._M_cur_bucket) { }
334
335       reference
336       operator*() const
337       { return this->_M_cur_node->_M_v; }
338   
339       pointer
340       operator->() const
341       { return &this->_M_cur_node->_M_v; }
342
343       _Hashtable_const_iterator&
344       operator++()
345       { 
346         this->_M_incr();
347         return *this;
348       }
349   
350       _Hashtable_const_iterator
351       operator++(int)
352       { 
353         _Hashtable_const_iterator __tmp(*this);
354         this->_M_incr();
355         return __tmp;
356       }
357     };
358
359
360   // Many of class template _Hashtable's template parameters are policy
361   // classes.  These are defaults for the policies.
362
363   // Default range hashing function: use division to fold a large number
364   // into the range [0, N).
365   struct _Mod_range_hashing
366   {
367     typedef std::size_t first_argument_type;
368     typedef std::size_t second_argument_type;
369     typedef std::size_t result_type;
370
371     result_type
372     operator()(first_argument_type __num, second_argument_type __den) const
373     { return __num % __den; }
374   };
375
376   // Default ranged hash function H.  In principle it should be a
377   // function object composed from objects of type H1 and H2 such that
378   // h(k, N) = h2(h1(k), N), but that would mean making extra copies of
379   // h1 and h2.  So instead we'll just use a tag to tell class template
380   // hashtable to do that composition.
381   struct _Default_ranged_hash { };
382
383   // Default value for rehash policy.  Bucket size is (usually) the
384   // smallest prime that keeps the load factor small enough.
385   struct _Prime_rehash_policy
386   {
387     _Prime_rehash_policy(float __z = 1.0)
388     : _M_max_load_factor(__z), _M_growth_factor(2.f), _M_next_resize(0) { }
389
390     float
391     max_load_factor() const
392     { return _M_max_load_factor; }      
393
394     // Return a bucket size no smaller than n.
395     std::size_t
396     _M_next_bkt(std::size_t __n) const;
397     
398     // Return a bucket count appropriate for n elements
399     std::size_t
400     _M_bkt_for_elements(std::size_t __n) const;
401     
402     // __n_bkt is current bucket count, __n_elt is current element count,
403     // and __n_ins is number of elements to be inserted.  Do we need to
404     // increase bucket count?  If so, return make_pair(true, n), where n
405     // is the new bucket count.  If not, return make_pair(false, 0).
406     std::pair<bool, std::size_t>
407     _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
408                    std::size_t __n_ins) const;
409
410     enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 };
411
412     float                _M_max_load_factor;
413     float                _M_growth_factor;
414     mutable std::size_t  _M_next_resize;
415   };
416
417   extern const unsigned long __prime_list[];
418
419   // XXX This is a hack.  There's no good reason for any of
420   // _Prime_rehash_policy's member functions to be inline.  
421
422   // Return a prime no smaller than n.
423   inline std::size_t
424   _Prime_rehash_policy::
425   _M_next_bkt(std::size_t __n) const
426   {
427     const unsigned long* __p = std::lower_bound(__prime_list, __prime_list
428                                                 + _S_n_primes, __n);
429     _M_next_resize = 
430       static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
431     return *__p;
432   }
433
434   // Return the smallest prime p such that alpha p >= n, where alpha
435   // is the load factor.
436   inline std::size_t
437   _Prime_rehash_policy::
438   _M_bkt_for_elements(std::size_t __n) const
439   {
440     const float __min_bkts = __n / _M_max_load_factor;
441     const unsigned long* __p = std::lower_bound(__prime_list, __prime_list
442                                                 + _S_n_primes, __min_bkts);
443     _M_next_resize =
444       static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
445     return *__p;
446   }
447
448   // Finds the smallest prime p such that alpha p > __n_elt + __n_ins.
449   // If p > __n_bkt, return make_pair(true, p); otherwise return
450   // make_pair(false, 0).  In principle this isn't very different from 
451   // _M_bkt_for_elements.
452
453   // The only tricky part is that we're caching the element count at
454   // which we need to rehash, so we don't have to do a floating-point
455   // multiply for every insertion.
456
457   inline std::pair<bool, std::size_t>
458   _Prime_rehash_policy::
459   _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
460                  std::size_t __n_ins) const
461   {
462     if (__n_elt + __n_ins > _M_next_resize)
463       {
464         float __min_bkts = ((float(__n_ins) + float(__n_elt))
465                             / _M_max_load_factor);
466         if (__min_bkts > __n_bkt)
467           {
468             __min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt);
469             const unsigned long* __p =
470               std::lower_bound(__prime_list, __prime_list + _S_n_primes,
471                                __min_bkts);
472             _M_next_resize = static_cast<std::size_t>
473               (__builtin_ceil(*__p * _M_max_load_factor));
474             return std::make_pair(true, *__p);
475           }
476         else 
477           {
478             _M_next_resize = static_cast<std::size_t>
479               (__builtin_ceil(__n_bkt * _M_max_load_factor));
480             return std::make_pair(false, 0);
481           }
482       }
483     else
484       return std::make_pair(false, 0);
485   }
486
487   // Base classes for std::_Hashtable.  We define these base classes
488   // because in some cases we want to do different things depending
489   // on the value of a policy class.  In some cases the policy class
490   // affects which member functions and nested typedefs are defined;
491   // we handle that by specializing base class templates.  Several of
492   // the base class templates need to access other members of class
493   // template _Hashtable, so we use the "curiously recurring template
494   // pattern" for them.
495
496   // class template _Map_base.  If the hashtable has a value type of
497   // the form pair<T1, T2> and a key extraction policy that returns the
498   // first part of the pair, the hashtable gets a mapped_type typedef.
499   // If it satisfies those criteria and also has unique keys, then it
500   // also gets an operator[].  
501   template<typename _Key, typename _Value, typename _Ex, bool __unique,
502            typename _Hashtable>
503     struct _Map_base { };
504
505   template<typename _Key, typename _Pair, typename _Hashtable>
506     struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, false, _Hashtable>
507     {
508       typedef typename _Pair::second_type mapped_type;
509     };
510
511   template<typename _Key, typename _Pair, typename _Hashtable>
512     struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>
513     {
514       typedef typename _Pair::second_type mapped_type;
515
516       mapped_type&
517       operator[](const _Key& __k);
518
519       // _GLIBCXX_RESOLVE_LIB_DEFECTS
520       // DR 761. unordered_map needs an at() member function.
521       mapped_type&
522       at(const _Key& __k);
523
524       const mapped_type&
525       at(const _Key& __k) const;
526     };
527
528   template<typename _Key, typename _Pair, typename _Hashtable>
529     typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
530                        true, _Hashtable>::mapped_type&
531     _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
532     operator[](const _Key& __k)
533     {
534       _Hashtable* __h = static_cast<_Hashtable*>(this);
535       typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
536       std::size_t __n = __h->_M_bucket_index(__k, __code,
537                                              __h->_M_bucket_count);
538
539       typename _Hashtable::_Node* __p =
540         __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
541       if (!__p)
542         return __h->_M_insert_bucket(std::make_pair(__k, mapped_type()),
543                                      __n, __code)->second;
544       return (__p->_M_v).second;
545     }
546
547   template<typename _Key, typename _Pair, typename _Hashtable>
548     typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
549                        true, _Hashtable>::mapped_type&
550     _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
551     at(const _Key& __k)
552     {
553       _Hashtable* __h = static_cast<_Hashtable*>(this);
554       typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
555       std::size_t __n = __h->_M_bucket_index(__k, __code,
556                                              __h->_M_bucket_count);
557
558       typename _Hashtable::_Node* __p =
559         __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
560       if (!__p)
561         __throw_out_of_range(__N("_Map_base::at"));
562       return (__p->_M_v).second;
563     }
564
565   template<typename _Key, typename _Pair, typename _Hashtable>
566     const typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
567                              true, _Hashtable>::mapped_type&
568     _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
569     at(const _Key& __k) const
570     {
571       const _Hashtable* __h = static_cast<const _Hashtable*>(this);
572       typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
573       std::size_t __n = __h->_M_bucket_index(__k, __code,
574                                              __h->_M_bucket_count);
575
576       typename _Hashtable::_Node* __p =
577         __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
578       if (!__p)
579         __throw_out_of_range(__N("_Map_base::at"));
580       return (__p->_M_v).second;
581     }
582
583   // class template _Rehash_base.  Give hashtable the max_load_factor
584   // functions and reserve iff the rehash policy is _Prime_rehash_policy.
585   template<typename _RehashPolicy, typename _Hashtable>
586     struct _Rehash_base { };
587
588   template<typename _Hashtable>
589     struct _Rehash_base<_Prime_rehash_policy, _Hashtable>
590     {
591       float
592       max_load_factor() const
593       {
594         const _Hashtable* __this = static_cast<const _Hashtable*>(this);
595         return __this->__rehash_policy().max_load_factor();
596       }
597
598       void
599       max_load_factor(float __z)
600       {
601         _Hashtable* __this = static_cast<_Hashtable*>(this);
602         __this->__rehash_policy(_Prime_rehash_policy(__z));
603       }
604
605       void
606       reserve(std::size_t __n)
607       {
608         _Hashtable* __this = static_cast<_Hashtable*>(this);
609         __this->rehash(__builtin_ceil(__n / max_load_factor()));
610       }
611     };
612
613   // Class template _Hash_code_base.  Encapsulates two policy issues that
614   // aren't quite orthogonal.
615   //   (1) the difference between using a ranged hash function and using
616   //       the combination of a hash function and a range-hashing function.
617   //       In the former case we don't have such things as hash codes, so
618   //       we have a dummy type as placeholder.
619   //   (2) Whether or not we cache hash codes.  Caching hash codes is
620   //       meaningless if we have a ranged hash function.
621   // We also put the key extraction and equality comparison function 
622   // objects here, for convenience.
623   
624   // Primary template: unused except as a hook for specializations.  
625   template<typename _Key, typename _Value,
626            typename _ExtractKey, typename _Equal,
627            typename _H1, typename _H2, typename _Hash,
628            bool __cache_hash_code>
629     struct _Hash_code_base;
630
631   // Specialization: ranged hash function, no caching hash codes.  H1
632   // and H2 are provided but ignored.  We define a dummy hash code type.
633   template<typename _Key, typename _Value,
634            typename _ExtractKey, typename _Equal,
635            typename _H1, typename _H2, typename _Hash>
636     struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
637                            _Hash, false>
638     {
639     protected:
640       _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
641                       const _H1&, const _H2&, const _Hash& __h)
642       : _M_extract(__ex), _M_eq(__eq), _M_ranged_hash(__h) { }
643
644       typedef void* _Hash_code_type;
645   
646       _Hash_code_type
647       _M_hash_code(const _Key& __key) const
648       { return 0; }
649   
650       std::size_t
651       _M_bucket_index(const _Key& __k, _Hash_code_type,
652                       std::size_t __n) const
653       { return _M_ranged_hash(__k, __n); }
654
655       std::size_t
656       _M_bucket_index(const _Hash_node<_Value, false>* __p,
657                       std::size_t __n) const
658       { return _M_ranged_hash(_M_extract(__p->_M_v), __n); }
659   
660       bool
661       _M_compare(const _Key& __k, _Hash_code_type,
662                  _Hash_node<_Value, false>* __n) const
663       { return _M_eq(__k, _M_extract(__n->_M_v)); }
664
665       void
666       _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
667       { }
668
669       void
670       _M_copy_code(_Hash_node<_Value, false>*,
671                    const _Hash_node<_Value, false>*) const
672       { }
673       
674       void
675       _M_swap(_Hash_code_base& __x)
676       {
677         std::swap(_M_extract, __x._M_extract);
678         std::swap(_M_eq, __x._M_eq);
679         std::swap(_M_ranged_hash, __x._M_ranged_hash);
680       }
681
682     protected:
683       _ExtractKey  _M_extract;
684       _Equal       _M_eq;
685       _Hash        _M_ranged_hash;
686     };
687
688
689   // No specialization for ranged hash function while caching hash codes.
690   // That combination is meaningless, and trying to do it is an error.
691   
692   
693   // Specialization: ranged hash function, cache hash codes.  This
694   // combination is meaningless, so we provide only a declaration
695   // and no definition.  
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, true>;
701
702   // Specialization: hash function and range-hashing function, no
703   // caching of hash codes.  H is provided but ignored.  Provides
704   // typedef and accessor required by TR1.  
705   template<typename _Key, typename _Value,
706            typename _ExtractKey, typename _Equal,
707            typename _H1, typename _H2>
708     struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
709                            _Default_ranged_hash, false>
710     {
711       typedef _H1 hasher;
712
713       hasher
714       hash_function() const
715       { return _M_h1; }
716
717     protected:
718       _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
719                       const _H1& __h1, const _H2& __h2,
720                       const _Default_ranged_hash&)
721       : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
722
723       typedef std::size_t _Hash_code_type;
724
725       _Hash_code_type
726       _M_hash_code(const _Key& __k) const
727       { return _M_h1(__k); }
728       
729       std::size_t
730       _M_bucket_index(const _Key&, _Hash_code_type __c,
731                       std::size_t __n) const
732       { return _M_h2(__c, __n); }
733
734       std::size_t
735       _M_bucket_index(const _Hash_node<_Value, false>* __p,
736                       std::size_t __n) const
737       { return _M_h2(_M_h1(_M_extract(__p->_M_v)), __n); }
738
739       bool
740       _M_compare(const _Key& __k, _Hash_code_type,
741                  _Hash_node<_Value, false>* __n) const
742       { return _M_eq(__k, _M_extract(__n->_M_v)); }
743
744       void
745       _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
746       { }
747
748       void
749       _M_copy_code(_Hash_node<_Value, false>*,
750                    const _Hash_node<_Value, false>*) const
751       { }
752
753       void
754       _M_swap(_Hash_code_base& __x)
755       {
756         std::swap(_M_extract, __x._M_extract);
757         std::swap(_M_eq, __x._M_eq);
758         std::swap(_M_h1, __x._M_h1);
759         std::swap(_M_h2, __x._M_h2);
760       }
761
762     protected:
763       _ExtractKey  _M_extract;
764       _Equal       _M_eq;
765       _H1          _M_h1;
766       _H2          _M_h2;
767     };
768
769   // Specialization: hash function and range-hashing function, 
770   // caching hash codes.  H is provided but ignored.  Provides
771   // typedef and accessor required by TR1.
772   template<typename _Key, typename _Value,
773            typename _ExtractKey, typename _Equal,
774            typename _H1, typename _H2>
775     struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
776                            _Default_ranged_hash, true>
777     {
778       typedef _H1 hasher;
779       
780       hasher
781       hash_function() const
782       { return _M_h1; }
783
784     protected:
785       _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
786                       const _H1& __h1, const _H2& __h2,
787                       const _Default_ranged_hash&)
788       : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
789
790       typedef std::size_t _Hash_code_type;
791   
792       _Hash_code_type
793       _M_hash_code(const _Key& __k) const
794       { return _M_h1(__k); }
795   
796       std::size_t
797       _M_bucket_index(const _Key&, _Hash_code_type __c,
798                       std::size_t __n) const
799       { return _M_h2(__c, __n); }
800
801       std::size_t
802       _M_bucket_index(const _Hash_node<_Value, true>* __p,
803                       std::size_t __n) const
804       { return _M_h2(__p->_M_hash_code, __n); }
805
806       bool
807       _M_compare(const _Key& __k, _Hash_code_type __c,
808                  _Hash_node<_Value, true>* __n) const
809       { return __c == __n->_M_hash_code && _M_eq(__k, _M_extract(__n->_M_v)); }
810
811       void
812       _M_store_code(_Hash_node<_Value, true>* __n, _Hash_code_type __c) const
813       { __n->_M_hash_code = __c; }
814
815       void
816       _M_copy_code(_Hash_node<_Value, true>* __to,
817                    const _Hash_node<_Value, true>* __from) const
818       { __to->_M_hash_code = __from->_M_hash_code; }
819
820       void
821       _M_swap(_Hash_code_base& __x)
822       {
823         std::swap(_M_extract, __x._M_extract);
824         std::swap(_M_eq, __x._M_eq);
825         std::swap(_M_h1, __x._M_h1);
826         std::swap(_M_h2, __x._M_h2);
827       }
828       
829     protected:
830       _ExtractKey  _M_extract;
831       _Equal       _M_eq;
832       _H1          _M_h1;
833       _H2          _M_h2;
834     };
835
836
837   // Class template _Equality_base.  This is for implementing equality
838   // comparison for unordered containers, per N3068, by John Lakos and
839   // Pablo Halpern.  Algorithmically, we follow closely the reference
840   // implementations therein.
841   template<typename _ExtractKey, bool __unique_keys,
842            typename _Hashtable>
843     struct _Equality_base;
844
845   template<typename _ExtractKey, typename _Hashtable>
846     struct _Equality_base<_ExtractKey, true, _Hashtable>
847     {
848       bool _M_equal(const _Hashtable&) const;
849     };
850
851   template<typename _ExtractKey, typename _Hashtable>
852     bool
853     _Equality_base<_ExtractKey, true, _Hashtable>::
854     _M_equal(const _Hashtable& __other) const
855     {
856       const _Hashtable* __this = static_cast<const _Hashtable*>(this);
857
858       if (__this->size() != __other.size())
859         return false;
860
861       for (auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
862         {
863           const auto __ity = __other.find(_ExtractKey()(*__itx));
864           if (__ity == __other.end() || *__ity != *__itx)
865             return false;
866         }
867       return true;
868     }
869
870   template<typename _ExtractKey, typename _Hashtable>
871     struct _Equality_base<_ExtractKey, false, _Hashtable>
872     {
873       bool _M_equal(const _Hashtable&) const;
874
875     private:
876       template<typename _Uiterator>
877         static bool
878         _S_is_permutation(_Uiterator, _Uiterator, _Uiterator);
879     };
880
881   // See std::is_permutation in N3068.
882   template<typename _ExtractKey, typename _Hashtable>
883     template<typename _Uiterator>
884       bool
885       _Equality_base<_ExtractKey, false, _Hashtable>::
886       _S_is_permutation(_Uiterator __first1, _Uiterator __last1,
887                         _Uiterator __first2)
888       {
889         for (; __first1 != __last1; ++__first1, ++__first2)
890           if (!(*__first1 == *__first2))
891             break;
892
893         if (__first1 == __last1)
894           return true;
895
896         _Uiterator __last2 = __first2;
897         std::advance(__last2, std::distance(__first1, __last1));
898
899         for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1)
900           {
901             _Uiterator __tmp =  __first1;
902             while (__tmp != __it1 && !(*__tmp == *__it1))
903               ++__tmp;
904
905             // We've seen this one before.
906             if (__tmp != __it1)
907               continue;
908
909             std::ptrdiff_t __n2 = 0;
910             for (__tmp = __first2; __tmp != __last2; ++__tmp)
911               if (*__tmp == *__it1)
912                 ++__n2;
913
914             if (!__n2)
915               return false;
916
917             std::ptrdiff_t __n1 = 0;
918             for (__tmp = __it1; __tmp != __last1; ++__tmp)
919               if (*__tmp == *__it1)
920                 ++__n1;
921
922             if (__n1 != __n2)
923               return false;
924           }
925         return true;
926       }
927
928   template<typename _ExtractKey, typename _Hashtable>
929     bool
930     _Equality_base<_ExtractKey, false, _Hashtable>::
931     _M_equal(const _Hashtable& __other) const
932     {
933       const _Hashtable* __this = static_cast<const _Hashtable*>(this);
934
935       if (__this->size() != __other.size())
936         return false;
937
938       for (auto __itx = __this->begin(); __itx != __this->end();)
939         {
940           const auto __xrange = __this->equal_range(_ExtractKey()(*__itx));
941           const auto __yrange = __other.equal_range(_ExtractKey()(*__itx));
942
943           if (std::distance(__xrange.first, __xrange.second)
944               != std::distance(__yrange.first, __yrange.second))
945             return false;
946
947           if (!_S_is_permutation(__xrange.first,
948                                  __xrange.second,
949                                  __yrange.first))
950             return false;
951
952           __itx = __xrange.second;
953         }
954       return true;
955     }
956 } // namespace __detail
957 }
958
959 #endif // _HASHTABLE_POLICY_H