hashtable.h 33 KB

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