hashtable.h 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126
  1. // Hashtable implementation used by containers -*- C++ -*-
  2. // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
  3. // Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library. This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. // Under Section 7 of GPL version 3, you are granted additional
  15. // permissions described in the GCC Runtime Library Exception, version
  16. // 3.1, as published by the Free Software Foundation.
  17. // You should have received a copy of the GNU General Public License and
  18. // a copy of the GCC Runtime Library Exception along with this program;
  19. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  20. // <http://www.gnu.org/licenses/>.
  21. /*
  22. * Copyright (c) 1996,1997
  23. * Silicon Graphics Computer Systems, Inc.
  24. *
  25. * Permission to use, copy, modify, distribute and sell this software
  26. * and its documentation for any purpose is hereby granted without fee,
  27. * provided that the above copyright notice appear in all copies and
  28. * that both that copyright notice and this permission notice appear
  29. * in supporting documentation. Silicon Graphics makes no
  30. * representations about the suitability of this software for any
  31. * purpose. It is provided "as is" without express or implied warranty.
  32. *
  33. *
  34. * Copyright (c) 1994
  35. * Hewlett-Packard Company
  36. *
  37. * Permission to use, copy, modify, distribute and sell this software
  38. * and its documentation for any purpose is hereby granted without fee,
  39. * provided that the above copyright notice appear in all copies and
  40. * that both that copyright notice and this permission notice appear
  41. * in supporting documentation. Hewlett-Packard Company makes no
  42. * representations about the suitability of this software for any
  43. * purpose. It is provided "as is" without express or implied warranty.
  44. *
  45. */
  46. /** @file backward/hashtable.h
  47. * This file is a GNU extension to the Standard C++ Library (possibly
  48. * containing extensions from the HP/SGI STL subset).
  49. */
  50. #ifndef _BACKWARD_HASHTABLE_H
  51. #define _BACKWARD_HASHTABLE_H 1
  52. // Hashtable class, used to implement the hashed associative containers
  53. // hash_set, hash_map, hash_multiset, and hash_multimap.
  54. #include <vector>
  55. #include <iterator>
  56. #include <algorithm>
  57. #include <bits/stl_function.h>
  58. #include <backward/hash_fun.h>
  59. _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
  60. using std::size_t;
  61. using std::ptrdiff_t;
  62. using std::forward_iterator_tag;
  63. using std::input_iterator_tag;
  64. using std::_Construct;
  65. using std::_Destroy;
  66. using std::distance;
  67. using std::vector;
  68. using std::pair;
  69. using std::__iterator_category;
  70. template<class _Val>
  71. struct _Hashtable_node
  72. {
  73. _Hashtable_node* _M_next;
  74. _Val _M_val;
  75. };
  76. template<class _Val, class _Key, class _HashFcn, class _ExtractKey,
  77. class _EqualKey, class _Alloc = std::allocator<_Val> >
  78. class hashtable;
  79. template<class _Val, class _Key, class _HashFcn,
  80. class _ExtractKey, class _EqualKey, class _Alloc>
  81. struct _Hashtable_iterator;
  82. template<class _Val, class _Key, class _HashFcn,
  83. class _ExtractKey, class _EqualKey, class _Alloc>
  84. struct _Hashtable_const_iterator;
  85. template<class _Val, class _Key, class _HashFcn,
  86. class _ExtractKey, class _EqualKey, class _Alloc>
  87. struct _Hashtable_iterator
  88. {
  89. typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
  90. _Hashtable;
  91. typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
  92. _ExtractKey, _EqualKey, _Alloc>
  93. iterator;
  94. typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
  95. _ExtractKey, _EqualKey, _Alloc>
  96. const_iterator;
  97. typedef _Hashtable_node<_Val> _Node;
  98. typedef forward_iterator_tag iterator_category;
  99. typedef _Val value_type;
  100. typedef ptrdiff_t difference_type;
  101. typedef size_t size_type;
  102. typedef _Val& reference;
  103. typedef _Val* pointer;
  104. _Node* _M_cur;
  105. _Hashtable* _M_ht;
  106. _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
  107. : _M_cur(__n), _M_ht(__tab) { }
  108. _Hashtable_iterator() { }
  109. reference
  110. operator*() const
  111. { return _M_cur->_M_val; }
  112. pointer
  113. operator->() const
  114. { return &(operator*()); }
  115. iterator&
  116. operator++();
  117. iterator
  118. operator++(int);
  119. bool
  120. operator==(const iterator& __it) const
  121. { return _M_cur == __it._M_cur; }
  122. bool
  123. operator!=(const iterator& __it) const
  124. { return _M_cur != __it._M_cur; }
  125. };
  126. template<class _Val, class _Key, class _HashFcn,
  127. class _ExtractKey, class _EqualKey, class _Alloc>
  128. struct _Hashtable_const_iterator
  129. {
  130. typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
  131. _Hashtable;
  132. typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
  133. _ExtractKey,_EqualKey,_Alloc>
  134. iterator;
  135. typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
  136. _ExtractKey, _EqualKey, _Alloc>
  137. const_iterator;
  138. typedef _Hashtable_node<_Val> _Node;
  139. typedef forward_iterator_tag iterator_category;
  140. typedef _Val value_type;
  141. typedef ptrdiff_t difference_type;
  142. typedef size_t size_type;
  143. typedef const _Val& reference;
  144. typedef const _Val* pointer;
  145. const _Node* _M_cur;
  146. const _Hashtable* _M_ht;
  147. _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
  148. : _M_cur(__n), _M_ht(__tab) { }
  149. _Hashtable_const_iterator() { }
  150. _Hashtable_const_iterator(const iterator& __it)
  151. : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { }
  152. reference
  153. operator*() const
  154. { return _M_cur->_M_val; }
  155. pointer
  156. operator->() const
  157. { return &(operator*()); }
  158. const_iterator&
  159. operator++();
  160. const_iterator
  161. operator++(int);
  162. bool
  163. operator==(const const_iterator& __it) const
  164. { return _M_cur == __it._M_cur; }
  165. bool
  166. operator!=(const const_iterator& __it) const
  167. { return _M_cur != __it._M_cur; }
  168. };
  169. // Note: assumes long is at least 32 bits.
  170. enum { _S_num_primes = 28 };
  171. static const unsigned long __stl_prime_list[_S_num_primes] =
  172. {
  173. 53ul, 97ul, 193ul, 389ul, 769ul,
  174. 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
  175. 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
  176. 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
  177. 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
  178. 1610612741ul, 3221225473ul, 4294967291ul
  179. };
  180. inline unsigned long
  181. __stl_next_prime(unsigned long __n)
  182. {
  183. const unsigned long* __first = __stl_prime_list;
  184. const unsigned long* __last = __stl_prime_list + (int)_S_num_primes;
  185. const unsigned long* pos = std::lower_bound(__first, __last, __n);
  186. return pos == __last ? *(__last - 1) : *pos;
  187. }
  188. // Forward declaration of operator==.
  189. template<class _Val, class _Key, class _HF, class _Ex,
  190. class _Eq, class _All>
  191. class hashtable;
  192. template<class _Val, class _Key, class _HF, class _Ex,
  193. class _Eq, class _All>
  194. bool
  195. operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
  196. const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);
  197. // Hashtables handle allocators a bit differently than other
  198. // containers do. If we're using standard-conforming allocators, then
  199. // a hashtable unconditionally has a member variable to hold its
  200. // allocator, even if it so happens that all instances of the
  201. // allocator type are identical. This is because, for hashtables,
  202. // this extra storage is negligible. Additionally, a base class
  203. // wouldn't serve any other purposes; it wouldn't, for example,
  204. // simplify the exception-handling code.
  205. template<class _Val, class _Key, class _HashFcn,
  206. class _ExtractKey, class _EqualKey, class _Alloc>
  207. class hashtable
  208. {
  209. public:
  210. typedef _Key key_type;
  211. typedef _Val value_type;
  212. typedef _HashFcn hasher;
  213. typedef _EqualKey key_equal;
  214. typedef size_t size_type;
  215. typedef ptrdiff_t difference_type;
  216. typedef value_type* pointer;
  217. typedef const value_type* const_pointer;
  218. typedef value_type& reference;
  219. typedef const value_type& const_reference;
  220. hasher
  221. hash_funct() const
  222. { return _M_hash; }
  223. key_equal
  224. key_eq() const
  225. { return _M_equals; }
  226. private:
  227. typedef _Hashtable_node<_Val> _Node;
  228. public:
  229. typedef typename _Alloc::template rebind<value_type>::other allocator_type;
  230. allocator_type
  231. get_allocator() const
  232. { return _M_node_allocator; }
  233. private:
  234. typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
  235. typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
  236. typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
  237. _Node_Alloc _M_node_allocator;
  238. _Node*
  239. _M_get_node()
  240. { return _M_node_allocator.allocate(1); }
  241. void
  242. _M_put_node(_Node* __p)
  243. { _M_node_allocator.deallocate(__p, 1); }
  244. private:
  245. hasher _M_hash;
  246. key_equal _M_equals;
  247. _ExtractKey _M_get_key;
  248. _Vector_type _M_buckets;
  249. size_type _M_num_elements;
  250. public:
  251. typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
  252. _EqualKey, _Alloc>
  253. iterator;
  254. typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
  255. _EqualKey, _Alloc>
  256. const_iterator;
  257. friend struct
  258. _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>;
  259. friend struct
  260. _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
  261. _EqualKey, _Alloc>;
  262. public:
  263. hashtable(size_type __n, const _HashFcn& __hf,
  264. const _EqualKey& __eql, const _ExtractKey& __ext,
  265. const allocator_type& __a = allocator_type())
  266. : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
  267. _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0)
  268. { _M_initialize_buckets(__n); }
  269. hashtable(size_type __n, const _HashFcn& __hf,
  270. const _EqualKey& __eql,
  271. const allocator_type& __a = allocator_type())
  272. : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
  273. _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0)
  274. { _M_initialize_buckets(__n); }
  275. hashtable(const hashtable& __ht)
  276. : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash),
  277. _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key),
  278. _M_buckets(__ht.get_allocator()), _M_num_elements(0)
  279. { _M_copy_from(__ht); }
  280. hashtable&
  281. operator= (const hashtable& __ht)
  282. {
  283. if (&__ht != this)
  284. {
  285. clear();
  286. _M_hash = __ht._M_hash;
  287. _M_equals = __ht._M_equals;
  288. _M_get_key = __ht._M_get_key;
  289. _M_copy_from(__ht);
  290. }
  291. return *this;
  292. }
  293. ~hashtable()
  294. { clear(); }
  295. size_type
  296. size() const
  297. { return _M_num_elements; }
  298. size_type
  299. max_size() const
  300. { return size_type(-1); }
  301. bool
  302. empty() const
  303. { return size() == 0; }
  304. void
  305. swap(hashtable& __ht)
  306. {
  307. std::swap(_M_hash, __ht._M_hash);
  308. std::swap(_M_equals, __ht._M_equals);
  309. std::swap(_M_get_key, __ht._M_get_key);
  310. _M_buckets.swap(__ht._M_buckets);
  311. std::swap(_M_num_elements, __ht._M_num_elements);
  312. }
  313. iterator
  314. begin()
  315. {
  316. for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
  317. if (_M_buckets[__n])
  318. return iterator(_M_buckets[__n], this);
  319. return end();
  320. }
  321. iterator
  322. end()
  323. { return iterator(0, this); }
  324. const_iterator
  325. begin() const
  326. {
  327. for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
  328. if (_M_buckets[__n])
  329. return const_iterator(_M_buckets[__n], this);
  330. return end();
  331. }
  332. const_iterator
  333. end() const
  334. { return const_iterator(0, this); }
  335. template<class _Vl, class _Ky, class _HF, class _Ex, class _Eq,
  336. class _Al>
  337. friend bool
  338. operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&,
  339. const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&);
  340. public:
  341. size_type
  342. bucket_count() const
  343. { return _M_buckets.size(); }
  344. size_type
  345. max_bucket_count() const
  346. { return __stl_prime_list[(int)_S_num_primes - 1]; }
  347. size_type
  348. elems_in_bucket(size_type __bucket) const
  349. {
  350. size_type __result = 0;
  351. for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next)
  352. __result += 1;
  353. return __result;
  354. }
  355. pair<iterator, bool>
  356. insert_unique(const value_type& __obj)
  357. {
  358. resize(_M_num_elements + 1);
  359. return insert_unique_noresize(__obj);
  360. }
  361. iterator
  362. insert_equal(const value_type& __obj)
  363. {
  364. resize(_M_num_elements + 1);
  365. return insert_equal_noresize(__obj);
  366. }
  367. pair<iterator, bool>
  368. insert_unique_noresize(const value_type& __obj);
  369. iterator
  370. insert_equal_noresize(const value_type& __obj);
  371. template<class _InputIterator>
  372. void
  373. insert_unique(_InputIterator __f, _InputIterator __l)
  374. { insert_unique(__f, __l, __iterator_category(__f)); }
  375. template<class _InputIterator>
  376. void
  377. insert_equal(_InputIterator __f, _InputIterator __l)
  378. { insert_equal(__f, __l, __iterator_category(__f)); }
  379. template<class _InputIterator>
  380. void
  381. insert_unique(_InputIterator __f, _InputIterator __l,
  382. input_iterator_tag)
  383. {
  384. for ( ; __f != __l; ++__f)
  385. insert_unique(*__f);
  386. }
  387. template<class _InputIterator>
  388. void
  389. insert_equal(_InputIterator __f, _InputIterator __l,
  390. input_iterator_tag)
  391. {
  392. for ( ; __f != __l; ++__f)
  393. insert_equal(*__f);
  394. }
  395. template<class _ForwardIterator>
  396. void
  397. insert_unique(_ForwardIterator __f, _ForwardIterator __l,
  398. forward_iterator_tag)
  399. {
  400. size_type __n = distance(__f, __l);
  401. resize(_M_num_elements + __n);
  402. for ( ; __n > 0; --__n, ++__f)
  403. insert_unique_noresize(*__f);
  404. }
  405. template<class _ForwardIterator>
  406. void
  407. insert_equal(_ForwardIterator __f, _ForwardIterator __l,
  408. forward_iterator_tag)
  409. {
  410. size_type __n = distance(__f, __l);
  411. resize(_M_num_elements + __n);
  412. for ( ; __n > 0; --__n, ++__f)
  413. insert_equal_noresize(*__f);
  414. }
  415. reference
  416. find_or_insert(const value_type& __obj);
  417. iterator
  418. find(const key_type& __key)
  419. {
  420. size_type __n = _M_bkt_num_key(__key);
  421. _Node* __first;
  422. for (__first = _M_buckets[__n];
  423. __first && !_M_equals(_M_get_key(__first->_M_val), __key);
  424. __first = __first->_M_next)
  425. { }
  426. return iterator(__first, this);
  427. }
  428. const_iterator
  429. find(const key_type& __key) const
  430. {
  431. size_type __n = _M_bkt_num_key(__key);
  432. const _Node* __first;
  433. for (__first = _M_buckets[__n];
  434. __first && !_M_equals(_M_get_key(__first->_M_val), __key);
  435. __first = __first->_M_next)
  436. { }
  437. return const_iterator(__first, this);
  438. }
  439. size_type
  440. count(const key_type& __key) const
  441. {
  442. const size_type __n = _M_bkt_num_key(__key);
  443. size_type __result = 0;
  444. for (const _Node* __cur = _M_buckets[__n]; __cur;
  445. __cur = __cur->_M_next)
  446. if (_M_equals(_M_get_key(__cur->_M_val), __key))
  447. ++__result;
  448. return __result;
  449. }
  450. pair<iterator, iterator>
  451. equal_range(const key_type& __key);
  452. pair<const_iterator, const_iterator>
  453. equal_range(const key_type& __key) const;
  454. size_type
  455. erase(const key_type& __key);
  456. void
  457. erase(const iterator& __it);
  458. void
  459. erase(iterator __first, iterator __last);
  460. void
  461. erase(const const_iterator& __it);
  462. void
  463. erase(const_iterator __first, const_iterator __last);
  464. void
  465. resize(size_type __num_elements_hint);
  466. void
  467. clear();
  468. private:
  469. size_type
  470. _M_next_size(size_type __n) const
  471. { return __stl_next_prime(__n); }
  472. void
  473. _M_initialize_buckets(size_type __n)
  474. {
  475. const size_type __n_buckets = _M_next_size(__n);
  476. _M_buckets.reserve(__n_buckets);
  477. _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
  478. _M_num_elements = 0;
  479. }
  480. size_type
  481. _M_bkt_num_key(const key_type& __key) const
  482. { return _M_bkt_num_key(__key, _M_buckets.size()); }
  483. size_type
  484. _M_bkt_num(const value_type& __obj) const
  485. { return _M_bkt_num_key(_M_get_key(__obj)); }
  486. size_type
  487. _M_bkt_num_key(const key_type& __key, size_t __n) const
  488. { return _M_hash(__key) % __n; }
  489. size_type
  490. _M_bkt_num(const value_type& __obj, size_t __n) const
  491. { return _M_bkt_num_key(_M_get_key(__obj), __n); }
  492. _Node*
  493. _M_new_node(const value_type& __obj)
  494. {
  495. _Node* __n = _M_get_node();
  496. __n->_M_next = 0;
  497. __try
  498. {
  499. this->get_allocator().construct(&__n->_M_val, __obj);
  500. return __n;
  501. }
  502. __catch(...)
  503. {
  504. _M_put_node(__n);
  505. __throw_exception_again;
  506. }
  507. }
  508. void
  509. _M_delete_node(_Node* __n)
  510. {
  511. this->get_allocator().destroy(&__n->_M_val);
  512. _M_put_node(__n);
  513. }
  514. void
  515. _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
  516. void
  517. _M_erase_bucket(const size_type __n, _Node* __last);
  518. void
  519. _M_copy_from(const hashtable& __ht);
  520. };
  521. template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
  522. class _All>
  523. _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
  524. _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
  525. operator++()
  526. {
  527. const _Node* __old = _M_cur;
  528. _M_cur = _M_cur->_M_next;
  529. if (!_M_cur)
  530. {
  531. size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
  532. while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
  533. _M_cur = _M_ht->_M_buckets[__bucket];
  534. }
  535. return *this;
  536. }
  537. template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
  538. class _All>
  539. inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
  540. _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
  541. operator++(int)
  542. {
  543. iterator __tmp = *this;
  544. ++*this;
  545. return __tmp;
  546. }
  547. template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
  548. class _All>
  549. _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
  550. _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
  551. operator++()
  552. {
  553. const _Node* __old = _M_cur;
  554. _M_cur = _M_cur->_M_next;
  555. if (!_M_cur)
  556. {
  557. size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
  558. while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
  559. _M_cur = _M_ht->_M_buckets[__bucket];
  560. }
  561. return *this;
  562. }
  563. template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
  564. class _All>
  565. inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
  566. _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
  567. operator++(int)
  568. {
  569. const_iterator __tmp = *this;
  570. ++*this;
  571. return __tmp;
  572. }
  573. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  574. bool
  575. operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
  576. const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
  577. {
  578. typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;
  579. if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
  580. return false;
  581. for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n)
  582. {
  583. _Node* __cur1 = __ht1._M_buckets[__n];
  584. _Node* __cur2 = __ht2._M_buckets[__n];
  585. // Check same length of lists
  586. for (; __cur1 && __cur2;
  587. __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
  588. { }
  589. if (__cur1 || __cur2)
  590. return false;
  591. // Now check one's elements are in the other
  592. for (__cur1 = __ht1._M_buckets[__n] ; __cur1;
  593. __cur1 = __cur1->_M_next)
  594. {
  595. bool _found__cur1 = false;
  596. for (__cur2 = __ht2._M_buckets[__n];
  597. __cur2; __cur2 = __cur2->_M_next)
  598. {
  599. if (__cur1->_M_val == __cur2->_M_val)
  600. {
  601. _found__cur1 = true;
  602. break;
  603. }
  604. }
  605. if (!_found__cur1)
  606. return false;
  607. }
  608. }
  609. return true;
  610. }
  611. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  612. inline bool
  613. operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
  614. const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
  615. { return !(__ht1 == __ht2); }
  616. template<class _Val, class _Key, class _HF, class _Extract, class _EqKey,
  617. class _All>
  618. inline void
  619. swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
  620. hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
  621. { __ht1.swap(__ht2); }
  622. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  623. pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool>
  624. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  625. insert_unique_noresize(const value_type& __obj)
  626. {
  627. const size_type __n = _M_bkt_num(__obj);
  628. _Node* __first = _M_buckets[__n];
  629. for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  630. if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
  631. return pair<iterator, bool>(iterator(__cur, this), false);
  632. _Node* __tmp = _M_new_node(__obj);
  633. __tmp->_M_next = __first;
  634. _M_buckets[__n] = __tmp;
  635. ++_M_num_elements;
  636. return pair<iterator, bool>(iterator(__tmp, this), true);
  637. }
  638. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  639. typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
  640. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  641. insert_equal_noresize(const value_type& __obj)
  642. {
  643. const size_type __n = _M_bkt_num(__obj);
  644. _Node* __first = _M_buckets[__n];
  645. for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  646. if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
  647. {
  648. _Node* __tmp = _M_new_node(__obj);
  649. __tmp->_M_next = __cur->_M_next;
  650. __cur->_M_next = __tmp;
  651. ++_M_num_elements;
  652. return iterator(__tmp, this);
  653. }
  654. _Node* __tmp = _M_new_node(__obj);
  655. __tmp->_M_next = __first;
  656. _M_buckets[__n] = __tmp;
  657. ++_M_num_elements;
  658. return iterator(__tmp, this);
  659. }
  660. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  661. typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference
  662. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  663. find_or_insert(const value_type& __obj)
  664. {
  665. resize(_M_num_elements + 1);
  666. size_type __n = _M_bkt_num(__obj);
  667. _Node* __first = _M_buckets[__n];
  668. for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  669. if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
  670. return __cur->_M_val;
  671. _Node* __tmp = _M_new_node(__obj);
  672. __tmp->_M_next = __first;
  673. _M_buckets[__n] = __tmp;
  674. ++_M_num_elements;
  675. return __tmp->_M_val;
  676. }
  677. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  678. pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
  679. typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
  680. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  681. equal_range(const key_type& __key)
  682. {
  683. typedef pair<iterator, iterator> _Pii;
  684. const size_type __n = _M_bkt_num_key(__key);
  685. for (_Node* __first = _M_buckets[__n]; __first;
  686. __first = __first->_M_next)
  687. if (_M_equals(_M_get_key(__first->_M_val), __key))
  688. {
  689. for (_Node* __cur = __first->_M_next; __cur;
  690. __cur = __cur->_M_next)
  691. if (!_M_equals(_M_get_key(__cur->_M_val), __key))
  692. return _Pii(iterator(__first, this), iterator(__cur, this));
  693. for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
  694. if (_M_buckets[__m])
  695. return _Pii(iterator(__first, this),
  696. iterator(_M_buckets[__m], this));
  697. return _Pii(iterator(__first, this), end());
  698. }
  699. return _Pii(end(), end());
  700. }
  701. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  702. pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
  703. typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
  704. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  705. equal_range(const key_type& __key) const
  706. {
  707. typedef pair<const_iterator, const_iterator> _Pii;
  708. const size_type __n = _M_bkt_num_key(__key);
  709. for (const _Node* __first = _M_buckets[__n]; __first;
  710. __first = __first->_M_next)
  711. {
  712. if (_M_equals(_M_get_key(__first->_M_val), __key))
  713. {
  714. for (const _Node* __cur = __first->_M_next; __cur;
  715. __cur = __cur->_M_next)
  716. if (!_M_equals(_M_get_key(__cur->_M_val), __key))
  717. return _Pii(const_iterator(__first, this),
  718. const_iterator(__cur, this));
  719. for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
  720. if (_M_buckets[__m])
  721. return _Pii(const_iterator(__first, this),
  722. const_iterator(_M_buckets[__m], this));
  723. return _Pii(const_iterator(__first, this), end());
  724. }
  725. }
  726. return _Pii(end(), end());
  727. }
  728. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  729. typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
  730. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  731. erase(const key_type& __key)
  732. {
  733. const size_type __n = _M_bkt_num_key(__key);
  734. _Node* __first = _M_buckets[__n];
  735. size_type __erased = 0;
  736. if (__first)
  737. {
  738. _Node* __cur = __first;
  739. _Node* __next = __cur->_M_next;
  740. while (__next)
  741. {
  742. if (_M_equals(_M_get_key(__next->_M_val), __key))
  743. {
  744. __cur->_M_next = __next->_M_next;
  745. _M_delete_node(__next);
  746. __next = __cur->_M_next;
  747. ++__erased;
  748. --_M_num_elements;
  749. }
  750. else
  751. {
  752. __cur = __next;
  753. __next = __cur->_M_next;
  754. }
  755. }
  756. if (_M_equals(_M_get_key(__first->_M_val), __key))
  757. {
  758. _M_buckets[__n] = __first->_M_next;
  759. _M_delete_node(__first);
  760. ++__erased;
  761. --_M_num_elements;
  762. }
  763. }
  764. return __erased;
  765. }
  766. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  767. void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  768. erase(const iterator& __it)
  769. {
  770. _Node* __p = __it._M_cur;
  771. if (__p)
  772. {
  773. const size_type __n = _M_bkt_num(__p->_M_val);
  774. _Node* __cur = _M_buckets[__n];
  775. if (__cur == __p)
  776. {
  777. _M_buckets[__n] = __cur->_M_next;
  778. _M_delete_node(__cur);
  779. --_M_num_elements;
  780. }
  781. else
  782. {
  783. _Node* __next = __cur->_M_next;
  784. while (__next)
  785. {
  786. if (__next == __p)
  787. {
  788. __cur->_M_next = __next->_M_next;
  789. _M_delete_node(__next);
  790. --_M_num_elements;
  791. break;
  792. }
  793. else
  794. {
  795. __cur = __next;
  796. __next = __cur->_M_next;
  797. }
  798. }
  799. }
  800. }
  801. }
  802. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  803. void
  804. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  805. erase(iterator __first, iterator __last)
  806. {
  807. size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val)
  808. : _M_buckets.size();
  809. size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val)
  810. : _M_buckets.size();
  811. if (__first._M_cur == __last._M_cur)
  812. return;
  813. else if (__f_bucket == __l_bucket)
  814. _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
  815. else
  816. {
  817. _M_erase_bucket(__f_bucket, __first._M_cur, 0);
  818. for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
  819. _M_erase_bucket(__n, 0);
  820. if (__l_bucket != _M_buckets.size())
  821. _M_erase_bucket(__l_bucket, __last._M_cur);
  822. }
  823. }
  824. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  825. inline void
  826. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  827. erase(const_iterator __first, const_iterator __last)
  828. {
  829. erase(iterator(const_cast<_Node*>(__first._M_cur),
  830. const_cast<hashtable*>(__first._M_ht)),
  831. iterator(const_cast<_Node*>(__last._M_cur),
  832. const_cast<hashtable*>(__last._M_ht)));
  833. }
  834. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  835. inline void
  836. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  837. erase(const const_iterator& __it)
  838. { erase(iterator(const_cast<_Node*>(__it._M_cur),
  839. const_cast<hashtable*>(__it._M_ht))); }
  840. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  841. void
  842. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  843. resize(size_type __num_elements_hint)
  844. {
  845. const size_type __old_n = _M_buckets.size();
  846. if (__num_elements_hint > __old_n)
  847. {
  848. const size_type __n = _M_next_size(__num_elements_hint);
  849. if (__n > __old_n)
  850. {
  851. _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
  852. __try
  853. {
  854. for (size_type __bucket = 0; __bucket < __old_n; ++__bucket)
  855. {
  856. _Node* __first = _M_buckets[__bucket];
  857. while (__first)
  858. {
  859. size_type __new_bucket = _M_bkt_num(__first->_M_val,
  860. __n);
  861. _M_buckets[__bucket] = __first->_M_next;
  862. __first->_M_next = __tmp[__new_bucket];
  863. __tmp[__new_bucket] = __first;
  864. __first = _M_buckets[__bucket];
  865. }
  866. }
  867. _M_buckets.swap(__tmp);
  868. }
  869. __catch(...)
  870. {
  871. for (size_type __bucket = 0; __bucket < __tmp.size();
  872. ++__bucket)
  873. {
  874. while (__tmp[__bucket])
  875. {
  876. _Node* __next = __tmp[__bucket]->_M_next;
  877. _M_delete_node(__tmp[__bucket]);
  878. __tmp[__bucket] = __next;
  879. }
  880. }
  881. __throw_exception_again;
  882. }
  883. }
  884. }
  885. }
  886. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  887. void
  888. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  889. _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
  890. {
  891. _Node* __cur = _M_buckets[__n];
  892. if (__cur == __first)
  893. _M_erase_bucket(__n, __last);
  894. else
  895. {
  896. _Node* __next;
  897. for (__next = __cur->_M_next;
  898. __next != __first;
  899. __cur = __next, __next = __cur->_M_next)
  900. ;
  901. while (__next != __last)
  902. {
  903. __cur->_M_next = __next->_M_next;
  904. _M_delete_node(__next);
  905. __next = __cur->_M_next;
  906. --_M_num_elements;
  907. }
  908. }
  909. }
  910. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  911. void
  912. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  913. _M_erase_bucket(const size_type __n, _Node* __last)
  914. {
  915. _Node* __cur = _M_buckets[__n];
  916. while (__cur != __last)
  917. {
  918. _Node* __next = __cur->_M_next;
  919. _M_delete_node(__cur);
  920. __cur = __next;
  921. _M_buckets[__n] = __cur;
  922. --_M_num_elements;
  923. }
  924. }
  925. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  926. void
  927. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  928. clear()
  929. {
  930. for (size_type __i = 0; __i < _M_buckets.size(); ++__i)
  931. {
  932. _Node* __cur = _M_buckets[__i];
  933. while (__cur != 0)
  934. {
  935. _Node* __next = __cur->_M_next;
  936. _M_delete_node(__cur);
  937. __cur = __next;
  938. }
  939. _M_buckets[__i] = 0;
  940. }
  941. _M_num_elements = 0;
  942. }
  943. template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  944. void
  945. hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
  946. _M_copy_from(const hashtable& __ht)
  947. {
  948. _M_buckets.clear();
  949. _M_buckets.reserve(__ht._M_buckets.size());
  950. _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
  951. __try
  952. {
  953. for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
  954. const _Node* __cur = __ht._M_buckets[__i];
  955. if (__cur)
  956. {
  957. _Node* __local_copy = _M_new_node(__cur->_M_val);
  958. _M_buckets[__i] = __local_copy;
  959. for (_Node* __next = __cur->_M_next;
  960. __next;
  961. __cur = __next, __next = __cur->_M_next)
  962. {
  963. __local_copy->_M_next = _M_new_node(__next->_M_val);
  964. __local_copy = __local_copy->_M_next;
  965. }
  966. }
  967. }
  968. _M_num_elements = __ht._M_num_elements;
  969. }
  970. __catch(...)
  971. {
  972. clear();
  973. __throw_exception_again;
  974. }
  975. }
  976. _GLIBCXX_END_NAMESPACE
  977. #endif