BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstp_hashtable.h
Go to the documentation of this file.
1/// @file bslstp_hashtable.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstp_hashtable.h -*-C++-*-
8#ifndef INCLUDED_BSLSTP_HASHTABLE
9#define INCLUDED_BSLSTP_HASHTABLE
10
11/// @defgroup bslstp_hashtable bslstp_hashtable
12/// @brief Provide facilities for STLPort implementation.
13/// @addtogroup bsl
14/// @{
15/// @addtogroup bslstp
16/// @{
17/// @addtogroup bslstp_hashtable
18/// @{
19///
20/// <h1> Outline </h1>
21/// * <a href="#bslstp_hashtable-purpose"> Purpose</a>
22/// * <a href="#bslstp_hashtable-classes"> Classes </a>
23/// * <a href="#bslstp_hashtable-description"> Description </a>
24///
25/// # Purpose {#bslstp_hashtable-purpose}
26/// Provide facilities for STLPort implementation.
27///
28/// @deprecated Do not use directly.
29///
30/// # Classes {#bslstp_hashtable-classes}
31///
32///
33/// @see bslstp_hashmap, bslstp_hashset
34///
35/// # Description {#bslstp_hashtable-description}
36/// This component is for internal use only.
37///
38/// Note that the functions in this component are based on STLPort's
39/// implementation, with copyright notice as follows:
40/// @code
41//*
42/ *
43/ * Copyright (c) 1994
44/ * Hewlett-Packard Company
45/ *
46/ * Copyright (c) 1996,1997
47/ * Silicon Graphics Computer Systems, Inc.
48/ *
49/ * Copyright (c) 1997
50/ * Moscow Center for SPARC Technology
51/ *
52/ * Copyright (c) 1999
53/ * Boris Fomitchev
54/ *
55/ * This material is provided "as is", with absolutely no warranty expressed
56/ * or implied. Any use is at your own risk.
57/ *
58/ * Permission to use or copy this software for any purpose is hereby granted
59/ * without fee, provided the above notices are retained on all copies.
60/ * Permission to modify the code and to distribute modified code is granted,
61/ * provided the above notices are retained, and a notice that the code was
62/ * modified is included with the above copyright notice.
63/ *
64/ */
65/// @endcode
66///
67/// /Usage
68/// /-----
69/// This component is for internal use only.
70/// @}
71/** @} */
72/** @} */
73
74/** @addtogroup bsl
75 * @{
76 */
77/** @addtogroup bslstp
78 * @{
79 */
80/** @addtogroup bslstp_hashtable
81 * @{
82 */
83
84#ifdef BDE_OPENSOURCE_PUBLICATION // STP
85#error "bslstp_hashtable is not for publication"
86#endif
87#include <bslstp_alloc.h>
88#include <bslstp_iterator.h> // const and nonconst traits for iterator
89#include <bslstp_util.h>
90
93
94#include <bsls_exceptionutil.h>
95#include <bsls_util.h>
96
97#include <bslstl_hash.h>
98#include <bslstl_iterator.h>
99#include <bslstl_pair.h>
100#include <bslstl_vector.h>
101
102#include <algorithm>
103#include <functional>
104#include <iterator>
105
106// Hashtable class, used to implement the hashed associative containers
107// hash_set, hash_map, hash_multiset, and hash_multimap.
108
109namespace bsl {
110
111template <class _Val>
118
119// some compilers require the names of template parameters to be the same
120template <class _Val, class _Key, class _HF,
121 class _ExK, class _EqK, class _All>
122class hashtable;
123
124template <class _Val, class _Key, class _HF,
125 class _ExK, class _EqK, class _All>
141
142
143template <class _Val, class _Traits, class _Key, class _HF,
144 class _ExK, class _EqK, class _All>
145struct _Ht_iterator : public _Hashtable_iterator< _Val, _Key,_HF, _ExK,_EqK,_All>
146{
147
149
150 // typedef _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All> iterator;
151 // typedef _Ht_iterator<_Val, _Const_traits<_Val>,_Key,_HF,_ExK,_EqK,_All> const_iterator;
153
156
157 typedef _Val value_type;
158 typedef std::forward_iterator_tag iterator_category;
159 typedef ptrdiff_t difference_type;
160 typedef size_t size_type;
161 typedef typename _Traits::reference reference;
162 typedef typename _Traits::pointer pointer;
163
164 _Ht_iterator(const _Node* __n, const _Hashtable* __tab) :
165 _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>(const_cast<_Node*>(__n),
166 const_cast<_Hashtable*>(__tab)) {}
168 _Ht_iterator(const _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __it) :
169 _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>(__it) {}
170
172 return this->_M_cur->_M_val;
173 }
174
175 pointer operator -> ( ) const { return & ( operator * ( ) ) ; }
176
178 _Node* __n = this->_M_cur->_M_next;
179 this->_M_cur = (__n !=0 ? __n : this->_M_skip_to_next());
180 return *this;
181 }
182 inline
183 _Self operator++(int) {
184 _Self __tmp = *this;
185 ++*this;
186 return __tmp;
187 }
188};
189
190template <class _Val, class _Traits, class _Traits1, class _Key, class _HF,
191 class _ExK, class _EqK, class _All>
192inline
193bool operator==(
196{
197 return __x._M_cur == __y._M_cur;
198}
199
200
201template <class _Val, class _Key, class _HF,
202 class _ExK, class _EqK, class _All>
203inline
206 return __x._M_cur != __y._M_cur;
207}
208
209#define BSLSTP_STL_NUM_PRIMES 31
210
211template <class _Tp>
213public:
214 static const size_t _M_list[BSLSTP_STL_NUM_PRIMES];
215};
216
218
219
220// Hashtables handle allocators a bit differently than other containers
221// do. If we're using standard-conforming allocators, then a hashtable
222// unconditionally has a member variable to hold its allocator, even if
223// it so happens that all instances of the allocator type are identical.
224// This is because, for hashtables, this extra storage is negligible.
225// Additionally, a base class wouldn't serve any other purposes; it
226// wouldn't, for example, simplify the exception-handling code.
227template <class _Val, class _Key, class _HF,
228 class _ExK, class _EqK, class _All>
230{
232
233public:
234 typedef _Key key_type;
235 typedef _Val value_type;
236 typedef _HF hasher;
237 typedef _EqK key_equal;
238
239 typedef size_t size_type;
240 typedef ptrdiff_t difference_type;
242 typedef const value_type* const_pointer;
245 typedef std::forward_iterator_tag _Iterator_category;
246
247 hasher hash_funct() const { return _M_hash; }
248 key_equal key_eq() const { return _M_equals; }
249
250private:
251 typedef _Hashtable_node<_Val> _Node;
252
253 struct QuickSwap;
254 friend struct QuickSwap;
255
256 /// Function object to quickly swap two trees with identical
257 /// allocators and allocation modes.
258 struct QuickSwap
259 {
260
261 /// Swap contents of `v1` and `v2`. Undefined unless
262 /// `v1.get_allocator() == v2.get_allocator()` and
263 /// `v1.allocationHint() == v2.allocationHint()`.
264 void operator()(_Self& v1, _Self& v2) const
265 {
266 ::std::swap(v1._M_hash, v2._M_hash);
267 ::std::swap(v1._M_equals, v2._M_equals);
268 ::std::swap(v1._M_get_key, v2._M_get_key);
269 v1._M_buckets.swap(v2._M_buckets);
270 ::std::swap(v1._M_num_elements._M_data,
271 v2._M_num_elements._M_data);
272 }
273 };
274
275private:
276 typedef typename _Alloc_traits<_Node, _All>::allocator_type _M_node_allocator_type;
277 typedef typename _Alloc_traits<void*, _All>::allocator_type _M_node_ptr_allocator_type;
278 typedef vector<void*, _M_node_ptr_allocator_type> _BucketVector;
279public:
282 //return _STLP_CONVERT_ALLOCATOR((const _M_node_allocator_type&)_M_num_elements, _Val).allocator();
283 return (const _M_node_allocator_type&)(_M_num_elements.get_allocator());
284 }
285private:
286 hasher _M_hash;
287 key_equal _M_equals;
288 _ExK _M_get_key;
289 _BucketVector _M_buckets;
291 const _Node* _M_get_bucket(size_t __n) const { return (_Node*)_M_buckets[__n]; }
292
293public:
298 friend struct _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>;
299 friend struct _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>;
300 friend struct _Ht_iterator<_Val, _Const_traits<_Val>,_Key,_HF,_ExK,_EqK, _All>;
301
302public:
304 const _HF& __hf,
305 const _EqK& __eql,
306 const _ExK& __ext,
307 const allocator_type& __a = allocator_type())
308 :
309 _M_hash(__hf),
310 _M_equals(__eql),
311 _M_get_key(__ext),
312 _M_buckets(__a),
313 _M_num_elements(__a, (size_type)0)
314 {
315 _M_initialize_buckets(__n);
316 }
317
319 const _HF& __hf,
320 const _EqK& __eql,
321 const allocator_type& __a = allocator_type())
322 :
323 _M_hash(__hf),
324 _M_equals(__eql),
325 _M_get_key(_ExK()),
326 _M_buckets(__a),
327 _M_num_elements(__a, (size_type)0)
328 {
329 _M_initialize_buckets(__n);
330 }
331
332 /* TODO:
333 typedef BloombergLP::bslstl::TraitsGroupStlUnorderedContainer<
334 _Val,
335 _HF,
336 _EqK,
337 _All> HashTableTypeTraits;
338 BSLALG_DECLARE_NESTED_TRAITS(hashtable, HashTableTypeTraits);
339 */
340
341 hashtable(const _Self& __ht)
342 :
343 _M_hash(__ht._M_hash),
344 _M_equals(__ht._M_equals),
345 _M_get_key(__ht._M_get_key),
346 _M_buckets(BloombergLP::bslstp::Util::copyContainerAllocator(__ht.get_allocator())),
347 _M_num_elements(BloombergLP::bslstp::Util::copyContainerAllocator((const _M_node_allocator_type&)__ht._M_num_elements), (size_type)0)
348 {
349 _M_copy_from(__ht);
350 }
351
352 hashtable(const _Self& __ht, const allocator_type& __a)
353 :
354 _M_hash(__ht._M_hash),
355 _M_equals(__ht._M_equals),
356 _M_get_key(__ht._M_get_key),
357 _M_buckets(__a),
358 _M_num_elements(__a, (size_type)0)
359 {
360 _M_copy_from(__ht);
361 }
362
363 _Self& operator= (const _Self& __ht)
364 {
365 if (&__ht != this) {
366 clear();
367 _M_hash = __ht._M_hash;
368 _M_equals = __ht._M_equals;
369 _M_get_key = __ht._M_get_key;
370 _M_copy_from(__ht);
371 }
372 return *this;
373 }
374
376
377 size_type size() const { return _M_num_elements._M_data; }
378 size_type max_size() const { return size_type(-1); }
379 bool empty() const { return size() == 0; }
380
381 void swap(_Self& __ht)
382 {
383 BloombergLP::bslstp::Util::swapContainers(*this, __ht, QuickSwap());
384 }
385
387 {
388 for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
389 if (_M_buckets[__n])
390 return iterator((_Node*)_M_buckets[__n], this); // RETURN
391 return end();
392 }
393
394 iterator end() { return iterator((_Node*)0, this); }
395
397 {
398 for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
399 if (_M_buckets[__n])
400 return const_iterator((_Node*)_M_buckets[__n], this); // RETURN
401 return end();
402 }
403
404 const_iterator end() const { return const_iterator((_Node*)0, this); }
405
408
409public:
410
411 size_type bucket_count() const { return _M_buckets.size(); }
412
415
417 {
418 size_type __result = 0;
419 for (_Node* __cur = (_Node*)_M_buckets[__bucket]; __cur; __cur = __cur->_M_next)
420 __result += 1;
421 return __result;
422 }
423
425 {
426 resize(_M_num_elements._M_data + 1);
427 return insert_unique_noresize(__obj);
428 }
429
431 {
432 resize(_M_num_elements._M_data + 1);
433 return insert_equal_noresize(__obj);
434 }
435
438
439 template <class _InputIterator>
440 void insert_unique(_InputIterator __f, _InputIterator __l)
441 {
442 // MODIFIED BY ARTHUR
443 // insert_unique(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator));
444 insert_unique(__f, __l, typename bsl::iterator_traits<_InputIterator>::iterator_category());
445 }
446
447 template <class _InputIterator>
448 void insert_equal(_InputIterator __f, _InputIterator __l)
449 {
450 // MODIFIED BY ARTHUR
451 // insert_equal(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator));
452 // MODIFIEd BY BCHAPMAN
453 // insert_unique(__f, __l, typename bsl::iterator_traits<_InputIterator>::iterator_category());
454 insert_equal(__f, __l, typename bsl::iterator_traits<_InputIterator>::iterator_category());
455 }
456
457 template <class _InputIterator>
458 void insert_unique(_InputIterator __f, _InputIterator __l,
459 const std::input_iterator_tag &)
460 {
461 for ( ; __f != __l; ++__f)
462 insert_unique(*__f);
463 }
464
465 template <class _InputIterator>
466 void insert_equal(_InputIterator __f, _InputIterator __l,
467 const std::input_iterator_tag &)
468 {
469 for ( ; __f != __l; ++__f)
470 insert_equal(*__f);
471 }
472
473 template <class _ForwardIterator>
474 void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
475 const std::forward_iterator_tag &)
476 {
477 size_type __n = bsl::distance(__f, __l);
478 resize(_M_num_elements._M_data + __n);
479 for ( ; __n > 0; --__n, ++__f)
481 }
482
483 template <class _ForwardIterator>
484 void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
485 const std::forward_iterator_tag &)
486 {
487 size_type __n = bsl::distance(__f, __l);
488 resize(_M_num_elements._M_data + __n);
489 for ( ; __n > 0; --__n, ++__f)
491 }
492
493
495
496private:
497 _Node* _M_find(const key_type& __key) const
498 {
499 size_type __n = _M_hash(__key)% _M_buckets.size();
500 _Node* __first;
501 for ( __first = (_Node*)_M_buckets[__n];
502 __first && !_M_equals(_M_get_key(__first->_M_val), __key);
503 __first = __first->_M_next)
504 {}
505 return __first;
506 }
507
508public:
509 template <class _KT>
510 iterator find(const _KT& __key)
511 {
512 return iterator(_M_find(__key), this);
513 }
514
515 template <class _KT>
516 const_iterator find(const _KT& __key) const
517 {
518 return const_iterator(_M_find(__key), this);
519 }
520
521 size_type count(const key_type& __key) const
522 {
523 const size_type __n = _M_bkt_num_key(__key);
524 size_type __result = 0;
525
526 for (const _Node* __cur = (_Node*)_M_buckets[__n]; __cur; __cur = __cur->_M_next)
527 if (_M_equals(_M_get_key(__cur->_M_val), __key))
528 ++__result;
529 return __result;
530 }
531
533 equal_range(const key_type& __key);
534
536 equal_range(const key_type& __key) const;
537
538 size_type erase(const key_type& __key);
539 // void erase(const iterator& __it); `
540 void erase(const const_iterator& __it) ;
541
542 // void erase(const const_iterator& __first, const const_iterator __last) {
543 // erase((const iterator&)__first, (const iterator&)__last);
544 // }
545 void erase(const_iterator __first, const_iterator __last);
546 void resize(size_type __num_elements_hint);
547 void clear();
548
549public:
550 // this is for hash_map::operator[]
552
553private:
554
555 size_type _M_next_size(size_type __n) const;
556
557 void _M_initialize_buckets(size_type __n)
558 {
559 const size_type __n_buckets = _M_next_size(__n);
560 _M_buckets.reserve(__n_buckets);
561 _M_buckets.insert(_M_buckets.end(), __n_buckets, (void*) 0);
562 _M_num_elements._M_data = 0;
563 }
564
565 size_type _M_bkt_num_key(const key_type& __key) const
566 {
567 return _M_bkt_num_key(__key, _M_buckets.size());
568 }
569
570 size_type _M_bkt_num(const value_type& __obj) const
571 {
572 return _M_bkt_num_key(_M_get_key(__obj));
573 }
574
575 size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
576 {
577 return _M_hash(__key) % __n;
578 }
579
580 size_type _M_bkt_num(const value_type& __obj, size_t __n) const
581 {
582 return _M_bkt_num_key(_M_get_key(__obj), __n);
583 }
584
585 _Node* _M_new_node(const value_type& __obj)
586 {
587 _Node* __n = _M_num_elements.allocatorRef().allocate(1);
588 __n->_M_next = 0;
589 BSLS_TRY {
590 BloombergLP::bslma::ConstructionUtil::construct(
591 BSLS_UTIL_ADDRESSOF(__n->_M_val),
592 _M_num_elements.get_allocator(),
593 __obj);
594 }
595 BSLS_CATCH(...)
596 {
597 (_M_num_elements.allocatorRef().deallocate(__n, 1));
599 }
600 return __n;
601 }
602
603 void _M_delete_node(_Node* __n)
604 {
605 BloombergLP::bslma::DestructionUtil::destroy(
606 BSLS_UTIL_ADDRESSOF(__n->_M_val));
607 _M_num_elements.allocatorRef().deallocate(__n, 1);
608 }
609
610 void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
611 void _M_erase_bucket(const size_type __n, _Node* __last);
612
613 void _M_copy_from(const _Self& __ht);
614};
615
616template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
617inline
623
624template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
625inline
626bool operator!=(const hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>& __hm1,
628 return !(__hm1 == __hm2);
629}
630
631} // close namespace bsl
632
633// BEGIN FORMER CONTENTS OF bslstp_hashtable.c
634/*
635 *
636 *
637 * Copyright (c) 1994
638 * Hewlett-Packard Company
639 *
640 * Copyright (c) 1996,1997
641 * Silicon Graphics Computer Systems, Inc.
642 *
643 * Copyright (c) 1997
644 * Moscow Center for SPARC Technology
645 *
646 * Copyright (c) 1999
647 * Boris Fomitchev
648 *
649 * This material is provided "as is", with absolutely no warranty expressed
650 * or implied. Any use is at your own risk.
651 *
652 * Permission to use or copy this software for any purpose is hereby granted
653 * without fee, provided the above notices are retained on all copies.
654 * Permission to modify the code and to distribute modified code is granted,
655 * provided the above notices are retained, and a notice that the code was
656 * modified is included with the above copyright notice.
657 *
658 */
659namespace bsl {
660
661# define BSLSTP_STL_PRIME_LIST_BODY { \
662 5ul, 11ul, 23ul, \
663 53ul, 97ul, 193ul, 389ul, 769ul, \
664 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, \
665 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, \
666 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, \
667 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,\
668 1610612741ul, 3221225473ul, 4294967291ul \
669}
670
671template <class _Tp>
673
674# undef BSLSTP_STL_PRIME_LIST_BODY
675
676template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
677 class _All>
678_Hashtable_node<_Val>*
680 size_t __bucket = _M_ht->_M_bkt_num(_M_cur->_M_val);
681 size_t __h_sz;
682 __h_sz = this->_M_ht->bucket_count();
683
684 _Node* __i=0;
685 while (__i==0 && ++__bucket < __h_sz)
686 __i = (_Node*)_M_ht->_M_buckets[__bucket];
687 return __i;
688}
689
690template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
691 class _All>
692typename hashtable < _Val , _Key , _HF , _ExK , _EqK , _All > :: size_type
694 const size_type* __first = (const size_type*)_Stl_prime_type::_M_list;
695 const size_type* __last = (const size_type*)_Stl_prime_type::_M_list + (int)BSLSTP_STL_NUM_PRIMES;
696 // MODIFIED BY ARTHUR
697 const size_type* pos = ::std::lower_bound(__first, __last, __n, ::std::less<size_type>());
698 return (pos == __last ? *(__last - 1) : *pos);
699}
700
701template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
702bool
706{
707 // typedef _Hashtable_node<_Val> _Node;
708 if (__ht1.bucket_count() != __ht2.bucket_count())
709 return false; // RETURN
710 for (size_t __n = 0; __n < __ht1.bucket_count(); ++__n) {
711 const _Node* __cur1 = __ht1._M_get_bucket(__n);
712 const _Node* __cur2 = __ht2._M_get_bucket(__n);
713 for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val;
714 __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
715 {}
716 if (__cur1 || __cur2)
717 return false; // RETURN
718 }
719 return true;
720}
721
722template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
723pair< _Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All> , bool>
726{
727 const size_type __n = _M_bkt_num(__obj);
728 _Node* __first = (_Node*)_M_buckets[__n];
729
730 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
731 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
732 return pair<iterator, bool>(iterator(__cur, this), false); // RETURN
733
734 _Node* __tmp = _M_new_node(__obj);
735 __tmp->_M_next = __first;
736 _M_buckets[__n] = __tmp;
737 ++_M_num_elements._M_data;
738 return pair<iterator, bool>(iterator(__tmp, this), true);
739}
740
741template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
742typename hashtable < _Val , _Key , _HF , _ExK , _EqK , _All > :: iterator
745{
746 const size_type __n = _M_bkt_num(__obj);
747 _Node* __first = (_Node*)_M_buckets[__n];
748
749 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
750 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
751 _Node* __tmp = _M_new_node(__obj);
752 __tmp->_M_next = __cur->_M_next;
753 __cur->_M_next = __tmp;
754 ++_M_num_elements._M_data;
755 return iterator(__tmp, this); // RETURN
756 }
757
758 _Node* __tmp = _M_new_node(__obj);
759 __tmp->_M_next = __first;
760 _M_buckets[__n] = __tmp;
761 ++_M_num_elements._M_data;
762 return iterator(__tmp, this);
763}
764
765template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
766typename hashtable < _Val , _Key , _HF , _ExK , _EqK , _All > :: reference
768{
769 resize(_M_num_elements._M_data + 1);
770
771 size_type __n = _M_bkt_num(__obj);
772 _Node* __first = (_Node*)_M_buckets[__n];
773
774 _Node* __tmp = _M_new_node(__obj);
775 __tmp->_M_next = __first;
776 _M_buckets[__n] = __tmp;
777 ++_M_num_elements._M_data;
778 return __tmp->_M_val;
779}
780
781template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
782typename hashtable < _Val , _Key , _HF , _ExK , _EqK , _All > :: reference
784{
785
786 _Node* __first = _M_find(_M_get_key(__obj));
787 if (__first)
788 return __first->_M_val; // RETURN
789 else
790 return _M_insert(__obj); // RETURN
791}
792
793template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
794pair< _Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All>,
795 _Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All> >
797{
798 typedef pair<iterator, iterator> _Pii;
799 const size_type __n = _M_bkt_num_key(__key);
800
801 for (_Node* __first = (_Node*)_M_buckets[__n]; __first; __first = __first->_M_next)
802 if (_M_equals(_M_get_key(__first->_M_val), __key)) {
803 for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next)
804 if (!_M_equals(_M_get_key(__cur->_M_val), __key))
805 return _Pii(iterator(__first, this), iterator(__cur, this));
806 // RETURN
807 for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
808 if (_M_buckets[__m])
809 return _Pii(iterator(__first, this),
810 iterator((_Node*)_M_buckets[__m], this)); // RETURN
811 return _Pii(iterator(__first, this), end()); // RETURN
812 }
813 return _Pii(end(), end());
814}
815
816template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
817pair< _Ht_iterator<_Val, _Const_traits<_Val>, _Key, _HF, _ExK, _EqK, _All>,
818 _Ht_iterator<_Val, _Const_traits<_Val>, _Key, _HF, _ExK, _EqK, _All> >
820 ::equal_range(const key_type& __key) const
821{
823 const size_type __n = _M_bkt_num_key(__key);
824
825 for (const _Node* __first = (_Node*)_M_buckets[__n] ;
826 __first;
827 __first = __first->_M_next) {
828 if (_M_equals(_M_get_key(__first->_M_val), __key)) {
829 for (const _Node* __cur = __first->_M_next;
830 __cur;
831 __cur = __cur->_M_next)
832 if (!_M_equals(_M_get_key(__cur->_M_val), __key))
833 return _Pii(const_iterator(__first, this),
834 const_iterator(__cur, this)); // RETURN
835 for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
836 if (_M_buckets[__m])
837 return _Pii(const_iterator(__first, this),
838 const_iterator((_Node*)_M_buckets[__m], this)); // RETURN
839 return _Pii(const_iterator(__first, this), end()); // RETURN
840 }
841 }
842 return _Pii(end(), end());
843}
844
845template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
846typename hashtable < _Val , _Key , _HF , _ExK , _EqK , _All > :: size_type
848{
849 const size_type __n = _M_bkt_num_key(__key);
850 _Node* __first = (_Node*)_M_buckets[__n];
851 size_type __erased = 0;
852
853 if (__first) {
854 _Node* __cur = __first;
855 _Node* __next = __cur->_M_next;
856 while (__next) {
857 if (_M_equals(_M_get_key(__next->_M_val), __key)) {
858 __cur->_M_next = __next->_M_next;
859 _M_delete_node(__next);
860 __next = __cur->_M_next;
861 ++__erased;
862 --_M_num_elements._M_data;
863 }
864 else {
865 __cur = __next;
866 __next = __cur->_M_next;
867 }
868 }
869 if (_M_equals(_M_get_key(__first->_M_val), __key)) {
870 _M_buckets[__n] = __first->_M_next;
871 _M_delete_node(__first);
872 ++__erased;
873 --_M_num_elements._M_data;
874 }
875 }
876 return __erased;
877}
878
879template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
881{
882 // const iterator& __it = __REINTERPRET_CAST(const iterator&,_c_it);
883 const _Node* __p = __it._M_cur;
884 if (__p) {
885 const size_type __n = _M_bkt_num(__p->_M_val);
886 _Node* __cur = (_Node*)_M_buckets[__n];
887
888 if (__cur == __p) {
889 _M_buckets[__n] = __cur->_M_next;
890 _M_delete_node(__cur);
891 --_M_num_elements._M_data;
892 }
893 else {
894 _Node* __next = __cur->_M_next;
895 while (__next) {
896 if (__next == __p) {
897 __cur->_M_next = __next->_M_next;
898 _M_delete_node(__next);
899 --_M_num_elements._M_data;
900 break;
901 }
902 else {
903 __cur = __next;
904 __next = __cur->_M_next;
905 }
906 }
907 }
908 }
909}
910
911template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
914{
915 iterator& __first = (iterator&)_c_first;
916 iterator& __last = (iterator&)_c_last;
917 size_type __f_bucket = __first._M_cur ?
918 _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
919 size_type __l_bucket = __last._M_cur ?
920 _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
921 if (__first._M_cur == __last._M_cur)
922 return; // RETURN
923 else if (__f_bucket == __l_bucket)
924 _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
925 else {
926 _M_erase_bucket(__f_bucket, __first._M_cur, 0);
927 for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
928 _M_erase_bucket(__n, 0);
929 if (__l_bucket != _M_buckets.size())
930 _M_erase_bucket(__l_bucket, __last._M_cur);
931 }
932}
933
934template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
936 ::resize(size_type __num_elements_hint)
937{
938 const size_type __old_n = _M_buckets.size();
939 if (__num_elements_hint > __old_n) {
940 const size_type __n = _M_next_size(__num_elements_hint);
941 if (__n > __old_n) {
942 _BucketVector __tmp(__n, (void*)(0),
943 _M_buckets.get_allocator());
944 BSLS_TRY {
945 for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
946 _Node* __first = (_Node*)_M_buckets[__bucket];
947 while (__first) {
948 size_type __new_bucket = _M_bkt_num(__first->_M_val, __n);
949 _M_buckets[__bucket] = __first->_M_next;
950 __first->_M_next = (_Node*)__tmp[__new_bucket];
951 __tmp[__new_bucket] = __first;
952 __first = (_Node*)_M_buckets[__bucket];
953 }
954 }
955 _M_buckets.swap(__tmp);
956 }
957 BSLS_CATCH(...) {
958 for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
959 while (__tmp[__bucket]) {
960 _Node* __next = ((_Node*)__tmp[__bucket])->_M_next;
961 _M_delete_node((_Node*)__tmp[__bucket]);
962 __tmp[__bucket] = __next;
963 }
964 }
966 }
967 }
968 }
969}
970
971template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
973 ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
974{
975 _Node* __cur = (_Node*)_M_buckets[__n];
976 if (__cur == __first)
977 _M_erase_bucket(__n, __last);
978 else {
979 _Node* __next;
980 for (__next = __cur->_M_next;
981 __next != __first;
982 __cur = __next, __next = __cur->_M_next)
983 ;
984 while (__next != __last) {
985 __cur->_M_next = __next->_M_next;
986 _M_delete_node(__next);
987 __next = __cur->_M_next;
988 --_M_num_elements._M_data;
989 }
990 }
991}
992
993template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
994void hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
995 ::_M_erase_bucket(const size_type __n, _Node* __last)
996{
997 _Node* __cur = (_Node*)_M_buckets[__n];
998 while (__cur && __cur != __last) {
999 _Node* __next = __cur->_M_next;
1000 _M_delete_node(__cur);
1001 __cur = __next;
1002 _M_buckets[__n] = __cur;
1003 --_M_num_elements._M_data;
1004 }
1005}
1006
1007template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
1009{
1010 for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
1011 _Node* __cur = (_Node*)_M_buckets[__i];
1012 while (__cur != 0) {
1013 _Node* __next = __cur->_M_next;
1014 _M_delete_node(__cur);
1015 __cur = __next;
1016 }
1017 _M_buckets[__i] = 0;
1018 }
1019 _M_num_elements._M_data = 0;
1020}
1021
1022
1023template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
1026{
1027 _M_buckets.clear();
1028 _M_buckets.reserve(__ht._M_buckets.size());
1029 _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (void*) 0);
1030 BSLS_TRY {
1031 for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
1032 const _Node* __cur = (_Node*)__ht._M_buckets[__i];
1033 if (__cur) {
1034 _Node* __xcopy = _M_new_node(__cur->_M_val);
1035 _M_buckets[__i] = __xcopy;
1036
1037 for (_Node* __next = __cur->_M_next;
1038 __next;
1039 __cur = __next, __next = __cur->_M_next) {
1040 __xcopy->_M_next = _M_new_node(__next->_M_val);
1041 __xcopy = __xcopy->_M_next;
1042 }
1043 }
1044 }
1045 _M_num_elements._M_data = __ht._M_num_elements._M_data;
1046 }
1047 BSLS_CATCH(...) {
1048 clear();
1050 }
1051}
1052
1053} // close namespace bsl
1054
1055// Local Variables:
1056// mode:C++
1057// End:
1058// END FORMER CONTENTS OF bslstp_hashtable.c
1059
1060#endif /* INCLUDED_BSLSTP_HASHTABLE */
1061
1062// Local Variables:
1063// mode:C++
1064// End:
1065
1066/** @} */
1067/** @} */
1068/** @} */
#define BSLSTP_STL_PRIME_LIST_BODY
Definition bslstp_hashtable.h:661
#define BSLSTP_STL_NUM_PRIMES
Definition bslstp_hashtable.h:209
Definition bslstp_alloc.h:105
_Value _M_data
Definition bslstp_alloc.h:112
_MaybeReboundAlloc get_allocator() const
Definition bslstp_alloc.h:115
Definition bslstp_hashtable.h:212
static const size_t _M_list[BSLSTP_STL_NUM_PRIMES]
Definition bslstp_hashtable.h:214
Definition bslstp_hashtable.h:230
size_type max_bucket_count() const
Definition bslstp_hashtable.h:413
iterator insert_equal_noresize(const value_type &__obj)
Definition bslstp_hashtable.h:744
reference find_or_insert(const value_type &__obj)
Definition bslstp_hashtable.h:783
void erase(const_iterator __first, const_iterator __last)
Definition bslstp_hashtable.h:913
~hashtable()
Definition bslstp_hashtable.h:375
void insert_equal(_InputIterator __f, _InputIterator __l)
Definition bslstp_hashtable.h:448
size_type erase(const key_type &__key)
Definition bslstp_hashtable.h:847
hasher hash_funct() const
Definition bslstp_hashtable.h:247
iterator begin()
Definition bslstp_hashtable.h:386
_HF hasher
Definition bslstp_hashtable.h:236
size_type max_size() const
Definition bslstp_hashtable.h:378
value_type & reference
Definition bslstp_hashtable.h:243
void erase(const const_iterator &__it)
Definition bslstp_hashtable.h:880
pair< iterator, iterator > equal_range(const key_type &__key)
Definition bslstp_hashtable.h:796
_Ht_iterator< _Val, __nonconst_val_traits, _Key, _HF, _ExK, _EqK, _All > iterator
Definition bslstp_hashtable.h:297
ptrdiff_t difference_type
Definition bslstp_hashtable.h:240
allocator_type get_allocator() const
Definition bslstp_hashtable.h:281
_Key key_type
Definition bslstp_hashtable.h:234
iterator insert_equal(const value_type &__obj)
Definition bslstp_hashtable.h:430
void insert_unique(_InputIterator __f, _InputIterator __l)
Definition bslstp_hashtable.h:440
iterator end()
Definition bslstp_hashtable.h:394
void swap(_Self &__ht)
Definition bslstp_hashtable.h:381
_Nonconst_traits< _Val > __nonconst_val_traits
Definition bslstp_hashtable.h:295
size_type size() const
Definition bslstp_hashtable.h:377
static bool _M_equal(const hashtable< _Val, _Key, _HF, _ExK, _EqK, _All > &, const hashtable< _Val, _Key, _HF, _ExK, _EqK, _All > &)
Definition bslstp_hashtable.h:703
std::forward_iterator_tag _Iterator_category
Definition bslstp_hashtable.h:245
key_equal key_eq() const
Definition bslstp_hashtable.h:248
const_iterator find(const _KT &__key) const
Definition bslstp_hashtable.h:516
pair< iterator, bool > insert_unique(const value_type &__obj)
Definition bslstp_hashtable.h:424
_Const_traits< _Val > __const_val_traits
Definition bslstp_hashtable.h:294
_Self & operator=(const _Self &__ht)
Definition bslstp_hashtable.h:363
size_type count(const key_type &__key) const
Definition bslstp_hashtable.h:521
pair< iterator, bool > insert_unique_noresize(const value_type &__obj)
Definition bslstp_hashtable.h:725
const_iterator end() const
Definition bslstp_hashtable.h:404
value_type * pointer
Definition bslstp_hashtable.h:241
void resize(size_type __num_elements_hint)
Definition bslstp_hashtable.h:936
const value_type & const_reference
Definition bslstp_hashtable.h:244
size_type bucket_count() const
Definition bslstp_hashtable.h:411
_EqK key_equal
Definition bslstp_hashtable.h:237
size_type elems_in_bucket(size_type __bucket) const
Definition bslstp_hashtable.h:416
bool empty() const
Definition bslstp_hashtable.h:379
hashtable(size_type __n, const _HF &__hf, const _EqK &__eql, const allocator_type &__a=allocator_type())
Definition bslstp_hashtable.h:318
pair< const_iterator, const_iterator > equal_range(const key_type &__key) const
Definition bslstp_hashtable.h:820
hashtable(const _Self &__ht, const allocator_type &__a)
Definition bslstp_hashtable.h:352
void insert_unique(_InputIterator __f, _InputIterator __l, const std::input_iterator_tag &)
Definition bslstp_hashtable.h:458
hashtable(const _Self &__ht)
Definition bslstp_hashtable.h:341
_Ht_iterator< _Val, __const_val_traits, _Key, _HF, _ExK, _EqK, _All > const_iterator
Definition bslstp_hashtable.h:296
_Val value_type
Definition bslstp_hashtable.h:235
void insert_equal(_InputIterator __f, _InputIterator __l, const std::input_iterator_tag &)
Definition bslstp_hashtable.h:466
const value_type * const_pointer
Definition bslstp_hashtable.h:242
friend struct QuickSwap
Definition bslstp_hashtable.h:254
size_t size_type
Definition bslstp_hashtable.h:239
void insert_equal(_ForwardIterator __f, _ForwardIterator __l, const std::forward_iterator_tag &)
Definition bslstp_hashtable.h:484
reference _M_insert(const value_type &__obj)
Definition bslstp_hashtable.h:767
hashtable(size_type __n, const _HF &__hf, const _EqK &__eql, const _ExK &__ext, const allocator_type &__a=allocator_type())
Definition bslstp_hashtable.h:303
const_iterator begin() const
Definition bslstp_hashtable.h:396
iterator find(const _KT &__key)
Definition bslstp_hashtable.h:510
void insert_unique(_ForwardIterator __f, _ForwardIterator __l, const std::forward_iterator_tag &)
Definition bslstp_hashtable.h:474
_Alloc_traits< _Val, _All >::allocator_type allocator_type
Definition bslstp_hashtable.h:280
void clear()
Definition bslstp_hashtable.h:1008
Definition bslstl_pair.h:1210
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:2664
#define BSLS_CATCH(X)
Definition bsls_exceptionutil.h:372
#define BSLS_TRY
Definition bsls_exceptionutil.h:370
#define BSLS_RETHROW
Definition bsls_exceptionutil.h:378
#define BSLS_UTIL_ADDRESSOF(OBJ)
Definition bsls_util.h:289
Definition bdlb_printmethods.h:283
_Stl_prime< bool > _Stl_prime_type
Definition bslstp_hashtable.h:217
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
Definition bslstp_exfunctional.h:323
void swap(TYPE &a, TYPE &b)
_Rebind_type::other allocator_type
Definition bslstp_alloc.h:98
Definition bslstp_iterator.h:96
Definition bslstp_hashtable.h:127
_Hashtable_node< _Val > _Node
Definition bslstp_hashtable.h:130
_Node * _M_skip_to_next()
Definition bslstp_hashtable.h:679
hashtable< _Val, _Key, _HF, _ExK, _EqK, _All > _Hashtable
Definition bslstp_hashtable.h:129
_Hashtable_iterator(_Node *__n, _Hashtable *__tab)
Definition bslstp_hashtable.h:135
_Node * _M_cur
Definition bslstp_hashtable.h:132
_Hashtable_iterator()
Definition bslstp_hashtable.h:137
_Hashtable * _M_ht
Definition bslstp_hashtable.h:133
Definition bslstp_hashtable.h:113
_Hashtable_node< _Val > _Self
Definition bslstp_hashtable.h:114
_Val _M_val
Definition bslstp_hashtable.h:116
_Self * _M_next
Definition bslstp_hashtable.h:115
Definition bslstp_hashtable.h:146
reference operator*() const
Definition bslstp_hashtable.h:171
_Hashtable_iterator< _Val, _Key, _HF, _ExK, _EqK, _All > _Base
Definition bslstp_hashtable.h:148
_Ht_iterator()
Definition bslstp_hashtable.h:167
_Val value_type
Definition bslstp_hashtable.h:157
ptrdiff_t difference_type
Definition bslstp_hashtable.h:159
_Traits::reference reference
Definition bslstp_hashtable.h:161
_Ht_iterator(const _Node *__n, const _Hashtable *__tab)
Definition bslstp_hashtable.h:164
_Traits::pointer pointer
Definition bslstp_hashtable.h:162
_Self operator++(int)
Definition bslstp_hashtable.h:183
pointer operator->() const
Definition bslstp_hashtable.h:175
_Hashtable_node< _Val > _Node
Definition bslstp_hashtable.h:155
size_t size_type
Definition bslstp_hashtable.h:160
std::forward_iterator_tag iterator_category
Definition bslstp_hashtable.h:158
_Self & operator++()
Definition bslstp_hashtable.h:177
hashtable< _Val, _Key, _HF, _ExK, _EqK, _All > _Hashtable
Definition bslstp_hashtable.h:154
_Ht_iterator(const _Ht_iterator< _Val, _Nonconst_traits< _Val >, _Key, _HF, _ExK, _EqK, _All > &__it)
Definition bslstp_hashtable.h:168
_Ht_iterator< _Val, _Traits, _Key, _HF, _ExK, _EqK, _All > _Self
Definition bslstp_hashtable.h:152
Definition bslstp_iterator.h:104