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