hashtable.hxx.in 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  1. /*============================================================================
  2. KWSys - Kitware System Library
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. /*
  11. * Copyright (c) 1996
  12. * Silicon Graphics Computer Systems, Inc.
  13. *
  14. * Permission to use, copy, modify, distribute and sell this software
  15. * and its documentation for any purpose is hereby granted without fee,
  16. * provided that the above copyright notice appear in all copies and
  17. * that both that copyright notice and this permission notice appear
  18. * in supporting documentation. Silicon Graphics makes no
  19. * representations about the suitability of this software for any
  20. * purpose. It is provided "as is" without express or implied warranty.
  21. *
  22. *
  23. * Copyright (c) 1994
  24. * Hewlett-Packard Company
  25. *
  26. * Permission to use, copy, modify, distribute and sell this software
  27. * and its documentation for any purpose is hereby granted without fee,
  28. * provided that the above copyright notice appear in all copies and
  29. * that both that copyright notice and this permission notice appear
  30. * in supporting documentation. Hewlett-Packard Company makes no
  31. * representations about the suitability of this software for any
  32. * purpose. It is provided "as is" without express or implied warranty.
  33. *
  34. */
  35. #ifdef __BORLANDC__
  36. # pragma warn -8027 /* 'for' not inlined. */
  37. # pragma warn -8026 /* 'exception' not inlined. */
  38. #endif
  39. #ifndef @KWSYS_NAMESPACE@_hashtable_hxx
  40. #define @KWSYS_NAMESPACE@_hashtable_hxx
  41. #include <@KWSYS_NAMESPACE@/Configure.hxx>
  42. #include <stddef.h> // size_t
  43. #include <algorithm> // lower_bound
  44. #include <functional> // unary_function
  45. #include <iterator> // iterator_traits
  46. #include <memory> // allocator
  47. #include <utility> // pair
  48. #include <vector> // vector
  49. #if defined(_MSC_VER)
  50. # pragma warning (push)
  51. # pragma warning (disable:4284)
  52. # pragma warning (disable:4786)
  53. # pragma warning (disable:4512) /* no assignment operator for class */
  54. #endif
  55. #if defined(__sgi) && !defined(__GNUC__)
  56. # pragma set woff 3970 /* pointer to int conversion */ 3321 3968
  57. #endif
  58. // In C++11, clang will warn about using dynamic exception specifications
  59. // as they are deprecated. But as this class is trying to faithfully
  60. // mimic unordered_set and unordered_map, we want to keep the 'throw()'
  61. // decorations below. So we suppress the warning.
  62. #if defined(__clang__) && defined(__has_warning)
  63. # if __has_warning("-Wdeprecated")
  64. # pragma clang diagnostic push
  65. # pragma clang diagnostic ignored "-Wdeprecated"
  66. # endif
  67. #endif
  68. namespace @KWSYS_NAMESPACE@
  69. {
  70. template <class _Val>
  71. struct _Hashtable_node
  72. {
  73. _Hashtable_node* _M_next;
  74. _Val _M_val;
  75. void public_method_to_quiet_warning_about_all_methods_private();
  76. private:
  77. void operator=(_Hashtable_node<_Val> const&); // poison node assignment
  78. };
  79. template <class _Val, class _Key, class _HashFcn,
  80. class _ExtractKey, class _EqualKey,
  81. class _Alloc = std::allocator<char> >
  82. class hashtable;
  83. template <class _Val, class _Key, class _HashFcn,
  84. class _ExtractKey, class _EqualKey, class _Alloc>
  85. struct _Hashtable_iterator;
  86. template <class _Val, class _Key, class _HashFcn,
  87. class _ExtractKey, class _EqualKey, class _Alloc>
  88. struct _Hashtable_const_iterator;
  89. template <class _Val, class _Key, class _HashFcn,
  90. class _ExtractKey, class _EqualKey, class _Alloc>
  91. struct _Hashtable_iterator {
  92. typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  93. _Hashtable;
  94. typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
  95. _ExtractKey, _EqualKey, _Alloc>
  96. iterator;
  97. typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
  98. _ExtractKey, _EqualKey, _Alloc>
  99. const_iterator;
  100. typedef _Hashtable_node<_Val> _Node;
  101. typedef std::forward_iterator_tag iterator_category;
  102. typedef _Val value_type;
  103. typedef ptrdiff_t difference_type;
  104. typedef size_t size_type;
  105. typedef _Val& reference;
  106. typedef _Val* pointer;
  107. _Node* _M_cur;
  108. _Hashtable* _M_ht;
  109. _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
  110. : _M_cur(__n), _M_ht(__tab) {}
  111. _Hashtable_iterator() {}
  112. reference operator*() const { return _M_cur->_M_val; }
  113. pointer operator->() const { return &(operator*()); }
  114. iterator& operator++();
  115. iterator operator++(int);
  116. bool operator==(const iterator& __it) const
  117. { return _M_cur == __it._M_cur; }
  118. bool operator!=(const iterator& __it) const
  119. { return _M_cur != __it._M_cur; }
  120. };
  121. template <class _Val, class _Key, class _HashFcn,
  122. class _ExtractKey, class _EqualKey, class _Alloc>
  123. struct _Hashtable_const_iterator {
  124. typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  125. _Hashtable;
  126. typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
  127. _ExtractKey,_EqualKey,_Alloc>
  128. iterator;
  129. typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
  130. _ExtractKey, _EqualKey, _Alloc>
  131. const_iterator;
  132. typedef _Hashtable_node<_Val> _Node;
  133. typedef std::forward_iterator_tag iterator_category;
  134. typedef _Val value_type;
  135. typedef ptrdiff_t difference_type;
  136. typedef size_t size_type;
  137. typedef const _Val& reference;
  138. typedef const _Val* pointer;
  139. const _Node* _M_cur;
  140. const _Hashtable* _M_ht;
  141. _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
  142. : _M_cur(__n), _M_ht(__tab) {}
  143. _Hashtable_const_iterator() {}
  144. _Hashtable_const_iterator(const iterator& __it)
  145. : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {}
  146. reference operator*() const { return _M_cur->_M_val; }
  147. pointer operator->() const { return &(operator*()); }
  148. const_iterator& operator++();
  149. const_iterator operator++(int);
  150. bool operator==(const const_iterator& __it) const
  151. { return _M_cur == __it._M_cur; }
  152. bool operator!=(const const_iterator& __it) const
  153. { return _M_cur != __it._M_cur; }
  154. };
  155. // Note: assumes long is at least 32 bits.
  156. enum { _stl_num_primes = 31 };
  157. // create a function with a static local to that function that returns
  158. // the static
  159. static inline const unsigned long* get_stl_prime_list() {
  160. static const unsigned long _stl_prime_list[_stl_num_primes] =
  161. {
  162. 5ul, 11ul, 23ul,
  163. 53ul, 97ul, 193ul, 389ul, 769ul,
  164. 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
  165. 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
  166. 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
  167. 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
  168. 1610612741ul, 3221225473ul, 4294967291ul
  169. };
  170. return &_stl_prime_list[0]; }
  171. static inline size_t _stl_next_prime(size_t __n)
  172. {
  173. const unsigned long* __first = get_stl_prime_list();
  174. const unsigned long* __last = get_stl_prime_list() + (int)_stl_num_primes;
  175. const unsigned long* pos = std::lower_bound(__first, __last, __n);
  176. return pos == __last ? *(__last - 1) : *pos;
  177. }
  178. // Forward declaration of operator==.
  179. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  180. class hashtable;
  181. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  182. bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
  183. const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2);
  184. // Hashtables handle allocators a bit differently than other containers
  185. // do. If we're using standard-conforming allocators, then a hashtable
  186. // unconditionally has a member variable to hold its allocator, even if
  187. // it so happens that all instances of the allocator type are identical.
  188. // This is because, for hashtables, this extra storage is negligible.
  189. // Additionally, a base class wouldn't serve any other purposes; it
  190. // wouldn't, for example, simplify the exception-handling code.
  191. template <class _Val, class _Key, class _HashFcn,
  192. class _ExtractKey, class _EqualKey, class _Alloc>
  193. class hashtable {
  194. public:
  195. typedef _Key key_type;
  196. typedef _Val value_type;
  197. typedef _HashFcn hasher;
  198. typedef _EqualKey key_equal;
  199. typedef size_t size_type;
  200. typedef ptrdiff_t difference_type;
  201. typedef value_type* pointer;
  202. typedef const value_type* const_pointer;
  203. typedef value_type& reference;
  204. typedef const value_type& const_reference;
  205. hasher hash_funct() const { return _M_hash; }
  206. key_equal key_eq() const { return _M_equals; }
  207. private:
  208. typedef _Hashtable_node<_Val> _Node;
  209. public:
  210. typedef typename _Alloc::template rebind<_Val>::other allocator_type;
  211. allocator_type get_allocator() const { return _M_node_allocator; }
  212. private:
  213. typedef typename _Alloc::template rebind<_Node>::other _M_node_allocator_type;
  214. typedef typename _Alloc::template rebind<_Node*>::other _M_node_ptr_allocator_type;
  215. typedef std::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type;
  216. private:
  217. _M_node_allocator_type _M_node_allocator;
  218. hasher _M_hash;
  219. key_equal _M_equals;
  220. _ExtractKey _M_get_key;
  221. _M_buckets_type _M_buckets;
  222. size_type _M_num_elements;
  223. _Node* _M_get_node() { return _M_node_allocator.allocate(1); }
  224. void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
  225. public:
  226. typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  227. iterator;
  228. typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,
  229. _Alloc>
  230. const_iterator;
  231. friend struct
  232. _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
  233. friend struct
  234. _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
  235. public:
  236. hashtable(size_type __n,
  237. const _HashFcn& __hf,
  238. const _EqualKey& __eql,
  239. const _ExtractKey& __ext,
  240. const allocator_type& __a = allocator_type())
  241. : _M_node_allocator(__a),
  242. _M_hash(__hf),
  243. _M_equals(__eql),
  244. _M_get_key(__ext),
  245. _M_buckets(__a),
  246. _M_num_elements(0)
  247. {
  248. _M_initialize_buckets(__n);
  249. }
  250. hashtable(size_type __n,
  251. const _HashFcn& __hf,
  252. const _EqualKey& __eql,
  253. const allocator_type& __a = allocator_type())
  254. : _M_node_allocator(__a),
  255. _M_hash(__hf),
  256. _M_equals(__eql),
  257. _M_get_key(_ExtractKey()),
  258. _M_buckets(__a),
  259. _M_num_elements(0)
  260. {
  261. _M_initialize_buckets(__n);
  262. }
  263. hashtable(const hashtable& __ht)
  264. : _M_node_allocator(__ht.get_allocator()),
  265. _M_hash(__ht._M_hash),
  266. _M_equals(__ht._M_equals),
  267. _M_get_key(__ht._M_get_key),
  268. _M_buckets(__ht.get_allocator()),
  269. _M_num_elements(0)
  270. {
  271. _M_copy_from(__ht);
  272. }
  273. hashtable& operator= (const hashtable& __ht)
  274. {
  275. if (&__ht != this) {
  276. clear();
  277. _M_hash = __ht._M_hash;
  278. _M_equals = __ht._M_equals;
  279. _M_get_key = __ht._M_get_key;
  280. _M_copy_from(__ht);
  281. }
  282. return *this;
  283. }
  284. ~hashtable() { clear(); }
  285. size_type size() const { return _M_num_elements; }
  286. size_type max_size() const { return size_type(-1); }
  287. bool empty() const { return size() == 0; }
  288. void swap(hashtable& __ht)
  289. {
  290. std::swap(_M_hash, __ht._M_hash);
  291. std::swap(_M_equals, __ht._M_equals);
  292. std::swap(_M_get_key, __ht._M_get_key);
  293. _M_buckets.swap(__ht._M_buckets);
  294. std::swap(_M_num_elements, __ht._M_num_elements);
  295. }
  296. iterator begin()
  297. {
  298. for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
  299. if (_M_buckets[__n])
  300. return iterator(_M_buckets[__n], this);
  301. return end();
  302. }
  303. iterator end() { return iterator(0, this); }
  304. const_iterator begin() const
  305. {
  306. for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
  307. if (_M_buckets[__n])
  308. return const_iterator(_M_buckets[__n], this);
  309. return end();
  310. }
  311. const_iterator end() const { return const_iterator(0, this); }
  312. friend bool operator==<>(const hashtable&,
  313. const hashtable&);
  314. public:
  315. size_type bucket_count() const { return _M_buckets.size(); }
  316. size_type max_bucket_count() const
  317. { return get_stl_prime_list()[(int)_stl_num_primes - 1]; }
  318. size_type elems_in_bucket(size_type __bucket) const
  319. {
  320. size_type __result = 0;
  321. for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next)
  322. __result += 1;
  323. return __result;
  324. }
  325. std::pair<iterator, bool> insert_unique(const value_type& __obj)
  326. {
  327. resize(_M_num_elements + 1);
  328. return insert_unique_noresize(__obj);
  329. }
  330. iterator insert_equal(const value_type& __obj)
  331. {
  332. resize(_M_num_elements + 1);
  333. return insert_equal_noresize(__obj);
  334. }
  335. std::pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
  336. iterator insert_equal_noresize(const value_type& __obj);
  337. template <class _InputIterator>
  338. void insert_unique(_InputIterator __f, _InputIterator __l)
  339. {
  340. insert_unique(__f, __l,
  341. typename std::iterator_traits<_InputIterator>::iterator_category());
  342. }
  343. template <class _InputIterator>
  344. void insert_equal(_InputIterator __f, _InputIterator __l)
  345. {
  346. insert_equal(__f, __l,
  347. typename std::iterator_traits<_InputIterator>::iterator_category());
  348. }
  349. template <class _InputIterator>
  350. void insert_unique(_InputIterator __f, _InputIterator __l,
  351. std::input_iterator_tag)
  352. {
  353. for ( ; __f != __l; ++__f)
  354. insert_unique(*__f);
  355. }
  356. template <class _InputIterator>
  357. void insert_equal(_InputIterator __f, _InputIterator __l,
  358. std::input_iterator_tag)
  359. {
  360. for ( ; __f != __l; ++__f)
  361. insert_equal(*__f);
  362. }
  363. template <class _ForwardIterator>
  364. void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
  365. std::forward_iterator_tag)
  366. {
  367. size_type __n = 0;
  368. std::distance(__f, __l, __n);
  369. resize(_M_num_elements + __n);
  370. for ( ; __n > 0; --__n, ++__f)
  371. insert_unique_noresize(*__f);
  372. }
  373. template <class _ForwardIterator>
  374. void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
  375. std::forward_iterator_tag)
  376. {
  377. size_type __n = 0;
  378. std::distance(__f, __l, __n);
  379. resize(_M_num_elements + __n);
  380. for ( ; __n > 0; --__n, ++__f)
  381. insert_equal_noresize(*__f);
  382. }
  383. reference find_or_insert(const value_type& __obj);
  384. iterator find(const key_type& __key)
  385. {
  386. size_type __n = _M_bkt_num_key(__key);
  387. _Node* __first;
  388. for ( __first = _M_buckets[__n];
  389. __first && !_M_equals(_M_get_key(__first->_M_val), __key);
  390. __first = __first->_M_next)
  391. {}
  392. return iterator(__first, this);
  393. }
  394. const_iterator find(const key_type& __key) const
  395. {
  396. size_type __n = _M_bkt_num_key(__key);
  397. const _Node* __first;
  398. for ( __first = _M_buckets[__n];
  399. __first && !_M_equals(_M_get_key(__first->_M_val), __key);
  400. __first = __first->_M_next)
  401. {}
  402. return const_iterator(__first, this);
  403. }
  404. size_type count(const key_type& __key) const
  405. {
  406. const size_type __n = _M_bkt_num_key(__key);
  407. size_type __result = 0;
  408. for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next)
  409. if (_M_equals(_M_get_key(__cur->_M_val), __key))
  410. ++__result;
  411. return __result;
  412. }
  413. std::pair<iterator, iterator>
  414. equal_range(const key_type& __key);
  415. std::pair<const_iterator, const_iterator>
  416. equal_range(const key_type& __key) const;
  417. size_type erase(const key_type& __key);
  418. void erase(const iterator& __it);
  419. void erase(iterator __first, iterator __last);
  420. void erase(const const_iterator& __it);
  421. void erase(const_iterator __first, const_iterator __last);
  422. void resize(size_type __num_elements_hint);
  423. void clear();
  424. private:
  425. size_type _M_next_size(size_type __n) const
  426. { return _stl_next_prime(__n); }
  427. void _M_initialize_buckets(size_type __n)
  428. {
  429. const size_type __n_buckets = _M_next_size(__n);
  430. _M_buckets.reserve(__n_buckets);
  431. _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
  432. _M_num_elements = 0;
  433. }
  434. size_type _M_bkt_num_key(const key_type& __key) const
  435. {
  436. return _M_bkt_num_key(__key, _M_buckets.size());
  437. }
  438. size_type _M_bkt_num(const value_type& __obj) const
  439. {
  440. return _M_bkt_num_key(_M_get_key(__obj));
  441. }
  442. size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
  443. {
  444. return _M_hash(__key) % __n;
  445. }
  446. size_type _M_bkt_num(const value_type& __obj, size_t __n) const
  447. {
  448. return _M_bkt_num_key(_M_get_key(__obj), __n);
  449. }
  450. void construct(_Val* p, const _Val& v)
  451. {
  452. new (p) _Val(v);
  453. }
  454. void destroy(_Val* p)
  455. {
  456. (void)p;
  457. p->~_Val();
  458. }
  459. _Node* _M_new_node(const value_type& __obj)
  460. {
  461. _Node* __n = _M_get_node();
  462. __n->_M_next = 0;
  463. try {
  464. construct(&__n->_M_val, __obj);
  465. return __n;
  466. }
  467. catch(...) {_M_put_node(__n); throw;}
  468. }
  469. void _M_delete_node(_Node* __n)
  470. {
  471. destroy(&__n->_M_val);
  472. _M_put_node(__n);
  473. }
  474. void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
  475. void _M_erase_bucket(const size_type __n, _Node* __last);
  476. void _M_copy_from(const hashtable& __ht);
  477. };
  478. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  479. class _All>
  480. _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
  481. _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
  482. {
  483. const _Node* __old = _M_cur;
  484. _M_cur = _M_cur->_M_next;
  485. if (!_M_cur) {
  486. size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
  487. while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
  488. _M_cur = _M_ht->_M_buckets[__bucket];
  489. }
  490. return *this;
  491. }
  492. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  493. class _All>
  494. inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
  495. _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
  496. {
  497. iterator __tmp = *this;
  498. ++*this;
  499. return __tmp;
  500. }
  501. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  502. class _All>
  503. _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
  504. _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
  505. {
  506. const _Node* __old = _M_cur;
  507. _M_cur = _M_cur->_M_next;
  508. if (!_M_cur) {
  509. size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
  510. while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
  511. _M_cur = _M_ht->_M_buckets[__bucket];
  512. }
  513. return *this;
  514. }
  515. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  516. class _All>
  517. inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
  518. _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
  519. {
  520. const_iterator __tmp = *this;
  521. ++*this;
  522. return __tmp;
  523. }
  524. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  525. bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
  526. const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2)
  527. {
  528. typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node;
  529. if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
  530. return false;
  531. for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) {
  532. _Node* __cur1 = __ht1._M_buckets[__n];
  533. _Node* __cur2 = __ht2._M_buckets[__n];
  534. for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val;
  535. __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
  536. {}
  537. if (__cur1 || __cur2)
  538. return false;
  539. }
  540. return true;
  541. }
  542. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  543. inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
  544. const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) {
  545. return !(__ht1 == __ht2);
  546. }
  547. template <class _Val, class _Key, class _HF, class _Extract, class _EqKey,
  548. class _All>
  549. inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
  550. hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) {
  551. __ht1.swap(__ht2);
  552. }
  553. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  554. std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool>
  555. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  556. ::insert_unique_noresize(const value_type& __obj)
  557. {
  558. const size_type __n = _M_bkt_num(__obj);
  559. _Node* __first = _M_buckets[__n];
  560. for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  561. if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
  562. return std::pair<iterator, bool>(iterator(__cur, this), false);
  563. _Node* __tmp = _M_new_node(__obj);
  564. __tmp->_M_next = __first;
  565. _M_buckets[__n] = __tmp;
  566. ++_M_num_elements;
  567. return std::pair<iterator, bool>(iterator(__tmp, this), true);
  568. }
  569. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  570. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator
  571. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  572. ::insert_equal_noresize(const value_type& __obj)
  573. {
  574. const size_type __n = _M_bkt_num(__obj);
  575. _Node* __first = _M_buckets[__n];
  576. for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  577. if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
  578. _Node* __tmp = _M_new_node(__obj);
  579. __tmp->_M_next = __cur->_M_next;
  580. __cur->_M_next = __tmp;
  581. ++_M_num_elements;
  582. return iterator(__tmp, this);
  583. }
  584. _Node* __tmp = _M_new_node(__obj);
  585. __tmp->_M_next = __first;
  586. _M_buckets[__n] = __tmp;
  587. ++_M_num_elements;
  588. return iterator(__tmp, this);
  589. }
  590. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  591. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference
  592. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj)
  593. {
  594. resize(_M_num_elements + 1);
  595. size_type __n = _M_bkt_num(__obj);
  596. _Node* __first = _M_buckets[__n];
  597. for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  598. if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
  599. return __cur->_M_val;
  600. _Node* __tmp = _M_new_node(__obj);
  601. __tmp->_M_next = __first;
  602. _M_buckets[__n] = __tmp;
  603. ++_M_num_elements;
  604. return __tmp->_M_val;
  605. }
  606. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  607. std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator,
  608. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator>
  609. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
  610. {
  611. typedef std::pair<iterator, iterator> _Pii;
  612. const size_type __n = _M_bkt_num_key(__key);
  613. for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next)
  614. if (_M_equals(_M_get_key(__first->_M_val), __key)) {
  615. for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next)
  616. if (!_M_equals(_M_get_key(__cur->_M_val), __key))
  617. return _Pii(iterator(__first, this), iterator(__cur, this));
  618. for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
  619. if (_M_buckets[__m])
  620. return _Pii(iterator(__first, this),
  621. iterator(_M_buckets[__m], this));
  622. return _Pii(iterator(__first, this), end());
  623. }
  624. return _Pii(end(), end());
  625. }
  626. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  627. std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator,
  628. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator>
  629. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  630. ::equal_range(const key_type& __key) const
  631. {
  632. typedef std::pair<const_iterator, const_iterator> _Pii;
  633. const size_type __n = _M_bkt_num_key(__key);
  634. for (const _Node* __first = _M_buckets[__n] ;
  635. __first;
  636. __first = __first->_M_next) {
  637. if (_M_equals(_M_get_key(__first->_M_val), __key)) {
  638. for (const _Node* __cur = __first->_M_next;
  639. __cur;
  640. __cur = __cur->_M_next)
  641. if (!_M_equals(_M_get_key(__cur->_M_val), __key))
  642. return _Pii(const_iterator(__first, this),
  643. const_iterator(__cur, this));
  644. for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
  645. if (_M_buckets[__m])
  646. return _Pii(const_iterator(__first, this),
  647. const_iterator(_M_buckets[__m], this));
  648. return _Pii(const_iterator(__first, this), end());
  649. }
  650. }
  651. return _Pii(end(), end());
  652. }
  653. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  654. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type
  655. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key)
  656. {
  657. const size_type __n = _M_bkt_num_key(__key);
  658. _Node* __first = _M_buckets[__n];
  659. size_type __erased = 0;
  660. if (__first) {
  661. _Node* __cur = __first;
  662. _Node* __next = __cur->_M_next;
  663. while (__next) {
  664. if (_M_equals(_M_get_key(__next->_M_val), __key)) {
  665. __cur->_M_next = __next->_M_next;
  666. _M_delete_node(__next);
  667. __next = __cur->_M_next;
  668. ++__erased;
  669. --_M_num_elements;
  670. }
  671. else {
  672. __cur = __next;
  673. __next = __cur->_M_next;
  674. }
  675. }
  676. if (_M_equals(_M_get_key(__first->_M_val), __key)) {
  677. _M_buckets[__n] = __first->_M_next;
  678. _M_delete_node(__first);
  679. ++__erased;
  680. --_M_num_elements;
  681. }
  682. }
  683. return __erased;
  684. }
  685. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  686. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it)
  687. {
  688. _Node* __p = __it._M_cur;
  689. if (__p) {
  690. const size_type __n = _M_bkt_num(__p->_M_val);
  691. _Node* __cur = _M_buckets[__n];
  692. if (__cur == __p) {
  693. _M_buckets[__n] = __cur->_M_next;
  694. _M_delete_node(__cur);
  695. --_M_num_elements;
  696. }
  697. else {
  698. _Node* __next = __cur->_M_next;
  699. while (__next) {
  700. if (__next == __p) {
  701. __cur->_M_next = __next->_M_next;
  702. _M_delete_node(__next);
  703. --_M_num_elements;
  704. break;
  705. }
  706. else {
  707. __cur = __next;
  708. __next = __cur->_M_next;
  709. }
  710. }
  711. }
  712. }
  713. }
  714. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  715. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  716. ::erase(iterator __first, iterator __last)
  717. {
  718. size_type __f_bucket = __first._M_cur ?
  719. _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
  720. size_type __l_bucket = __last._M_cur ?
  721. _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
  722. if (__first._M_cur == __last._M_cur)
  723. return;
  724. else if (__f_bucket == __l_bucket)
  725. _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
  726. else {
  727. _M_erase_bucket(__f_bucket, __first._M_cur, 0);
  728. for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
  729. _M_erase_bucket(__n, 0);
  730. if (__l_bucket != _M_buckets.size())
  731. _M_erase_bucket(__l_bucket, __last._M_cur);
  732. }
  733. }
  734. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  735. inline void
  736. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first,
  737. const_iterator __last)
  738. {
  739. erase(iterator(const_cast<_Node*>(__first._M_cur),
  740. const_cast<hashtable*>(__first._M_ht)),
  741. iterator(const_cast<_Node*>(__last._M_cur),
  742. const_cast<hashtable*>(__last._M_ht)));
  743. }
  744. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  745. inline void
  746. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it)
  747. {
  748. erase(iterator(const_cast<_Node*>(__it._M_cur),
  749. const_cast<hashtable*>(__it._M_ht)));
  750. }
  751. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  752. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  753. ::resize(size_type __num_elements_hint)
  754. {
  755. const size_type __old_n = _M_buckets.size();
  756. if (__num_elements_hint > __old_n) {
  757. const size_type __n = _M_next_size(__num_elements_hint);
  758. if (__n > __old_n) {
  759. _M_buckets_type __tmp(
  760. __n, (_Node*)(0),
  761. _M_buckets.get_allocator());
  762. try {
  763. for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
  764. _Node* __first = _M_buckets[__bucket];
  765. while (__first) {
  766. size_type __new_bucket = _M_bkt_num(__first->_M_val, __n);
  767. _M_buckets[__bucket] = __first->_M_next;
  768. __first->_M_next = __tmp[__new_bucket];
  769. __tmp[__new_bucket] = __first;
  770. __first = _M_buckets[__bucket];
  771. }
  772. }
  773. _M_buckets.swap(__tmp);
  774. }
  775. catch(...) {
  776. for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
  777. while (__tmp[__bucket]) {
  778. _Node* __next = __tmp[__bucket]->_M_next;
  779. _M_delete_node(__tmp[__bucket]);
  780. __tmp[__bucket] = __next;
  781. }
  782. }
  783. throw;
  784. }
  785. }
  786. }
  787. }
  788. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  789. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  790. ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
  791. {
  792. _Node* __cur = _M_buckets[__n];
  793. if (__cur == __first)
  794. _M_erase_bucket(__n, __last);
  795. else {
  796. _Node* __next;
  797. for (__next = __cur->_M_next;
  798. __next != __first;
  799. __cur = __next, __next = __cur->_M_next)
  800. ;
  801. while (__next != __last) {
  802. __cur->_M_next = __next->_M_next;
  803. _M_delete_node(__next);
  804. __next = __cur->_M_next;
  805. --_M_num_elements;
  806. }
  807. }
  808. }
  809. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  810. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  811. ::_M_erase_bucket(const size_type __n, _Node* __last)
  812. {
  813. _Node* __cur = _M_buckets[__n];
  814. while (__cur != __last) {
  815. _Node* __next = __cur->_M_next;
  816. _M_delete_node(__cur);
  817. __cur = __next;
  818. _M_buckets[__n] = __cur;
  819. --_M_num_elements;
  820. }
  821. }
  822. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  823. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear()
  824. {
  825. for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
  826. _Node* __cur = _M_buckets[__i];
  827. while (__cur != 0) {
  828. _Node* __next = __cur->_M_next;
  829. _M_delete_node(__cur);
  830. __cur = __next;
  831. }
  832. _M_buckets[__i] = 0;
  833. }
  834. _M_num_elements = 0;
  835. }
  836. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  837. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  838. ::_M_copy_from(const hashtable& __ht)
  839. {
  840. _M_buckets.clear();
  841. _M_buckets.reserve(__ht._M_buckets.size());
  842. _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
  843. try {
  844. for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
  845. const _Node* __cur = __ht._M_buckets[__i];
  846. if (__cur) {
  847. _Node* __copy = _M_new_node(__cur->_M_val);
  848. _M_buckets[__i] = __copy;
  849. for (_Node* __next = __cur->_M_next;
  850. __next;
  851. __cur = __next, __next = __cur->_M_next) {
  852. __copy->_M_next = _M_new_node(__next->_M_val);
  853. __copy = __copy->_M_next;
  854. }
  855. }
  856. }
  857. _M_num_elements = __ht._M_num_elements;
  858. }
  859. catch(...) {clear(); throw;}
  860. }
  861. } // namespace @KWSYS_NAMESPACE@
  862. // Undo warning suppression.
  863. #if defined(__clang__) && defined(__has_warning)
  864. # if __has_warning("-Wdeprecated")
  865. # pragma clang diagnostic pop
  866. # endif
  867. #endif
  868. #if defined(_MSC_VER)
  869. # pragma warning (pop)
  870. #endif
  871. #endif