_hashtable.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. /*
  2. *
  3. * Copyright (c) 1994
  4. * Hewlett-Packard Company
  5. *
  6. * Copyright (c) 1996,1997
  7. * Silicon Graphics Computer Systems, Inc.
  8. *
  9. * Copyright (c) 1997
  10. * Moscow Center for SPARC Technology
  11. *
  12. * Copyright (c) 1999
  13. * Boris Fomitchev
  14. *
  15. * This material is provided "as is", with absolutely no warranty expressed
  16. * or implied. Any use is at your own risk.
  17. *
  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.
  23. *
  24. */
  25. /* NOTE: This is an internal header file, included by other STL headers.
  26. * You should not attempt to use it directly.
  27. */
  28. #ifndef _STLP_INTERNAL_HASHTABLE_H
  29. #define _STLP_INTERNAL_HASHTABLE_H
  30. #ifndef _STLP_INTERNAL_VECTOR_H
  31. # include <stl/_vector.h>
  32. #endif
  33. #ifndef _STLP_INTERNAL_SLIST_H
  34. # include <stl/_slist.h>
  35. #endif
  36. #ifndef _STLP_INTERNAL_ITERATOR_H
  37. # include <stl/_iterator.h>
  38. #endif
  39. #ifndef _STLP_INTERNAL_FUNCTION_BASE_H
  40. # include <stl/_function_base.h>
  41. #endif
  42. #ifndef _STLP_INTERNAL_ALGOBASE_H
  43. # include <stl/_algobase.h>
  44. #endif
  45. #ifndef _STLP_HASH_FUN_H
  46. # include <stl/_hash_fun.h>
  47. #endif
  48. /*
  49. * Hashtable class, used to implement the hashed associative containers
  50. * hash_set, hash_map, hash_multiset, hash_multimap,
  51. * unordered_set, unordered_map, unordered_multiset, unordered_multimap.
  52. */
  53. _STLP_BEGIN_NAMESPACE
  54. #if defined (_STLP_USE_TEMPLATE_EXPORT)
  55. //Export of the classes used to represent buckets in the hashtable implementation.
  56. # if !defined (_STLP_USE_PTR_SPECIALIZATIONS)
  57. //If pointer specialization is enabled vector<_Slist_node_base*> will use the void*
  58. //storage type for which internal classes have already been exported.
  59. _STLP_EXPORT_TEMPLATE_CLASS allocator<_STLP_PRIV _Slist_node_base*>;
  60. _STLP_MOVE_TO_PRIV_NAMESPACE
  61. _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<_Slist_node_base**, _Slist_node_base*,
  62. allocator<_Slist_node_base*> >;
  63. _STLP_EXPORT_TEMPLATE_CLASS _Vector_base<_Slist_node_base*,
  64. allocator<_Slist_node_base*> >;
  65. _STLP_MOVE_TO_STD_NAMESPACE
  66. # endif
  67. # if defined (_STLP_DEBUG)
  68. _STLP_MOVE_TO_PRIV_NAMESPACE
  69. # define _STLP_NON_DBG_VECTOR _STLP_NON_DBG_NAME(vector)
  70. _STLP_EXPORT_TEMPLATE_CLASS __construct_checker<_STLP_NON_DBG_VECTOR<_Slist_node_base*, allocator<_Slist_node_base*> > >;
  71. _STLP_EXPORT_TEMPLATE_CLASS _STLP_NON_DBG_VECTOR<_Slist_node_base*, allocator<_Slist_node_base*> >;
  72. # undef _STLP_NON_DBG_VECTOR
  73. _STLP_MOVE_TO_STD_NAMESPACE
  74. # endif
  75. _STLP_EXPORT_TEMPLATE_CLASS vector<_STLP_PRIV _Slist_node_base*,
  76. allocator<_STLP_PRIV _Slist_node_base*> >;
  77. #endif
  78. #if defined (_STLP_DEBUG)
  79. # define hashtable _STLP_NON_DBG_NAME(hashtable)
  80. _STLP_MOVE_TO_PRIV_NAMESPACE
  81. #endif
  82. // some compilers require the names of template parameters to be the same
  83. template <class _Val, class _Key, class _HF,
  84. class _Traits, class _ExK, class _EqK, class _All>
  85. class hashtable;
  86. #if !defined (_STLP_DEBUG)
  87. _STLP_MOVE_TO_PRIV_NAMESPACE
  88. #endif
  89. template <class _BaseIte, class _Traits>
  90. struct _Ht_iterator {
  91. typedef typename _Traits::_ConstTraits _ConstTraits;
  92. typedef typename _Traits::_NonConstTraits _NonConstTraits;
  93. typedef _Ht_iterator<_BaseIte,_Traits> _Self;
  94. typedef typename _Traits::value_type value_type;
  95. typedef typename _Traits::pointer pointer;
  96. typedef typename _Traits::reference reference;
  97. typedef forward_iterator_tag iterator_category;
  98. typedef ptrdiff_t difference_type;
  99. typedef size_t size_type;
  100. typedef _Ht_iterator<_BaseIte, _NonConstTraits> iterator;
  101. typedef _Ht_iterator<_BaseIte, _ConstTraits> const_iterator;
  102. _Ht_iterator() {}
  103. //copy constructor for iterator and constructor from iterator for const_iterator
  104. _Ht_iterator(const iterator& __it) : _M_ite(__it._M_ite) {}
  105. _Ht_iterator(_BaseIte __it) : _M_ite(__it) {}
  106. reference operator*() const {
  107. return *_M_ite;
  108. }
  109. _STLP_DEFINE_ARROW_OPERATOR
  110. _Self& operator++() {
  111. ++_M_ite;
  112. return *this;
  113. }
  114. _Self operator++(int) {
  115. _Self __tmp = *this;
  116. ++*this;
  117. return __tmp;
  118. }
  119. bool operator == (const_iterator __rhs) const {
  120. return _M_ite == __rhs._M_ite;
  121. }
  122. bool operator != (const_iterator __rhs) const {
  123. return _M_ite != __rhs._M_ite;
  124. }
  125. _BaseIte _M_ite;
  126. };
  127. _STLP_MOVE_TO_STD_NAMESPACE
  128. #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
  129. template <class _BaseIte, class _Traits>
  130. struct __type_traits<_STLP_PRIV _Ht_iterator<_BaseIte, _Traits> > {
  131. typedef __false_type has_trivial_default_constructor;
  132. typedef __true_type has_trivial_copy_constructor;
  133. typedef __true_type has_trivial_assignment_operator;
  134. typedef __true_type has_trivial_destructor;
  135. typedef __false_type is_POD_type;
  136. };
  137. #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
  138. #if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES)
  139. template <class _BaseIte, class _Traits>
  140. inline
  141. # if defined (_STLP_NESTED_TYPE_PARAM_BUG)
  142. _STLP_TYPENAME_ON_RETURN_TYPE _Traits::value_type *
  143. # else
  144. _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>::value_type *
  145. # endif
  146. value_type(const _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>&) {
  147. typedef _STLP_TYPENAME _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>::value_type _Val;
  148. return (_Val*) 0;
  149. }
  150. template <class _BaseIte, class _Traits>
  151. inline forward_iterator_tag iterator_category(const _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>&)
  152. { return forward_iterator_tag(); }
  153. template <class _BaseIte, class _Traits>
  154. inline ptrdiff_t* distance_type(const _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>&)
  155. { return (ptrdiff_t*) 0; }
  156. #endif
  157. _STLP_MOVE_TO_PRIV_NAMESPACE
  158. template <class _Dummy>
  159. class _Stl_prime {
  160. // Returns begining of primes list and size by reference.
  161. static const size_t* _S_primes(size_t&);
  162. public:
  163. //Returns the maximum number of buckets handled by the hashtable implementation
  164. static size_t _STLP_CALL _S_max_nb_buckets();
  165. //Returns the bucket size next to a required size
  166. static size_t _STLP_CALL _S_next_size(size_t);
  167. // Returns the bucket range containing sorted list of prime numbers <= __hint.
  168. static void _STLP_CALL _S_prev_sizes(size_t __hint, const size_t *&__begin, const size_t *&__end);
  169. };
  170. #if defined (_STLP_USE_TEMPLATE_EXPORT)
  171. _STLP_EXPORT_TEMPLATE_CLASS _Stl_prime<bool>;
  172. #endif
  173. typedef _Stl_prime<bool> _Stl_prime_type;
  174. #if !defined (_STLP_DEBUG)
  175. _STLP_MOVE_TO_STD_NAMESPACE
  176. #endif
  177. /*
  178. * Hashtables handle allocators a bit differently than other containers
  179. * do. If we're using standard-conforming allocators, then a hashtable
  180. * unconditionally has a member variable to hold its allocator, even if
  181. * it so happens that all instances of the allocator type are identical.
  182. * This is because, for hashtables, this extra storage is negligible.
  183. * Additionally, a base class wouldn't serve any other purposes; it
  184. * wouldn't, for example, simplify the exception-handling code.
  185. */
  186. template <class _Val, class _Key, class _HF,
  187. class _Traits, class _ExK, class _EqK, class _All>
  188. class hashtable {
  189. typedef hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All> _Self;
  190. typedef typename _Traits::_NonConstTraits _NonConstTraits;
  191. typedef typename _Traits::_ConstTraits _ConstTraits;
  192. typedef typename _Traits::_NonConstLocalTraits _NonConstLocalTraits;
  193. typedef typename _Traits::_ConstLocalTraits _ConstLocalTraits;
  194. public:
  195. typedef _Key key_type;
  196. typedef _Val value_type;
  197. typedef _HF hasher;
  198. typedef _EqK key_equal;
  199. typedef size_t size_type;
  200. typedef ptrdiff_t difference_type;
  201. typedef typename _NonConstTraits::pointer pointer;
  202. typedef const value_type* const_pointer;
  203. typedef typename _NonConstTraits::reference reference;
  204. typedef const value_type& const_reference;
  205. typedef forward_iterator_tag _Iterator_category;
  206. hasher hash_funct() const { return _M_hash; }
  207. key_equal key_eq() const { return _M_equals; }
  208. private:
  209. _STLP_FORCE_ALLOCATORS(_Val, _All)
  210. #if defined (_STLP_DEBUG)
  211. typedef _STLP_PRIV _STLP_NON_DBG_NAME(slist)<value_type, _All> _ElemsCont;
  212. #else
  213. typedef slist<value_type, _All> _ElemsCont;
  214. #endif
  215. typedef typename _ElemsCont::iterator _ElemsIte;
  216. typedef typename _ElemsCont::const_iterator _ElemsConstIte;
  217. typedef _STLP_PRIV _Slist_node_base _BucketType;
  218. typedef typename _Alloc_traits<_BucketType*, _All>::allocator_type _BucketAllocType;
  219. /*
  220. * We are going to use vector of _Slist_node_base pointers for 2 reasons:
  221. * - limit code bloat, all hashtable instanciation use the same buckets representation.
  222. * - avoid _STLP_DEBUG performance trouble: with a vector of iterator on slist the resize
  223. * method would be too slow because the slist::splice_after method become linear on
  224. * the number of iterators in the buckets rather than constant in time as the iterator
  225. * has to be move from a slist to the other.
  226. */
  227. #if defined (_STLP_DEBUG)
  228. typedef _STLP_PRIV _STLP_NON_DBG_NAME(vector)<_BucketType*, _BucketAllocType> _BucketVector;
  229. #else
  230. typedef vector<_BucketType*, _BucketAllocType> _BucketVector;
  231. #endif
  232. hasher _M_hash;
  233. key_equal _M_equals;
  234. _ElemsCont _M_elems;
  235. _BucketVector _M_buckets;
  236. size_type _M_num_elements;
  237. float _M_max_load_factor;
  238. _STLP_KEY_TYPE_FOR_CONT_EXT(key_type)
  239. static const key_type& _M_get_key(const value_type& __val) {
  240. _ExK k;
  241. return k(__val);
  242. }
  243. public:
  244. typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _NonConstTraits> iterator;
  245. typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _ConstTraits> const_iterator;
  246. //TODO: Avoids this debug check and make the local_iterator different from
  247. //iterator in debug mode too.
  248. #if !defined (_STLP_DEBUG)
  249. typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _NonConstLocalTraits> local_iterator;
  250. typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _ConstLocalTraits> const_local_iterator;
  251. #else
  252. typedef iterator local_iterator;
  253. typedef const_iterator const_local_iterator;
  254. #endif
  255. typedef _All allocator_type;
  256. allocator_type get_allocator() const { return _M_elems.get_allocator(); }
  257. #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
  258. hashtable(size_type __n,
  259. const _HF& __hf,
  260. const _EqK& __eql,
  261. const allocator_type& __a = allocator_type())
  262. #else
  263. hashtable(size_type __n,
  264. const _HF& __hf,
  265. const _EqK& __eql)
  266. : _M_hash(__hf),
  267. _M_equals(__eql),
  268. _M_elems(allocator_type()),
  269. _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)),
  270. _M_num_elements(0),
  271. _M_max_load_factor(1.0f)
  272. { _M_initialize_buckets(__n); }
  273. hashtable(size_type __n,
  274. const _HF& __hf,
  275. const _EqK& __eql,
  276. const allocator_type& __a)
  277. #endif
  278. : _M_hash(__hf),
  279. _M_equals(__eql),
  280. _M_elems(__a),
  281. _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)),
  282. _M_num_elements(0),
  283. _M_max_load_factor(1.0f)
  284. { _M_initialize_buckets(__n); }
  285. hashtable(const _Self& __ht)
  286. : _M_hash(__ht._M_hash),
  287. _M_equals(__ht._M_equals),
  288. _M_elems(__ht.get_allocator()),
  289. _M_buckets(_STLP_CONVERT_ALLOCATOR(__ht.get_allocator(), _BucketType*)),
  290. _M_num_elements(0),
  291. _M_max_load_factor(1.0f)
  292. { _M_copy_from(__ht); }
  293. #if !defined (_STLP_NO_MOVE_SEMANTIC)
  294. hashtable(__move_source<_Self> src)
  295. : _M_hash(_STLP_PRIV _AsMoveSource(src.get()._M_hash)),
  296. _M_equals(_STLP_PRIV _AsMoveSource(src.get()._M_equals)),
  297. _M_elems(__move_source<_ElemsCont>(src.get()._M_elems)),
  298. _M_buckets(__move_source<_BucketVector>(src.get()._M_buckets)),
  299. _M_num_elements(src.get()._M_num_elements),
  300. _M_max_load_factor(src.get()._M_max_load_factor) {}
  301. #endif
  302. _Self& operator= (const _Self& __ht) {
  303. if (&__ht != this) {
  304. clear();
  305. _M_hash = __ht._M_hash;
  306. _M_equals = __ht._M_equals;
  307. _M_copy_from(__ht);
  308. }
  309. return *this;
  310. }
  311. ~hashtable() { clear(); }
  312. size_type size() const { return _M_num_elements; }
  313. size_type max_size() const { return size_type(-1); }
  314. bool empty() const { return size() == 0; }
  315. void swap(_Self& __ht) {
  316. _STLP_STD::swap(_M_hash, __ht._M_hash);
  317. _STLP_STD::swap(_M_equals, __ht._M_equals);
  318. _M_elems.swap(__ht._M_elems);
  319. _M_buckets.swap(__ht._M_buckets);
  320. _STLP_STD::swap(_M_num_elements, __ht._M_num_elements);
  321. _STLP_STD::swap(_M_max_load_factor, __ht._M_max_load_factor);
  322. }
  323. iterator begin() { return _M_elems.begin(); }
  324. iterator end() { return _M_elems.end(); }
  325. local_iterator begin(size_type __n) { return _ElemsIte(_M_buckets[__n]); }
  326. local_iterator end(size_type __n) { return _ElemsIte(_M_buckets[__n + 1]); }
  327. const_iterator begin() const { return __CONST_CAST(_ElemsCont&, _M_elems).begin(); }
  328. const_iterator end() const { return __CONST_CAST(_ElemsCont&, _M_elems).end(); }
  329. const_local_iterator begin(size_type __n) const { return _ElemsIte(_M_buckets[__n]); }
  330. const_local_iterator end(size_type __n) const { return _ElemsIte(_M_buckets[__n + 1]); }
  331. //static bool _STLP_CALL _M_equal (const _Self&, const _Self&);
  332. public:
  333. //The number of buckets is size() - 1 because the last bucket always contains
  334. //_M_elems.end() to make algo easier to implement.
  335. size_type bucket_count() const { return _M_buckets.size() - 1; }
  336. size_type max_bucket_count() const { return _STLP_PRIV _Stl_prime_type::_S_max_nb_buckets(); }
  337. size_type elems_in_bucket(size_type __bucket) const
  338. { return _STLP_STD::distance(_ElemsIte(_M_buckets[__bucket]), _ElemsIte(_M_buckets[__bucket + 1])); }
  339. _STLP_TEMPLATE_FOR_CONT_EXT
  340. size_type bucket(const _KT& __k) const { return _M_bkt_num_key(__k); }
  341. // hash policy
  342. float load_factor() const { return (float)size() / (float)bucket_count(); }
  343. float max_load_factor() const { return _M_max_load_factor; }
  344. void max_load_factor(float __z) {
  345. _M_max_load_factor = __z;
  346. _M_resize();
  347. }
  348. pair<iterator, bool> insert_unique(const value_type& __obj) {
  349. _M_enlarge(_M_num_elements + 1);
  350. return insert_unique_noresize(__obj);
  351. }
  352. iterator insert_equal(const value_type& __obj) {
  353. _M_enlarge(_M_num_elements + 1);
  354. return insert_equal_noresize(__obj);
  355. }
  356. protected:
  357. iterator _M_insert_noresize(size_type __n, const value_type& __obj);
  358. public:
  359. pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
  360. iterator insert_equal_noresize(const value_type& __obj);
  361. #if defined (_STLP_MEMBER_TEMPLATES)
  362. template <class _InputIterator>
  363. void insert_unique(_InputIterator __f, _InputIterator __l)
  364. { insert_unique(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator)); }
  365. template <class _InputIterator>
  366. void insert_equal(_InputIterator __f, _InputIterator __l)
  367. { insert_equal(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator)); }
  368. template <class _InputIterator>
  369. void insert_unique(_InputIterator __f, _InputIterator __l,
  370. const input_iterator_tag &) {
  371. for ( ; __f != __l; ++__f)
  372. insert_unique(*__f);
  373. }
  374. template <class _InputIterator>
  375. void insert_equal(_InputIterator __f, _InputIterator __l,
  376. const input_iterator_tag &) {
  377. for ( ; __f != __l; ++__f)
  378. insert_equal(*__f);
  379. }
  380. template <class _ForwardIterator>
  381. void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
  382. const forward_iterator_tag &) {
  383. size_type __n = _STLP_STD::distance(__f, __l);
  384. _M_enlarge(_M_num_elements + __n);
  385. for ( ; __n > 0; --__n, ++__f)
  386. insert_unique_noresize(*__f);
  387. }
  388. template <class _ForwardIterator>
  389. void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
  390. const forward_iterator_tag &) {
  391. size_type __n = _STLP_STD::distance(__f, __l);
  392. _M_enlarge(_M_num_elements + __n);
  393. for ( ; __n > 0; --__n, ++__f)
  394. insert_equal_noresize(*__f);
  395. }
  396. #else /* _STLP_MEMBER_TEMPLATES */
  397. void insert_unique(const value_type* __f, const value_type* __l) {
  398. size_type __n = __l - __f;
  399. _M_enlarge(_M_num_elements + __n);
  400. for ( ; __n > 0; --__n, ++__f)
  401. insert_unique_noresize(*__f);
  402. }
  403. void insert_equal(const value_type* __f, const value_type* __l) {
  404. size_type __n = __l - __f;
  405. _M_enlarge(_M_num_elements + __n);
  406. for ( ; __n > 0; --__n, ++__f)
  407. insert_equal_noresize(*__f);
  408. }
  409. void insert_unique(const_iterator __f, const_iterator __l) {
  410. size_type __n = _STLP_STD::distance(__f, __l);
  411. _M_enlarge(_M_num_elements + __n);
  412. for ( ; __n > 0; --__n, ++__f)
  413. insert_unique_noresize(*__f);
  414. }
  415. void insert_equal(const_iterator __f, const_iterator __l) {
  416. size_type __n = _STLP_STD::distance(__f, __l);
  417. _M_enlarge(_M_num_elements + __n);
  418. for ( ; __n > 0; --__n, ++__f)
  419. insert_equal_noresize(*__f);
  420. }
  421. #endif /*_STLP_MEMBER_TEMPLATES */
  422. //reference find_or_insert(const value_type& __obj);
  423. private:
  424. _STLP_TEMPLATE_FOR_CONT_EXT
  425. _ElemsIte _M_find(const _KT& __key) const {
  426. size_type __n = _M_bkt_num_key(__key);
  427. _ElemsIte __first(_M_buckets[__n]);
  428. _ElemsIte __last(_M_buckets[__n + 1]);
  429. for ( ; (__first != __last) && !_M_equals(_M_get_key(*__first), __key); ++__first);
  430. if (__first != __last)
  431. return __first;
  432. else
  433. return __CONST_CAST(_ElemsCont&, _M_elems).end();
  434. }
  435. public:
  436. _STLP_TEMPLATE_FOR_CONT_EXT
  437. iterator find(const _KT& __key) { return _M_find(__key); }
  438. _STLP_TEMPLATE_FOR_CONT_EXT
  439. const_iterator find(const _KT& __key) const { return _M_find(__key); }
  440. _STLP_TEMPLATE_FOR_CONT_EXT
  441. size_type count(const _KT& __key) const {
  442. const size_type __n = _M_bkt_num_key(__key);
  443. _ElemsIte __cur(_M_buckets[__n]);
  444. _ElemsIte __last(_M_buckets[__n + 1]);
  445. for (; __cur != __last; ++__cur) {
  446. if (_M_equals(_M_get_key(*__cur), __key)) {
  447. size_type __result = 1;
  448. for (++__cur;
  449. __cur != __last && _M_equals(_M_get_key(*__cur), __key);
  450. ++__result, ++__cur);
  451. return __result;
  452. }
  453. }
  454. return 0;
  455. }
  456. _STLP_TEMPLATE_FOR_CONT_EXT
  457. pair<iterator, iterator> equal_range(const _KT& __key) {
  458. typedef pair<iterator, iterator> _Pii;
  459. const size_type __n = _M_bkt_num_key(__key);
  460. for (_ElemsIte __first(_M_buckets[__n]), __last(_M_buckets[__n + 1]);
  461. __first != __last; ++__first) {
  462. if (_M_equals(_M_get_key(*__first), __key)) {
  463. _ElemsIte __cur(__first);
  464. for (++__cur; (__cur != __last) && _M_equals(_M_get_key(*__cur), __key); ++__cur);
  465. return _Pii(__first, __cur);
  466. }
  467. }
  468. return _Pii(end(), end());
  469. }
  470. _STLP_TEMPLATE_FOR_CONT_EXT
  471. pair<const_iterator, const_iterator> equal_range(const _KT& __key) const {
  472. typedef pair<const_iterator, const_iterator> _Pii;
  473. const size_type __n = _M_bkt_num_key(__key);
  474. for (_ElemsIte __first(_M_buckets[__n]), __last(_M_buckets[__n + 1]);
  475. __first != __last; ++__first) {
  476. if (_M_equals(_M_get_key(*__first), __key)) {
  477. _ElemsIte __cur(__first);
  478. for (++__cur; (__cur != __last) && _M_equals(_M_get_key(*__cur), __key); ++__cur);
  479. return _Pii(__first, __cur);
  480. }
  481. }
  482. return _Pii(end(), end());
  483. }
  484. size_type erase(const key_type& __key);
  485. void erase(const_iterator __it);
  486. void erase(const_iterator __first, const_iterator __last);
  487. private:
  488. void _M_enlarge(size_type __n);
  489. void _M_reduce();
  490. void _M_resize();
  491. void _M_rehash(size_type __num_buckets);
  492. #if defined (_STLP_DEBUG)
  493. void _M_check() const;
  494. #endif
  495. public:
  496. void rehash(size_type __num_buckets_hint);
  497. void resize(size_type __num_buckets_hint)
  498. { rehash(__num_buckets_hint); }
  499. void clear();
  500. // this is for hash_map::operator[]
  501. reference _M_insert(const value_type& __obj);
  502. private:
  503. //__n is set to the first bucket that has to be modified if any
  504. //erase/insert operation is done after the returned iterator.
  505. iterator _M_before_begin(size_type &__n) const;
  506. static iterator _S_before_begin(const _ElemsCont& __elems, const _BucketVector& __buckets,
  507. size_type &__n);
  508. void _M_initialize_buckets(size_type __n) {
  509. const size_type __n_buckets = _STLP_PRIV _Stl_prime_type::_S_next_size(__n) + 1;
  510. _M_buckets.reserve(__n_buckets);
  511. _M_buckets.assign(__n_buckets, __STATIC_CAST(_BucketType*, 0));
  512. }
  513. _STLP_TEMPLATE_FOR_CONT_EXT
  514. size_type _M_bkt_num_key(const _KT& __key) const
  515. { return _M_bkt_num_key(__key, bucket_count()); }
  516. size_type _M_bkt_num(const value_type& __obj) const
  517. { return _M_bkt_num_key(_M_get_key(__obj)); }
  518. _STLP_TEMPLATE_FOR_CONT_EXT
  519. size_type _M_bkt_num_key(const _KT& __key, size_type __n) const
  520. { return _M_hash(__key) % __n; }
  521. size_type _M_bkt_num(const value_type& __obj, size_t __n) const
  522. { return _M_bkt_num_key(_M_get_key(__obj), __n); }
  523. void _M_copy_from(const _Self& __ht);
  524. };
  525. #if defined (_STLP_DEBUG)
  526. # undef hashtable
  527. _STLP_MOVE_TO_STD_NAMESPACE
  528. #endif
  529. _STLP_END_NAMESPACE
  530. #if !defined (_STLP_LINK_TIME_INSTANTIATION)
  531. # include <stl/_hashtable.c>
  532. #endif
  533. #if defined (_STLP_DEBUG)
  534. # include <stl/debug/_hashtable.h>
  535. #endif
  536. _STLP_BEGIN_NAMESPACE
  537. #define _STLP_TEMPLATE_HEADER template <class _Val, class _Key, class _HF, class _Traits, class _ExK, class _EqK, class _All>
  538. #define _STLP_TEMPLATE_CONTAINER hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
  539. #include <stl/_relops_hash_cont.h>
  540. #undef _STLP_TEMPLATE_CONTAINER
  541. #undef _STLP_TEMPLATE_HEADER
  542. #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_NO_MOVE_SEMANTIC)
  543. template <class _Val, class _Key, class _HF, class _Traits, class _ExK, class _EqK, class _All>
  544. struct __move_traits<hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All> > {
  545. //Hashtables are movable:
  546. typedef __true_type implemented;
  547. //Completeness depends on many template parameters, for the moment we consider it not complete:
  548. typedef __false_type complete;
  549. };
  550. #endif
  551. _STLP_END_NAMESPACE
  552. #endif /* _STLP_INTERNAL_HASHTABLE_H */
  553. // Local Variables:
  554. // mode:C++
  555. // End: