williamr@4
|
1 |
/*
|
williamr@4
|
2 |
*
|
williamr@4
|
3 |
*
|
williamr@4
|
4 |
* Copyright (c) 1994
|
williamr@4
|
5 |
* Hewlett-Packard Company
|
williamr@4
|
6 |
*
|
williamr@4
|
7 |
* Copyright (c) 1996,1997
|
williamr@4
|
8 |
* Silicon Graphics Computer Systems, Inc.
|
williamr@4
|
9 |
*
|
williamr@4
|
10 |
* Copyright (c) 1997
|
williamr@4
|
11 |
* Moscow Center for SPARC Technology
|
williamr@4
|
12 |
*
|
williamr@4
|
13 |
* Copyright (c) 1999
|
williamr@4
|
14 |
* Boris Fomitchev
|
williamr@4
|
15 |
*
|
williamr@4
|
16 |
* This material is provided "as is", with absolutely no warranty expressed
|
williamr@4
|
17 |
* or implied. Any use is at your own risk.
|
williamr@4
|
18 |
*
|
williamr@4
|
19 |
* Permission to use or copy this software for any purpose is hereby granted
|
williamr@4
|
20 |
* without fee, provided the above notices are retained on all copies.
|
williamr@4
|
21 |
* Permission to modify the code and to distribute modified code is granted,
|
williamr@4
|
22 |
* provided the above notices are retained, and a notice that the code was
|
williamr@4
|
23 |
* modified is included with the above copyright notice.
|
williamr@4
|
24 |
*
|
williamr@4
|
25 |
*/
|
williamr@4
|
26 |
#ifndef _STLP_HASHTABLE_C
|
williamr@4
|
27 |
#define _STLP_HASHTABLE_C
|
williamr@4
|
28 |
|
williamr@4
|
29 |
#ifndef _STLP_INTERNAL_HASHTABLE_H
|
williamr@4
|
30 |
# include <stl/_hashtable.h>
|
williamr@4
|
31 |
#endif
|
williamr@4
|
32 |
|
williamr@4
|
33 |
#ifdef _STLP_DEBUG
|
williamr@4
|
34 |
# define hashtable __WORKAROUND_DBG_RENAME(hashtable)
|
williamr@4
|
35 |
#endif
|
williamr@4
|
36 |
|
williamr@4
|
37 |
_STLP_BEGIN_NAMESPACE
|
williamr@4
|
38 |
|
williamr@4
|
39 |
# define __PRIME_LIST_BODY { \
|
williamr@4
|
40 |
53ul, 97ul, 193ul, 389ul, 769ul, \
|
williamr@4
|
41 |
1543ul, 3079ul, 6151ul, 12289ul, 24593ul, \
|
williamr@4
|
42 |
49157ul, 98317ul, 196613ul, 393241ul, 786433ul, \
|
williamr@4
|
43 |
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, \
|
williamr@4
|
44 |
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,\
|
williamr@4
|
45 |
1610612741ul, 3221225473ul, 4294967291ul \
|
williamr@4
|
46 |
}
|
williamr@4
|
47 |
|
williamr@4
|
48 |
#if ( _STLP_STATIC_TEMPLATE_DATA > 0 )
|
williamr@4
|
49 |
template <class _Tp>
|
williamr@4
|
50 |
const size_t _Stl_prime<_Tp>::_M_list[__stl_num_primes] = __PRIME_LIST_BODY;
|
williamr@4
|
51 |
#else
|
williamr@4
|
52 |
__DECLARE_INSTANCE(const size_t,
|
williamr@4
|
53 |
_Stl_prime_type::_M_list[], =__PRIME_LIST_BODY);
|
williamr@4
|
54 |
#endif /* _STLP_STATIC_TEMPLATE_DATA */
|
williamr@4
|
55 |
|
williamr@4
|
56 |
# undef __PRIME_LIST_BODY
|
williamr@4
|
57 |
|
williamr@4
|
58 |
// fbp: these defines are for outline methods definitions.
|
williamr@4
|
59 |
// needed to definitions to be portable. Should not be used in method bodies.
|
williamr@4
|
60 |
|
williamr@4
|
61 |
# if defined ( _STLP_NESTED_TYPE_PARAM_BUG )
|
williamr@4
|
62 |
# define __size_type__ size_t
|
williamr@4
|
63 |
# define size_type size_t
|
williamr@4
|
64 |
# define value_type _Val
|
williamr@4
|
65 |
# define key_type _Key
|
williamr@4
|
66 |
# define _Node _Hashtable_node<_Val>
|
williamr@4
|
67 |
# define __reference__ _Val&
|
williamr@4
|
68 |
|
williamr@4
|
69 |
# define __iterator__ _Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All>
|
williamr@4
|
70 |
# define __const_iterator__ _Ht_iterator<_Val, _Const_traits<_Val>, _Key, _HF, _ExK, _EqK, _All>
|
williamr@4
|
71 |
# else
|
williamr@4
|
72 |
# define __size_type__ _STLP_TYPENAME_ON_RETURN_TYPE hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>::size_type
|
williamr@4
|
73 |
# define __reference__ _STLP_TYPENAME_ON_RETURN_TYPE hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>::reference
|
williamr@4
|
74 |
# define __iterator__ _STLP_TYPENAME_ON_RETURN_TYPE hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>::iterator
|
williamr@4
|
75 |
# endif
|
williamr@4
|
76 |
|
williamr@4
|
77 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
|
williamr@4
|
78 |
class _All>
|
williamr@4
|
79 |
_Hashtable_node<_Val>*
|
williamr@4
|
80 |
_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::_M_skip_to_next() {
|
williamr@4
|
81 |
size_t __bucket = _M_ht->_M_bkt_num(_M_cur->_M_val);
|
williamr@4
|
82 |
size_t __h_sz;
|
williamr@4
|
83 |
__h_sz = this->_M_ht->bucket_count();
|
williamr@4
|
84 |
|
williamr@4
|
85 |
_Node* __i=0;
|
williamr@4
|
86 |
while (__i==0 && ++__bucket < __h_sz)
|
williamr@4
|
87 |
__i = (_Node*)_M_ht->_M_buckets[__bucket];
|
williamr@4
|
88 |
return __i;
|
williamr@4
|
89 |
}
|
williamr@4
|
90 |
|
williamr@4
|
91 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
|
williamr@4
|
92 |
class _All>
|
williamr@4
|
93 |
__size_type__
|
williamr@4
|
94 |
hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::_M_next_size(size_type __n) const {
|
williamr@4
|
95 |
const size_type* __first = (const size_type*)_Stl_prime_type::_M_list;
|
williamr@4
|
96 |
const size_type* __last = (const size_type*)_Stl_prime_type::_M_list + (int)__stl_num_primes;
|
williamr@4
|
97 |
const size_type* pos = __lower_bound(__first, __last, __n, __less((size_type*)0), (ptrdiff_t*)0);
|
williamr@4
|
98 |
return (pos == __last ? *(__last - 1) : *pos);
|
williamr@4
|
99 |
}
|
williamr@4
|
100 |
|
williamr@4
|
101 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
102 |
bool
|
williamr@4
|
103 |
hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::_M_equal(
|
williamr@4
|
104 |
const hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>& __ht1,
|
williamr@4
|
105 |
const hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>& __ht2)
|
williamr@4
|
106 |
{
|
williamr@4
|
107 |
// typedef _Hashtable_node<_Val> _Node;
|
williamr@4
|
108 |
if (__ht1.bucket_count() != __ht2.bucket_count())
|
williamr@4
|
109 |
return false;
|
williamr@4
|
110 |
for (size_t __n = 0; __n < __ht1.bucket_count(); ++__n) {
|
williamr@4
|
111 |
const _Node* __cur1 = __ht1._M_get_bucket(__n);
|
williamr@4
|
112 |
const _Node* __cur2 = __ht2._M_get_bucket(__n);
|
williamr@4
|
113 |
for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val;
|
williamr@4
|
114 |
__cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
|
williamr@4
|
115 |
{}
|
williamr@4
|
116 |
if (__cur1 || __cur2)
|
williamr@4
|
117 |
return false;
|
williamr@4
|
118 |
}
|
williamr@4
|
119 |
return true;
|
williamr@4
|
120 |
}
|
williamr@4
|
121 |
|
williamr@4
|
122 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
123 |
pair< _Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All> , bool>
|
williamr@4
|
124 |
hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
|
williamr@4
|
125 |
::insert_unique_noresize(const value_type& __obj)
|
williamr@4
|
126 |
{
|
williamr@4
|
127 |
const size_type __n = _M_bkt_num(__obj);
|
williamr@4
|
128 |
_Node* __first = (_Node*)_M_buckets[__n];
|
williamr@4
|
129 |
|
williamr@4
|
130 |
for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
|
williamr@4
|
131 |
if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
|
williamr@4
|
132 |
return pair<iterator, bool>(iterator(__cur, this), false);
|
williamr@4
|
133 |
|
williamr@4
|
134 |
_Node* __tmp = _M_new_node(__obj);
|
williamr@4
|
135 |
__tmp->_M_next = __first;
|
williamr@4
|
136 |
_M_buckets[__n] = __tmp;
|
williamr@4
|
137 |
++_M_num_elements._M_data;
|
williamr@4
|
138 |
return pair<iterator, bool>(iterator(__tmp, this), true);
|
williamr@4
|
139 |
}
|
williamr@4
|
140 |
|
williamr@4
|
141 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
142 |
__iterator__
|
williamr@4
|
143 |
hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
|
williamr@4
|
144 |
::insert_equal_noresize(const value_type& __obj)
|
williamr@4
|
145 |
{
|
williamr@4
|
146 |
const size_type __n = _M_bkt_num(__obj);
|
williamr@4
|
147 |
_Node* __first = (_Node*)_M_buckets[__n];
|
williamr@4
|
148 |
|
williamr@4
|
149 |
for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
|
williamr@4
|
150 |
if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
|
williamr@4
|
151 |
_Node* __tmp = _M_new_node(__obj);
|
williamr@4
|
152 |
__tmp->_M_next = __cur->_M_next;
|
williamr@4
|
153 |
__cur->_M_next = __tmp;
|
williamr@4
|
154 |
++_M_num_elements._M_data;
|
williamr@4
|
155 |
return iterator(__tmp, this);
|
williamr@4
|
156 |
}
|
williamr@4
|
157 |
|
williamr@4
|
158 |
_Node* __tmp = _M_new_node(__obj);
|
williamr@4
|
159 |
__tmp->_M_next = __first;
|
williamr@4
|
160 |
_M_buckets[__n] = __tmp;
|
williamr@4
|
161 |
++_M_num_elements._M_data;
|
williamr@4
|
162 |
return iterator(__tmp, this);
|
williamr@4
|
163 |
}
|
williamr@4
|
164 |
|
williamr@4
|
165 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
166 |
__reference__
|
williamr@4
|
167 |
hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::_M_insert(const value_type& __obj)
|
williamr@4
|
168 |
{
|
williamr@4
|
169 |
resize(_M_num_elements._M_data + 1);
|
williamr@4
|
170 |
|
williamr@4
|
171 |
size_type __n = _M_bkt_num(__obj);
|
williamr@4
|
172 |
_Node* __first = (_Node*)_M_buckets[__n];
|
williamr@4
|
173 |
|
williamr@4
|
174 |
_Node* __tmp = _M_new_node(__obj);
|
williamr@4
|
175 |
__tmp->_M_next = __first;
|
williamr@4
|
176 |
_M_buckets[__n] = __tmp;
|
williamr@4
|
177 |
++_M_num_elements._M_data;
|
williamr@4
|
178 |
return __tmp->_M_val;
|
williamr@4
|
179 |
}
|
williamr@4
|
180 |
|
williamr@4
|
181 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
182 |
__reference__
|
williamr@4
|
183 |
hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::find_or_insert(const value_type& __obj)
|
williamr@4
|
184 |
{
|
williamr@4
|
185 |
|
williamr@4
|
186 |
_Node* __first = _M_find(_M_get_key(__obj));
|
williamr@4
|
187 |
if (__first)
|
williamr@4
|
188 |
return __first->_M_val;
|
williamr@4
|
189 |
else
|
williamr@4
|
190 |
return _M_insert(__obj);
|
williamr@4
|
191 |
}
|
williamr@4
|
192 |
|
williamr@4
|
193 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
194 |
pair< _Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All>,
|
williamr@4
|
195 |
_Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All> >
|
williamr@4
|
196 |
hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::equal_range(const key_type& __key)
|
williamr@4
|
197 |
{
|
williamr@4
|
198 |
typedef pair<iterator, iterator> _Pii;
|
williamr@4
|
199 |
const size_type __n = _M_bkt_num_key(__key);
|
williamr@4
|
200 |
|
williamr@4
|
201 |
for (_Node* __first = (_Node*)_M_buckets[__n]; __first; __first = __first->_M_next)
|
williamr@4
|
202 |
if (_M_equals(_M_get_key(__first->_M_val), __key)) {
|
williamr@4
|
203 |
for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next)
|
williamr@4
|
204 |
if (!_M_equals(_M_get_key(__cur->_M_val), __key))
|
williamr@4
|
205 |
return _Pii(iterator(__first, this), iterator(__cur, this));
|
williamr@4
|
206 |
for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
|
williamr@4
|
207 |
if (_M_buckets[__m])
|
williamr@4
|
208 |
return _Pii(iterator(__first, this),
|
williamr@4
|
209 |
iterator((_Node*)_M_buckets[__m], this));
|
williamr@4
|
210 |
return _Pii(iterator(__first, this), end());
|
williamr@4
|
211 |
}
|
williamr@4
|
212 |
return _Pii(end(), end());
|
williamr@4
|
213 |
}
|
williamr@4
|
214 |
|
williamr@4
|
215 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
216 |
pair< _Ht_iterator<_Val, _Const_traits<_Val>, _Key, _HF, _ExK, _EqK, _All>,
|
williamr@4
|
217 |
_Ht_iterator<_Val, _Const_traits<_Val>, _Key, _HF, _ExK, _EqK, _All> >
|
williamr@4
|
218 |
hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
|
williamr@4
|
219 |
::equal_range(const key_type& __key) const
|
williamr@4
|
220 |
{
|
williamr@4
|
221 |
typedef pair<const_iterator, const_iterator> _Pii;
|
williamr@4
|
222 |
const size_type __n = _M_bkt_num_key(__key);
|
williamr@4
|
223 |
|
williamr@4
|
224 |
for (const _Node* __first = (_Node*)_M_buckets[__n] ;
|
williamr@4
|
225 |
__first;
|
williamr@4
|
226 |
__first = __first->_M_next) {
|
williamr@4
|
227 |
if (_M_equals(_M_get_key(__first->_M_val), __key)) {
|
williamr@4
|
228 |
for (const _Node* __cur = __first->_M_next;
|
williamr@4
|
229 |
__cur;
|
williamr@4
|
230 |
__cur = __cur->_M_next)
|
williamr@4
|
231 |
if (!_M_equals(_M_get_key(__cur->_M_val), __key))
|
williamr@4
|
232 |
return _Pii(const_iterator(__first, this),
|
williamr@4
|
233 |
const_iterator(__cur, this));
|
williamr@4
|
234 |
for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
|
williamr@4
|
235 |
if (_M_buckets[__m])
|
williamr@4
|
236 |
return _Pii(const_iterator(__first, this),
|
williamr@4
|
237 |
const_iterator((_Node*)_M_buckets[__m], this));
|
williamr@4
|
238 |
return _Pii(const_iterator(__first, this), end());
|
williamr@4
|
239 |
}
|
williamr@4
|
240 |
}
|
williamr@4
|
241 |
return _Pii(end(), end());
|
williamr@4
|
242 |
}
|
williamr@4
|
243 |
|
williamr@4
|
244 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
245 |
__size_type__
|
williamr@4
|
246 |
hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::erase(const key_type& __key)
|
williamr@4
|
247 |
{
|
williamr@4
|
248 |
const size_type __n = _M_bkt_num_key(__key);
|
williamr@4
|
249 |
_Node* __first = (_Node*)_M_buckets[__n];
|
williamr@4
|
250 |
size_type __erased = 0;
|
williamr@4
|
251 |
|
williamr@4
|
252 |
if (__first) {
|
williamr@4
|
253 |
_Node* __cur = __first;
|
williamr@4
|
254 |
_Node* __next = __cur->_M_next;
|
williamr@4
|
255 |
while (__next) {
|
williamr@4
|
256 |
if (_M_equals(_M_get_key(__next->_M_val), __key)) {
|
williamr@4
|
257 |
__cur->_M_next = __next->_M_next;
|
williamr@4
|
258 |
_M_delete_node(__next);
|
williamr@4
|
259 |
__next = __cur->_M_next;
|
williamr@4
|
260 |
++__erased;
|
williamr@4
|
261 |
--_M_num_elements._M_data;
|
williamr@4
|
262 |
}
|
williamr@4
|
263 |
else {
|
williamr@4
|
264 |
__cur = __next;
|
williamr@4
|
265 |
__next = __cur->_M_next;
|
williamr@4
|
266 |
}
|
williamr@4
|
267 |
}
|
williamr@4
|
268 |
if (_M_equals(_M_get_key(__first->_M_val), __key)) {
|
williamr@4
|
269 |
_M_buckets[__n] = __first->_M_next;
|
williamr@4
|
270 |
_M_delete_node(__first);
|
williamr@4
|
271 |
++__erased;
|
williamr@4
|
272 |
--_M_num_elements._M_data;
|
williamr@4
|
273 |
}
|
williamr@4
|
274 |
}
|
williamr@4
|
275 |
return __erased;
|
williamr@4
|
276 |
}
|
williamr@4
|
277 |
|
williamr@4
|
278 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
279 |
void hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::erase(const const_iterator& __it)
|
williamr@4
|
280 |
{
|
williamr@4
|
281 |
// const iterator& __it = __REINTERPRET_CAST(const iterator&,_c_it);
|
williamr@4
|
282 |
const _Node* __p = __it._M_cur;
|
williamr@4
|
283 |
if (__p) {
|
williamr@4
|
284 |
const size_type __n = _M_bkt_num(__p->_M_val);
|
williamr@4
|
285 |
_Node* __cur = (_Node*)_M_buckets[__n];
|
williamr@4
|
286 |
|
williamr@4
|
287 |
if (__cur == __p) {
|
williamr@4
|
288 |
_M_buckets[__n] = __cur->_M_next;
|
williamr@4
|
289 |
_M_delete_node(__cur);
|
williamr@4
|
290 |
--_M_num_elements._M_data;
|
williamr@4
|
291 |
}
|
williamr@4
|
292 |
else {
|
williamr@4
|
293 |
_Node* __next = __cur->_M_next;
|
williamr@4
|
294 |
while (__next) {
|
williamr@4
|
295 |
if (__next == __p) {
|
williamr@4
|
296 |
__cur->_M_next = __next->_M_next;
|
williamr@4
|
297 |
_M_delete_node(__next);
|
williamr@4
|
298 |
--_M_num_elements._M_data;
|
williamr@4
|
299 |
break;
|
williamr@4
|
300 |
}
|
williamr@4
|
301 |
else {
|
williamr@4
|
302 |
__cur = __next;
|
williamr@4
|
303 |
__next = __cur->_M_next;
|
williamr@4
|
304 |
}
|
williamr@4
|
305 |
}
|
williamr@4
|
306 |
}
|
williamr@4
|
307 |
}
|
williamr@4
|
308 |
}
|
williamr@4
|
309 |
|
williamr@4
|
310 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
311 |
void hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
|
williamr@4
|
312 |
::erase(const_iterator _c_first, const_iterator _c_last)
|
williamr@4
|
313 |
{
|
williamr@4
|
314 |
iterator& __first = (iterator&)_c_first;
|
williamr@4
|
315 |
iterator& __last = (iterator&)_c_last;
|
williamr@4
|
316 |
size_type __f_bucket = __first._M_cur ?
|
williamr@4
|
317 |
_M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
|
williamr@4
|
318 |
size_type __l_bucket = __last._M_cur ?
|
williamr@4
|
319 |
_M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
|
williamr@4
|
320 |
if (__first._M_cur == __last._M_cur)
|
williamr@4
|
321 |
return;
|
williamr@4
|
322 |
else if (__f_bucket == __l_bucket)
|
williamr@4
|
323 |
_M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
|
williamr@4
|
324 |
else {
|
williamr@4
|
325 |
_M_erase_bucket(__f_bucket, __first._M_cur, 0);
|
williamr@4
|
326 |
for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
|
williamr@4
|
327 |
_M_erase_bucket(__n, 0);
|
williamr@4
|
328 |
if (__l_bucket != _M_buckets.size())
|
williamr@4
|
329 |
_M_erase_bucket(__l_bucket, __last._M_cur);
|
williamr@4
|
330 |
}
|
williamr@4
|
331 |
}
|
williamr@4
|
332 |
|
williamr@4
|
333 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
334 |
void hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
|
williamr@4
|
335 |
::resize(size_type __num_elements_hint)
|
williamr@4
|
336 |
{
|
williamr@4
|
337 |
const size_type __old_n = _M_buckets.size();
|
williamr@4
|
338 |
if (__num_elements_hint > __old_n) {
|
williamr@4
|
339 |
const size_type __n = _M_next_size(__num_elements_hint);
|
williamr@4
|
340 |
if (__n > __old_n) {
|
williamr@4
|
341 |
_BucketVector __tmp(__n, (void*)(0),
|
williamr@4
|
342 |
_M_buckets.get_allocator());
|
williamr@4
|
343 |
_STLP_PUSH_CLEANUP_ITEM(_BucketVector, &__tmp);
|
williamr@4
|
344 |
_STLP_TRY {
|
williamr@4
|
345 |
for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
|
williamr@4
|
346 |
_Node* __first = (_Node*)_M_buckets[__bucket];
|
williamr@4
|
347 |
while (__first) {
|
williamr@4
|
348 |
size_type __new_bucket = _M_bkt_num(__first->_M_val, __n);
|
williamr@4
|
349 |
_M_buckets[__bucket] = __first->_M_next;
|
williamr@4
|
350 |
__first->_M_next = (_Node*)__tmp[__new_bucket];
|
williamr@4
|
351 |
__tmp[__new_bucket] = __first;
|
williamr@4
|
352 |
__first = (_Node*)_M_buckets[__bucket];
|
williamr@4
|
353 |
}
|
williamr@4
|
354 |
}
|
williamr@4
|
355 |
_M_buckets.swap(__tmp);
|
williamr@4
|
356 |
}
|
williamr@4
|
357 |
_STLP_CATCH_ALL {
|
williamr@4
|
358 |
for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
|
williamr@4
|
359 |
while (__tmp[__bucket]) {
|
williamr@4
|
360 |
_Node* __next = ((_Node*)__tmp[__bucket])->_M_next;
|
williamr@4
|
361 |
_M_delete_node((_Node*)__tmp[__bucket]);
|
williamr@4
|
362 |
__tmp[__bucket] = __next;
|
williamr@4
|
363 |
}
|
williamr@4
|
364 |
}
|
williamr@4
|
365 |
_STLP_RETHROW;
|
williamr@4
|
366 |
}
|
williamr@4
|
367 |
#ifdef _STLP_USE_TRAP_LEAVE
|
williamr@4
|
368 |
CleanupStack::Pop();
|
williamr@4
|
369 |
#endif
|
williamr@4
|
370 |
|
williamr@4
|
371 |
}
|
williamr@4
|
372 |
}
|
williamr@4
|
373 |
}
|
williamr@4
|
374 |
|
williamr@4
|
375 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
376 |
void hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
|
williamr@4
|
377 |
::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
|
williamr@4
|
378 |
{
|
williamr@4
|
379 |
_Node* __cur = (_Node*)_M_buckets[__n];
|
williamr@4
|
380 |
if (__cur == __first)
|
williamr@4
|
381 |
_M_erase_bucket(__n, __last);
|
williamr@4
|
382 |
else {
|
williamr@4
|
383 |
_Node* __next;
|
williamr@4
|
384 |
for (__next = __cur->_M_next;
|
williamr@4
|
385 |
__next != __first;
|
williamr@4
|
386 |
__cur = __next, __next = __cur->_M_next)
|
williamr@4
|
387 |
;
|
williamr@4
|
388 |
while (__next != __last) {
|
williamr@4
|
389 |
__cur->_M_next = __next->_M_next;
|
williamr@4
|
390 |
_M_delete_node(__next);
|
williamr@4
|
391 |
__next = __cur->_M_next;
|
williamr@4
|
392 |
--_M_num_elements._M_data;
|
williamr@4
|
393 |
}
|
williamr@4
|
394 |
}
|
williamr@4
|
395 |
}
|
williamr@4
|
396 |
|
williamr@4
|
397 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
398 |
void hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
|
williamr@4
|
399 |
::_M_erase_bucket(const size_type __n, _Node* __last)
|
williamr@4
|
400 |
{
|
williamr@4
|
401 |
_Node* __cur = (_Node*)_M_buckets[__n];
|
williamr@4
|
402 |
while (__cur && __cur != __last) {
|
williamr@4
|
403 |
_Node* __next = __cur->_M_next;
|
williamr@4
|
404 |
_M_delete_node(__cur);
|
williamr@4
|
405 |
__cur = __next;
|
williamr@4
|
406 |
_M_buckets[__n] = __cur;
|
williamr@4
|
407 |
--_M_num_elements._M_data;
|
williamr@4
|
408 |
}
|
williamr@4
|
409 |
}
|
williamr@4
|
410 |
|
williamr@4
|
411 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
412 |
void hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::clear()
|
williamr@4
|
413 |
{
|
williamr@4
|
414 |
for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
|
williamr@4
|
415 |
_Node* __cur = (_Node*)_M_buckets[__i];
|
williamr@4
|
416 |
while (__cur != 0) {
|
williamr@4
|
417 |
_Node* __next = __cur->_M_next;
|
williamr@4
|
418 |
_M_delete_node(__cur);
|
williamr@4
|
419 |
__cur = __next;
|
williamr@4
|
420 |
}
|
williamr@4
|
421 |
_M_buckets[__i] = 0;
|
williamr@4
|
422 |
}
|
williamr@4
|
423 |
_M_num_elements._M_data = 0;
|
williamr@4
|
424 |
}
|
williamr@4
|
425 |
|
williamr@4
|
426 |
|
williamr@4
|
427 |
template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
|
williamr@4
|
428 |
void hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
|
williamr@4
|
429 |
::_M_copy_from(const hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>& __ht)
|
williamr@4
|
430 |
{
|
williamr@4
|
431 |
_M_buckets.clear();
|
williamr@4
|
432 |
_M_buckets.reserve(__ht._M_buckets.size());
|
williamr@4
|
433 |
_M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (void*) 0);
|
williamr@4
|
434 |
_STLP_TRY {
|
williamr@4
|
435 |
for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
|
williamr@4
|
436 |
const _Node* __cur = (_Node*)__ht._M_buckets[__i];
|
williamr@4
|
437 |
if (__cur) {
|
williamr@4
|
438 |
_Node* __xcopy = _M_new_node(__cur->_M_val);
|
williamr@4
|
439 |
_M_buckets[__i] = __xcopy;
|
williamr@4
|
440 |
|
williamr@4
|
441 |
for (_Node* __next = __cur->_M_next;
|
williamr@4
|
442 |
__next;
|
williamr@4
|
443 |
__cur = __next, __next = __cur->_M_next) {
|
williamr@4
|
444 |
__xcopy->_M_next = _M_new_node(__next->_M_val);
|
williamr@4
|
445 |
__xcopy = __xcopy->_M_next;
|
williamr@4
|
446 |
}
|
williamr@4
|
447 |
}
|
williamr@4
|
448 |
}
|
williamr@4
|
449 |
_M_num_elements._M_data = __ht._M_num_elements._M_data;
|
williamr@4
|
450 |
}
|
williamr@4
|
451 |
_STLP_UNWIND(clear());
|
williamr@4
|
452 |
}
|
williamr@4
|
453 |
|
williamr@4
|
454 |
# undef __iterator__
|
williamr@4
|
455 |
# undef const_iterator
|
williamr@4
|
456 |
# undef __size_type__
|
williamr@4
|
457 |
# undef __reference__
|
williamr@4
|
458 |
# undef size_type
|
williamr@4
|
459 |
# undef value_type
|
williamr@4
|
460 |
# undef key_type
|
williamr@4
|
461 |
# undef _Node
|
williamr@4
|
462 |
# undef __stl_num_primes
|
williamr@4
|
463 |
# undef hashtable
|
williamr@4
|
464 |
|
williamr@4
|
465 |
_STLP_END_NAMESPACE
|
williamr@4
|
466 |
|
williamr@4
|
467 |
#endif /* _STLP_HASHTABLE_C */
|
williamr@4
|
468 |
|
williamr@4
|
469 |
// Local Variables:
|
williamr@4
|
470 |
// mode:C++
|
williamr@4
|
471 |
// End:
|