Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
4 * Hewlett-Packard Company
6 * Copyright (c) 1996,1997
7 * Silicon Graphics Computer Systems, Inc.
10 * Moscow Center for SPARC Technology
15 * This material is provided "as is", with absolutely no warranty expressed
16 * or implied. Any use is at your own risk.
18 * Permission to use or copy this software for any purpose is hereby granted
19 * without fee, provided the above notices are retained on all copies.
20 * Permission to modify the code and to distribute modified code is granted,
21 * provided the above notices are retained, and a notice that the code was
22 * modified is included with the above copyright notice.
26 /* NOTE: This is an internal header file, included by other STL headers.
27 * You should not attempt to use it directly.
30 #ifndef _STLP_INTERNAL_HASHTABLE_H
31 #define _STLP_INTERNAL_HASHTABLE_H
33 # ifndef _STLP_INTERNAL_VECTOR_H
34 # include <stl/_vector.h>
37 # ifndef _STLP_INTERNAL_ITERATOR_H
38 # include <stl/_iterator.h>
41 # ifndef _STLP_INTERNAL_FUNCTION_H
42 # include <stl/_function_base.h>
45 # ifndef _STLP_INTERNAL_ALGOBASE_H
46 # include <stl/_algobase.h>
49 # ifndef _STLP_HASH_FUN_H
50 # include <stl/_hash_fun.h>
53 // Hashtable class, used to implement the hashed associative containers
54 // hash_set, hash_map, hash_multiset, and hash_multimap.
57 # define hashtable __WORKAROUND_DBG_RENAME(hashtable)
63 struct _Hashtable_node
65 typedef _Hashtable_node<_Val> _Self;
68 __TRIVIAL_STUFF(_Hashtable_node)
71 // some compilers require the names of template parameters to be the same
72 template <class _Val, class _Key, class _HF,
73 class _ExK, class _EqK, class _All>
76 template <class _Val, class _Key, class _HF,
77 class _ExK, class _EqK, class _All>
78 struct _Hashtable_iterator
80 typedef hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
82 typedef _Hashtable_node<_Val> _Node;
87 _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
88 : _M_cur(__n), _M_ht(__tab) {}
89 _Hashtable_iterator() {}
91 _Node* _M_skip_to_next();
95 template <class _Val, class _Traits, class _Key, class _HF,
96 class _ExK, class _EqK, class _All>
97 struct _Ht_iterator : public _Hashtable_iterator< _Val, _Key,_HF, _ExK,_EqK,_All>
100 typedef _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> _Base;
102 // typedef _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All> iterator;
103 // typedef _Ht_iterator<_Val, _Const_traits<_Val>,_Key,_HF,_ExK,_EqK,_All> const_iterator;
104 typedef _Ht_iterator<_Val, _Traits,_Key,_HF,_ExK,_EqK,_All> _Self;
106 typedef hashtable<_Val,_Key,_HF,_ExK,_EqK,_All> _Hashtable;
107 typedef _Hashtable_node<_Val> _Node;
109 typedef _Val value_type;
110 typedef forward_iterator_tag iterator_category;
111 typedef ptrdiff_t difference_type;
112 typedef size_t size_type;
113 typedef typename _Traits::reference reference;
114 typedef typename _Traits::pointer pointer;
116 _Ht_iterator(const _Node* __n, const _Hashtable* __tab) :
117 _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>((_Node*)__n, (_Hashtable*)__tab) {}
119 _Ht_iterator(const _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __it) :
120 _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>(__it) {}
122 reference operator*() const {
123 return this->_M_cur->_M_val;
125 _STLP_DEFINE_ARROW_OPERATOR
127 _Self& operator++() {
128 _Node* __n = this->_M_cur->_M_next;
129 this->_M_cur = (__n !=0 ? __n : this->_M_skip_to_next());
132 inline _Self operator++(int) {
139 template <class _Val, class _Traits, class _Traits1, class _Key, class _HF,
140 class _ExK, class _EqK, class _All>
142 operator==(const _Ht_iterator<_Val, _Traits,_Key,_HF,_ExK,_EqK,_All>& __x,
143 const _Ht_iterator<_Val, _Traits1,_Key,_HF,_ExK,_EqK,_All>& __y) {
144 return __x._M_cur == __y._M_cur;
147 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
148 template <class _Val, class _Key, class _HF,
149 class _ExK, class _EqK, class _All>
151 operator!=(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& __x,
152 const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& __y) {
153 return __x._M_cur != __y._M_cur;
157 # if (defined (__GNUC__) && (__GNUC_MINOR__ < 8))
158 template <class _Val, class _Key, class _HF,
159 class _ExK, class _EqK, class _All>
161 operator!=(const _Ht_iterator<_Val, _Const_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __x,
162 const _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __y) {
163 return __x._M_cur != __y._M_cur;
167 template <class _Val, class _Key, class _HF,
168 class _ExK, class _EqK, class _All>
170 operator!=(const _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __x,
171 const _Ht_iterator<_Val, _Const_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __y) {
172 return __x._M_cur != __y._M_cur;
176 # ifdef _STLP_USE_OLD_HP_ITERATOR_QUERIES
177 template <class _Val, class _Traits, class _Key, class _HF, class _ExK, class _EqK, class _All>
178 inline _Val* value_type(const _Ht_iterator<_Val, _Traits,_Key,_HF,_ExK,_EqK,_All>&) { return (_Val*) 0; }
179 template <class _Val, class _Traits, class _Key, class _HF, class _ExK, class _EqK, class _All>
180 inline forward_iterator_tag iterator_category(const _Ht_iterator<_Val, _Traits,_Key,_HF,_ExK,_EqK,_All>&) { return forward_iterator_tag(); }
181 template <class _Val, class _Traits, class _Key, class _HF, class _ExK, class _EqK, class _All>
182 inline ptrdiff_t* distance_type(const _Ht_iterator<_Val,_Traits,_Key,_HF,_ExK,_EqK,_All>&) { return (ptrdiff_t*) 0; }
185 #define __stl_num_primes 28
189 static const size_t _M_list[__stl_num_primes];
192 # if defined (_STLP_USE_TEMPLATE_EXPORT)
193 _STLP_EXPORT_TEMPLATE_CLASS _Stl_prime<bool>;
196 typedef _Stl_prime<bool> _Stl_prime_type;
199 // Hashtables handle allocators a bit differently than other containers
200 // do. If we're using standard-conforming allocators, then a hashtable
201 // unconditionally has a member variable to hold its allocator, even if
202 // it so happens that all instances of the allocator type are identical.
203 // This is because, for hashtables, this extra storage is negligible.
204 // Additionally, a base class wouldn't serve any other purposes; it
205 // wouldn't, for example, simplify the exception-handling code.
206 template <class _Val, class _Key, class _HF,
207 class _ExK, class _EqK, class _All>
210 typedef hashtable<_Val, _Key, _HF, _ExK, _EqK, _All> _Self;
212 typedef _Key key_type;
213 typedef _Val value_type;
215 typedef _EqK key_equal;
217 typedef size_t size_type;
218 typedef ptrdiff_t difference_type;
219 typedef value_type* pointer;
220 typedef const value_type* const_pointer;
221 typedef value_type& reference;
222 typedef const value_type& const_reference;
223 typedef forward_iterator_tag _Iterator_category;
225 hasher hash_funct() const { return _M_hash; }
226 key_equal key_eq() const { return _M_equals; }
229 typedef _Hashtable_node<_Val> _Node;
232 _STLP_FORCE_ALLOCATORS(_Val, _All)
233 typedef typename _Alloc_traits<_Node, _All>::allocator_type _M_node_allocator_type;
234 typedef typename _Alloc_traits<void*, _All>::allocator_type _M_node_ptr_allocator_type;
235 typedef __vector__<void*, _M_node_ptr_allocator_type> _BucketVector;
237 typedef typename _Alloc_traits<_Val,_All>::allocator_type allocator_type;
238 allocator_type get_allocator() const {
239 return _STLP_CONVERT_ALLOCATOR((const _M_node_allocator_type&)_M_num_elements, _Val);
245 _BucketVector _M_buckets;
246 _STLP_alloc_proxy<size_type, _Node, _M_node_allocator_type> _M_num_elements;
247 const _Node* _M_get_bucket(size_t __n) const { return (_Node*)_M_buckets[__n]; }
250 typedef _Const_traits<_Val> __const_val_traits;
251 typedef _Nonconst_traits<_Val> __nonconst_val_traits;
252 typedef _Ht_iterator<_Val, __const_val_traits,_Key,_HF,_ExK,_EqK, _All> const_iterator;
253 typedef _Ht_iterator<_Val, __nonconst_val_traits,_Key,_HF,_ExK,_EqK,_All> iterator;
254 friend struct _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>;
255 friend struct _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>;
256 friend struct _Ht_iterator<_Val, _Const_traits<_Val>,_Key,_HF,_ExK,_EqK, _All>;
259 hashtable(size_type __n,
263 const allocator_type& __a = allocator_type())
268 _M_buckets(_STLP_CONVERT_ALLOCATOR(__a,void*)),
269 _M_num_elements(_STLP_CONVERT_ALLOCATOR(__a,_Node), (size_type)0)
271 _M_initialize_buckets(__n);
274 hashtable(size_type __n,
275 const _HF& __hf = hasher(),
276 const _EqK& __eql = key_equal(),
277 const allocator_type& __a = allocator_type())
282 _M_buckets(_STLP_CONVERT_ALLOCATOR(__a,void*)),
283 _M_num_elements(_STLP_CONVERT_ALLOCATOR(__a,_Node), (size_type)0)
285 _M_initialize_buckets(__n);
288 hashtable(const _Self& __ht)
290 _M_hash(__ht._M_hash),
291 _M_equals(__ht._M_equals),
292 _M_get_key(__ht._M_get_key),
293 _M_buckets(_STLP_CONVERT_ALLOCATOR(__ht.get_allocator(),void*)),
294 _M_num_elements((const _M_node_allocator_type&)__ht._M_num_elements, (size_type)0)
299 _Self& operator= (const _Self& __ht)
303 _M_hash = __ht._M_hash;
304 _M_equals = __ht._M_equals;
305 _M_get_key = __ht._M_get_key;
311 ~hashtable() { clear(); }
313 size_type size() const { return _M_num_elements._M_data; }
314 size_type max_size() const { return size_type(-1); }
315 bool empty() const { return size() == 0; }
317 void swap(_Self& __ht)
319 _STLP_STD::swap(_M_hash, __ht._M_hash);
320 _STLP_STD::swap(_M_equals, __ht._M_equals);
321 _STLP_STD::swap(_M_get_key, __ht._M_get_key);
322 _M_buckets.swap(__ht._M_buckets);
323 _STLP_STD::swap(_M_num_elements, __ht._M_num_elements);
328 for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
330 return iterator((_Node*)_M_buckets[__n], this);
334 iterator end() { return iterator((_Node*)0, this); }
336 const_iterator begin() const
338 for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
340 return const_iterator((_Node*)_M_buckets[__n], this);
344 const_iterator end() const { return const_iterator((_Node*)0, this); }
346 static bool _STLP_CALL _M_equal (const hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>&,
347 const hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>&);
351 size_type bucket_count() const { return _M_buckets.size(); }
353 size_type max_bucket_count() const
354 { return _Stl_prime_type::_M_list[(int)__stl_num_primes - 1]; }
356 size_type elems_in_bucket(size_type __bucket) const
358 size_type __result = 0;
359 for (_Node* __cur = (_Node*)_M_buckets[__bucket]; __cur; __cur = __cur->_M_next)
364 pair<iterator, bool> insert_unique(const value_type& __obj)
366 resize(_M_num_elements._M_data + 1);
367 return insert_unique_noresize(__obj);
370 iterator insert_equal(const value_type& __obj)
372 resize(_M_num_elements._M_data + 1);
373 return insert_equal_noresize(__obj);
376 pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
377 iterator insert_equal_noresize(const value_type& __obj);
379 #ifdef _STLP_MEMBER_TEMPLATES
380 template <class _InputIterator>
381 void insert_unique(_InputIterator __f, _InputIterator __l)
383 insert_unique(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator));
386 template <class _InputIterator>
387 void insert_equal(_InputIterator __f, _InputIterator __l)
389 insert_equal(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator));
392 template <class _InputIterator>
393 void insert_unique(_InputIterator __f, _InputIterator __l,
394 const input_iterator_tag &)
396 for ( ; __f != __l; ++__f)
400 template <class _InputIterator>
401 void insert_equal(_InputIterator __f, _InputIterator __l,
402 const input_iterator_tag &)
404 for ( ; __f != __l; ++__f)
408 template <class _ForwardIterator>
409 void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
410 const forward_iterator_tag &)
412 size_type __n = distance(__f, __l);
413 resize(_M_num_elements._M_data + __n);
414 for ( ; __n > 0; --__n, ++__f)
415 insert_unique_noresize(*__f);
418 template <class _ForwardIterator>
419 void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
420 const forward_iterator_tag &)
422 size_type __n = distance(__f, __l);
423 resize(_M_num_elements._M_data + __n);
424 for ( ; __n > 0; --__n, ++__f)
425 insert_equal_noresize(*__f);
428 #else /* _STLP_MEMBER_TEMPLATES */
429 void insert_unique(const value_type* __f, const value_type* __l)
431 size_type __n = __l - __f;
432 resize(_M_num_elements._M_data + __n);
433 for ( ; __n > 0; --__n, ++__f)
434 insert_unique_noresize(*__f);
437 void insert_equal(const value_type* __f, const value_type* __l)
439 size_type __n = __l - __f;
440 resize(_M_num_elements._M_data + __n);
441 for ( ; __n > 0; --__n, ++__f)
442 insert_equal_noresize(*__f);
445 void insert_unique(const_iterator __f, const_iterator __l)
447 size_type __n = distance(__f, __l);
448 resize(_M_num_elements._M_data + __n);
449 for ( ; __n > 0; --__n, ++__f)
450 insert_unique_noresize(*__f);
453 void insert_equal(const_iterator __f, const_iterator __l)
455 size_type __n = distance(__f, __l);
456 resize(_M_num_elements._M_data + __n);
457 for ( ; __n > 0; --__n, ++__f)
458 insert_equal_noresize(*__f);
460 #endif /*_STLP_MEMBER_TEMPLATES */
462 reference find_or_insert(const value_type& __obj);
465 # if defined(_STLP_MEMBER_TEMPLATES) && ! defined ( _STLP_NO_EXTENSIONS ) && !(defined(__MRC__)||(defined(__SC__)&&!defined(__DMC_)))
467 _Node* _M_find(const _KT& __key) const
469 _Node* _M_find(const key_type& __key) const
472 size_type __n = _M_hash(__key)% _M_buckets.size();
474 for ( __first = (_Node*)_M_buckets[__n];
475 __first && !_M_equals(_M_get_key(__first->_M_val), __key);
476 __first = __first->_M_next)
482 # if defined(_STLP_MEMBER_TEMPLATES) && ! defined ( _STLP_NO_EXTENSIONS ) && !(defined(__MRC__)||(defined(__SC__)&&!defined(__DMC__)))
484 iterator find(const _KT& __key)
486 iterator find(const key_type& __key)
489 return iterator(_M_find(__key), this);
492 # if defined(_STLP_MEMBER_TEMPLATES) && ! defined ( _STLP_NO_EXTENSIONS ) && !(defined(__MRC__)||(defined(__SC__)&&!defined(__DMC__)))
494 const_iterator find(const _KT& __key) const
496 const_iterator find(const key_type& __key) const
499 return const_iterator(_M_find(__key), this);
502 size_type count(const key_type& __key) const
504 const size_type __n = _M_bkt_num_key(__key);
505 size_type __result = 0;
507 for (const _Node* __cur = (_Node*)_M_buckets[__n]; __cur; __cur = __cur->_M_next)
508 if (_M_equals(_M_get_key(__cur->_M_val), __key))
513 pair<iterator, iterator>
514 equal_range(const key_type& __key);
516 pair<const_iterator, const_iterator>
517 equal_range(const key_type& __key) const;
519 size_type erase(const key_type& __key);
520 // void erase(const iterator& __it); `
521 void erase(const const_iterator& __it) ;
523 // void erase(const const_iterator& __first, const const_iterator __last) {
524 // erase((const iterator&)__first, (const iterator&)__last);
526 void erase(const_iterator __first, const_iterator __last);
527 void resize(size_type __num_elements_hint);
531 // this is for hash_map::operator[]
532 reference _M_insert(const value_type& __obj);
536 size_type _M_next_size(size_type __n) const;
538 void _M_initialize_buckets(size_type __n)
540 const size_type __n_buckets = _M_next_size(__n);
541 _M_buckets.reserve(__n_buckets);
542 _M_buckets.insert(_M_buckets.end(), __n_buckets, (void*) 0);
543 _M_num_elements._M_data = 0;
546 size_type _M_bkt_num_key(const key_type& __key) const
548 return _M_bkt_num_key(__key, _M_buckets.size());
551 size_type _M_bkt_num(const value_type& __obj) const
553 return _M_bkt_num_key(_M_get_key(__obj));
556 size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
558 return _M_hash(__key) % __n;
561 size_type _M_bkt_num(const value_type& __obj, size_t __n) const
563 return _M_bkt_num_key(_M_get_key(__obj), __n);
566 _Node* _M_new_node(const value_type& __obj)
568 _Node* __n = _M_num_elements.allocate(1);
571 _Construct(&__n->_M_val, __obj);
574 _STLP_UNWIND(_M_num_elements.deallocate(__n, 1));
578 void _M_delete_node(_Node* __n)
580 _STLP_STD::_Destroy(&__n->_M_val);
581 _M_num_elements.deallocate(__n, 1);
584 void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
585 void _M_erase_bucket(const size_type __n, _Node* __last);
587 void _M_copy_from(const _Self& __ht);
590 #define _STLP_TEMPLATE_HEADER template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
591 #define _STLP_TEMPLATE_CONTAINER hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
592 #include <stl/_relops_hash_cont.h>
593 #undef _STLP_TEMPLATE_CONTAINER
594 #undef _STLP_TEMPLATE_HEADER
600 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
601 # include <stl/_hashtable.c>
604 # if defined (_STLP_DEBUG)
605 # include <stl/debug/_hashtable.h>
608 #endif /* _STLP_INTERNAL_HASHTABLE_H */