hashtable.hxx.in 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258
  1. /*=========================================================================
  2. Program: KWSys - Kitware System Library
  3. Module: $RCSfile$
  4. Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
  5. See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even
  7. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  8. PURPOSE. See the above copyright notices 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. #ifndef @KWSYS_NAMESPACE@_hashtable_hxx
  36. #define @KWSYS_NAMESPACE@_hashtable_hxx
  37. #include <@KWSYS_NAMESPACE@/Configure.hxx>
  38. #include <@KWSYS_NAMESPACE@/cstddef> // size_t
  39. #include <@KWSYS_NAMESPACE@/stl/algorithm> // lower_bound
  40. #include <@KWSYS_NAMESPACE@/stl/functional> // unary_function
  41. #include <@KWSYS_NAMESPACE@/stl/iterator> // iterator_traits
  42. #include <@KWSYS_NAMESPACE@/stl/memory> // allocator
  43. #include <@KWSYS_NAMESPACE@/stl/utility> // pair
  44. #include <@KWSYS_NAMESPACE@/stl/vector> // vector
  45. #if defined(_MSC_VER)
  46. # pragma warning (push)
  47. # pragma warning (disable:4284)
  48. # pragma warning (disable:4786)
  49. #endif
  50. #if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_TEMPLATE
  51. # define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::allocator< T >
  52. #elif @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE
  53. # define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::allocator
  54. #else
  55. # define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::alloc
  56. #endif
  57. #if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS
  58. # define @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a) _M_buckets(__a)
  59. # define @KWSYS_NAMESPACE@_HASH_BUCKETS_GET_ALLOCATOR(__b) , __b.get_allocator()
  60. #else
  61. # define @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a) _M_buckets()
  62. # define @KWSYS_NAMESPACE@_HASH_BUCKETS_GET_ALLOCATOR(__b)
  63. #endif
  64. namespace @KWSYS_NAMESPACE@
  65. {
  66. //----------------------------------------------------------------------------
  67. // Define an allocator adaptor for platforms that do not provide an
  68. // allocator with the rebind member.
  69. #if !@KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_REBIND
  70. // Utility functions to convert item counts.
  71. inline size_t hash_sizeof(void*) { return sizeof(char); }
  72. inline size_t hash_sizeof(const void*) { return sizeof(char); }
  73. template <class TPtr> inline size_t hash_sizeof(TPtr p) { return sizeof(*p); }
  74. template <class POut, class PIn, class TSize>
  75. inline TSize hash_allocator_n(POut out, PIn in, TSize n)
  76. {
  77. return n*(hash_sizeof(out)/hash_sizeof(in) +
  78. (hash_sizeof(out)%hash_sizeof(in)>0));
  79. }
  80. // Define an allocation method to use the native allocator with
  81. // the proper signature. The following signatures of the allocate
  82. // method are used on various STL implementations:
  83. // pointer allocate(size_type, const void* hint)
  84. // pointer allocate(size_type)
  85. // static pointer allocate(size_type, const void* hint)
  86. // static pointer allocate(size_type)
  87. // Where pointer might be a real type or void*.
  88. // This set of overloads decodes the signature for a particular STL.
  89. // The extra three int/long arguments will favor certain signatures
  90. // over others in the case that multiple are present to avoid
  91. // ambiguity errors.
  92. template <class TAlloc, class PIn, class TSize, class THint, class POut>
  93. inline void hash_allocate(TAlloc* a, PIn (TAlloc::*allocate)(TSize, THint),
  94. TSize n_out, const void* hint, POut& out,
  95. int, int, int)
  96. {
  97. TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
  98. void* vout = (a->*allocate)(n_in, const_cast<THint>(hint));
  99. out = static_cast<POut>(vout);
  100. }
  101. template <class TAlloc, class PIn, class TSize, class POut>
  102. inline void hash_allocate(TAlloc* a, PIn (TAlloc::*allocate)(TSize),
  103. TSize n_out, const void*, POut& out,
  104. int, int, long)
  105. {
  106. TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
  107. void* vout = (a->*allocate)(n_in);
  108. out = static_cast<POut>(vout);
  109. }
  110. template <class PIn, class TSize, class THint, class POut>
  111. inline void hash_allocate(void*, PIn (*allocate)(TSize, THint),
  112. TSize n_out, const void* hint, POut& out,
  113. int, long, long)
  114. {
  115. TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
  116. void* vout = allocate(n_in, const_cast<THint>(hint));
  117. out = static_cast<POut>(vout);
  118. }
  119. template <class PIn, class TSize, class POut>
  120. inline void hash_allocate(void*, PIn (*allocate)(TSize),
  121. TSize n_out, const void*, POut& out,
  122. long, long, long)
  123. {
  124. TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
  125. void* vout = allocate(n_in);
  126. out = static_cast<POut>(vout);
  127. }
  128. // Define a deallocation method to use the native allocator with
  129. // the proper signature. The following signatures of the deallocate
  130. // method are used on various STL implementations:
  131. // void deallocate(pointer, size_type)
  132. // void deallocate(pointer)
  133. // static void deallocate(pointer, size_type)
  134. // static void deallocate(pointer)
  135. // Where pointer might be a real type or void*.
  136. // This set of overloads decodes the signature for a particular STL.
  137. // The extra three int/long arguments will favor certain signatures
  138. // over others in the case that multiple are present to avoid
  139. // ambiguity errors.
  140. template <class TAlloc, class PIn, class TSize, class PInReal, class POut>
  141. inline void hash_deallocate(TAlloc* a, void (TAlloc::*deallocate)(PIn, TSize),
  142. PInReal, POut p, TSize n_out, int, int, int)
  143. {
  144. TSize n_in = hash_allocator_n(POut(), PInReal(), n_out);
  145. void* vout = p;
  146. (a->*deallocate)(static_cast<PIn>(vout), n_in);
  147. }
  148. template <class TAlloc, class PIn, class TSize, class PInReal, class POut>
  149. inline void hash_deallocate(TAlloc* a, void (TAlloc::*deallocate)(PIn),
  150. PInReal, POut p, TSize, int, int, long)
  151. {
  152. void* vout = p;
  153. (a->*deallocate)(static_cast<PIn>(vout));
  154. }
  155. template <class PIn, class TSize, class PInReal, class POut>
  156. inline void hash_deallocate(void*, void (*deallocate)(PIn, TSize),
  157. PInReal, POut p, TSize n_out, int, long, long)
  158. {
  159. TSize n_in = hash_allocator_n(POut(), PInReal(), n_out);
  160. void* vout = p;
  161. deallocate(static_cast<PIn>(vout), n_in);
  162. }
  163. template <class PIn, class TSize, class PInReal, class POut>
  164. inline void hash_deallocate(void*, void (*deallocate)(PIn),
  165. PInReal, POut p, TSize, long, long, long)
  166. {
  167. void* vout = p;
  168. deallocate(static_cast<PIn>(vout));
  169. }
  170. // Use the same four overloads as hash_allocate to decode the type
  171. // really used for allocation. This is passed as PInReal to the
  172. // deallocate functions so that hash_allocator_n has the proper size.
  173. template <class TAlloc, class PIn, class TSize, class THint>
  174. inline PIn hash_allocate_type(PIn (TAlloc::*)(TSize, THint),
  175. int, int, int) { return 0; }
  176. template <class TAlloc, class PIn, class TSize>
  177. inline PIn hash_allocate_type(PIn (TAlloc::*)(TSize),
  178. int, int, long) { return 0; }
  179. template <class PIn, class TSize, class THint>
  180. inline PIn hash_allocate_type(PIn (*)(TSize, THint),
  181. int, long, long) { return 0; }
  182. template <class PIn, class TSize>
  183. inline PIn hash_allocate_type(PIn (*)(TSize),
  184. long, long, long) { return 0; }
  185. // Define the comparison operators in terms of a base type to avoid
  186. // needing templated versions.
  187. class hash_allocator_base {};
  188. bool operator==(const hash_allocator_base&,
  189. const hash_allocator_base&) throw() { return true; }
  190. bool operator!=(const hash_allocator_base&,
  191. const hash_allocator_base&) throw() { return false; }
  192. // Define the allocator template.
  193. template <class T, class Alloc>
  194. class hash_allocator: public hash_allocator_base
  195. {
  196. private:
  197. // Store the real allocator privately.
  198. typedef Alloc alloc_type;
  199. alloc_type alloc_;
  200. public:
  201. // Standard allocator interface.
  202. typedef size_t size_type;
  203. typedef ptrdiff_t difference_type;
  204. typedef T* pointer;
  205. typedef const T* const_pointer;
  206. typedef T& reference;
  207. typedef const T& const_reference;
  208. typedef T value_type;
  209. hash_allocator() throw(): alloc_() {}
  210. hash_allocator(const hash_allocator_base&) throw() : alloc_() {}
  211. hash_allocator(const hash_allocator& a) throw() : alloc_(a.alloc_) {}
  212. hash_allocator(const alloc_type& a) throw() : alloc_(a) {}
  213. ~hash_allocator() throw() {}
  214. # if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
  215. template <class U>
  216. struct rebind { typedef hash_allocator<U, alloc_type> other; };
  217. # endif
  218. pointer address(reference x) const { return &x; }
  219. const_pointer address(const_reference x) const { return &x; }
  220. typedef void* void_pointer;
  221. typedef const void* const_void_pointer;
  222. pointer allocate(size_type n=1, const_void_pointer hint = 0)
  223. {
  224. if(n)
  225. {
  226. pointer p;
  227. hash_allocate(&alloc_, &alloc_type::allocate, n, hint, p, 1, 1, 1);
  228. return p;
  229. }
  230. else
  231. {
  232. return 0;
  233. }
  234. }
  235. void deallocate(pointer p, size_type n=1)
  236. {
  237. if(n)
  238. {
  239. hash_deallocate(&alloc_, &alloc_type::deallocate,
  240. hash_allocate_type(&alloc_type::allocate, 1, 1, 1),
  241. p, n, 1, 1, 1);
  242. }
  243. }
  244. #if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
  245. size_type max_size(size_type s) const throw()
  246. {
  247. return alloc_.max_size(s);
  248. }
  249. #else
  250. size_type max_size() const throw()
  251. {
  252. size_type n = alloc_.max_size() / sizeof(value_type);
  253. return n>0? n:1;
  254. }
  255. #endif
  256. void construct(pointer p, const value_type& val) { new (p) value_type(val); }
  257. void destroy(pointer p) { (void)p; p->~value_type(); }
  258. };
  259. #endif
  260. template <class _Val>
  261. struct _Hashtable_node
  262. {
  263. _Hashtable_node* _M_next;
  264. _Val _M_val;
  265. };
  266. template <class _Val, class _Key, class _HashFcn,
  267. class _ExtractKey, class _EqualKey,
  268. class _Alloc = @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(char) >
  269. class hashtable;
  270. template <class _Val, class _Key, class _HashFcn,
  271. class _ExtractKey, class _EqualKey, class _Alloc>
  272. struct _Hashtable_iterator;
  273. template <class _Val, class _Key, class _HashFcn,
  274. class _ExtractKey, class _EqualKey, class _Alloc>
  275. struct _Hashtable_const_iterator;
  276. template <class _Val, class _Key, class _HashFcn,
  277. class _ExtractKey, class _EqualKey, class _Alloc>
  278. struct _Hashtable_iterator {
  279. typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  280. _Hashtable;
  281. typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
  282. _ExtractKey, _EqualKey, _Alloc>
  283. iterator;
  284. typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
  285. _ExtractKey, _EqualKey, _Alloc>
  286. const_iterator;
  287. typedef _Hashtable_node<_Val> _Node;
  288. typedef @KWSYS_NAMESPACE@_stl::forward_iterator_tag iterator_category;
  289. typedef _Val value_type;
  290. typedef ptrdiff_t difference_type;
  291. typedef size_t size_type;
  292. typedef _Val& reference;
  293. typedef _Val* pointer;
  294. _Node* _M_cur;
  295. _Hashtable* _M_ht;
  296. _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
  297. : _M_cur(__n), _M_ht(__tab) {}
  298. _Hashtable_iterator() {}
  299. reference operator*() const { return _M_cur->_M_val; }
  300. pointer operator->() const { return &(operator*()); }
  301. iterator& operator++();
  302. iterator operator++(int);
  303. bool operator==(const iterator& __it) const
  304. { return _M_cur == __it._M_cur; }
  305. bool operator!=(const iterator& __it) const
  306. { return _M_cur != __it._M_cur; }
  307. };
  308. template <class _Val, class _Key, class _HashFcn,
  309. class _ExtractKey, class _EqualKey, class _Alloc>
  310. struct _Hashtable_const_iterator {
  311. typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  312. _Hashtable;
  313. typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
  314. _ExtractKey,_EqualKey,_Alloc>
  315. iterator;
  316. typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
  317. _ExtractKey, _EqualKey, _Alloc>
  318. const_iterator;
  319. typedef _Hashtable_node<_Val> _Node;
  320. typedef @KWSYS_NAMESPACE@_stl::forward_iterator_tag iterator_category;
  321. typedef _Val value_type;
  322. typedef ptrdiff_t difference_type;
  323. typedef size_t size_type;
  324. typedef const _Val& reference;
  325. typedef const _Val* pointer;
  326. const _Node* _M_cur;
  327. const _Hashtable* _M_ht;
  328. _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
  329. : _M_cur(__n), _M_ht(__tab) {}
  330. _Hashtable_const_iterator() {}
  331. _Hashtable_const_iterator(const iterator& __it)
  332. : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {}
  333. reference operator*() const { return _M_cur->_M_val; }
  334. pointer operator->() const { return &(operator*()); }
  335. const_iterator& operator++();
  336. const_iterator operator++(int);
  337. bool operator==(const const_iterator& __it) const
  338. { return _M_cur == __it._M_cur; }
  339. bool operator!=(const const_iterator& __it) const
  340. { return _M_cur != __it._M_cur; }
  341. };
  342. // Note: assumes long is at least 32 bits.
  343. enum { _stl_num_primes = 31 };
  344. static const unsigned long _stl_prime_list[_stl_num_primes] =
  345. {
  346. 5ul, 11ul, 23ul,
  347. 53ul, 97ul, 193ul, 389ul, 769ul,
  348. 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
  349. 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
  350. 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
  351. 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
  352. 1610612741ul, 3221225473ul, 4294967291ul
  353. };
  354. inline unsigned long _stl_next_prime(unsigned long __n)
  355. {
  356. const unsigned long* __first = _stl_prime_list;
  357. const unsigned long* __last = _stl_prime_list + (int)_stl_num_primes;
  358. const unsigned long* pos = @KWSYS_NAMESPACE@_stl::lower_bound(__first, __last, __n);
  359. return pos == __last ? *(__last - 1) : *pos;
  360. }
  361. // Forward declaration of operator==.
  362. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  363. class hashtable;
  364. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  365. bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
  366. const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2);
  367. // Hashtables handle allocators a bit differently than other containers
  368. // do. If we're using standard-conforming allocators, then a hashtable
  369. // unconditionally has a member variable to hold its allocator, even if
  370. // it so happens that all instances of the allocator type are identical.
  371. // This is because, for hashtables, this extra storage is negligible.
  372. // Additionally, a base class wouldn't serve any other purposes; it
  373. // wouldn't, for example, simplify the exception-handling code.
  374. template <class _Val, class _Key, class _HashFcn,
  375. class _ExtractKey, class _EqualKey, class _Alloc>
  376. class hashtable {
  377. public:
  378. typedef _Key key_type;
  379. typedef _Val value_type;
  380. typedef _HashFcn hasher;
  381. typedef _EqualKey key_equal;
  382. typedef size_t size_type;
  383. typedef ptrdiff_t difference_type;
  384. typedef value_type* pointer;
  385. typedef const value_type* const_pointer;
  386. typedef value_type& reference;
  387. typedef const value_type& const_reference;
  388. hasher hash_funct() const { return _M_hash; }
  389. key_equal key_eq() const { return _M_equals; }
  390. private:
  391. typedef _Hashtable_node<_Val> _Node;
  392. #if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_REBIND
  393. public:
  394. typedef typename _Alloc::template rebind<_Val>::other allocator_type;
  395. allocator_type get_allocator() const { return _M_node_allocator; }
  396. private:
  397. typedef typename _Alloc::template rebind<_Node>::other _M_node_allocator_type;
  398. typedef typename _Alloc::template rebind<_Node*>::other _M_node_ptr_allocator_type;
  399. typedef @KWSYS_NAMESPACE@_stl::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type;
  400. #else
  401. public:
  402. typedef hash_allocator<_Val, _Alloc> allocator_type;
  403. allocator_type get_allocator() const { return allocator_type(); }
  404. private:
  405. typedef hash_allocator<_Node, _Alloc> _M_node_allocator_type;
  406. # if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS
  407. typedef hash_allocator<_Node*, _Alloc> _M_node_ptr_allocator_type;
  408. # else
  409. typedef _Alloc _M_node_ptr_allocator_type;
  410. # endif
  411. typedef @KWSYS_NAMESPACE@_stl::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type;
  412. #endif
  413. private:
  414. _M_node_allocator_type _M_node_allocator;
  415. hasher _M_hash;
  416. key_equal _M_equals;
  417. _ExtractKey _M_get_key;
  418. _M_buckets_type _M_buckets;
  419. size_type _M_num_elements;
  420. _Node* _M_get_node() { return _M_node_allocator.allocate(1); }
  421. void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
  422. public:
  423. typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  424. iterator;
  425. typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,
  426. _Alloc>
  427. const_iterator;
  428. friend struct
  429. _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
  430. friend struct
  431. _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
  432. public:
  433. hashtable(size_type __n,
  434. const _HashFcn& __hf,
  435. const _EqualKey& __eql,
  436. const _ExtractKey& __ext,
  437. const allocator_type& __a = allocator_type())
  438. : _M_node_allocator(__a),
  439. _M_hash(__hf),
  440. _M_equals(__eql),
  441. _M_get_key(__ext),
  442. @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a),
  443. _M_num_elements(0)
  444. {
  445. _M_initialize_buckets(__n);
  446. }
  447. hashtable(size_type __n,
  448. const _HashFcn& __hf,
  449. const _EqualKey& __eql,
  450. const allocator_type& __a = allocator_type())
  451. : _M_node_allocator(__a),
  452. _M_hash(__hf),
  453. _M_equals(__eql),
  454. _M_get_key(_ExtractKey()),
  455. @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a),
  456. _M_num_elements(0)
  457. {
  458. _M_initialize_buckets(__n);
  459. }
  460. hashtable(const hashtable& __ht)
  461. : _M_node_allocator(__ht.get_allocator()),
  462. _M_hash(__ht._M_hash),
  463. _M_equals(__ht._M_equals),
  464. _M_get_key(__ht._M_get_key),
  465. @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__ht.get_allocator()),
  466. _M_num_elements(0)
  467. {
  468. _M_copy_from(__ht);
  469. }
  470. hashtable& operator= (const hashtable& __ht)
  471. {
  472. if (&__ht != this) {
  473. clear();
  474. _M_hash = __ht._M_hash;
  475. _M_equals = __ht._M_equals;
  476. _M_get_key = __ht._M_get_key;
  477. _M_copy_from(__ht);
  478. }
  479. return *this;
  480. }
  481. ~hashtable() { clear(); }
  482. size_type size() const { return _M_num_elements; }
  483. size_type max_size() const { return size_type(-1); }
  484. bool empty() const { return size() == 0; }
  485. void swap(hashtable& __ht)
  486. {
  487. @KWSYS_NAMESPACE@_stl::swap(_M_hash, __ht._M_hash);
  488. @KWSYS_NAMESPACE@_stl::swap(_M_equals, __ht._M_equals);
  489. @KWSYS_NAMESPACE@_stl::swap(_M_get_key, __ht._M_get_key);
  490. _M_buckets.swap(__ht._M_buckets);
  491. @KWSYS_NAMESPACE@_stl::swap(_M_num_elements, __ht._M_num_elements);
  492. }
  493. iterator begin()
  494. {
  495. for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
  496. if (_M_buckets[__n])
  497. return iterator(_M_buckets[__n], this);
  498. return end();
  499. }
  500. iterator end() { return iterator(0, this); }
  501. const_iterator begin() const
  502. {
  503. for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
  504. if (_M_buckets[__n])
  505. return const_iterator(_M_buckets[__n], this);
  506. return end();
  507. }
  508. const_iterator end() const { return const_iterator(0, this); }
  509. friend bool operator==@KWSYS_NAMESPACE@_CXX_NULL_TEMPLATE_ARGS(const hashtable&,
  510. const hashtable&);
  511. public:
  512. size_type bucket_count() const { return _M_buckets.size(); }
  513. size_type max_bucket_count() const
  514. { return _stl_prime_list[(int)_stl_num_primes - 1]; }
  515. size_type elems_in_bucket(size_type __bucket) const
  516. {
  517. size_type __result = 0;
  518. for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next)
  519. __result += 1;
  520. return __result;
  521. }
  522. @KWSYS_NAMESPACE@_stl::pair<iterator, bool> insert_unique(const value_type& __obj)
  523. {
  524. resize(_M_num_elements + 1);
  525. return insert_unique_noresize(__obj);
  526. }
  527. iterator insert_equal(const value_type& __obj)
  528. {
  529. resize(_M_num_elements + 1);
  530. return insert_equal_noresize(__obj);
  531. }
  532. @KWSYS_NAMESPACE@_stl::pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
  533. iterator insert_equal_noresize(const value_type& __obj);
  534. #if @KWSYS_NAMESPACE@_STL_HAS_ITERATOR_TRAITS
  535. # define @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(T,I) \
  536. typename @KWSYS_NAMESPACE@_stl::iterator_traits< T >::iterator_category()
  537. #elif @KWSYS_NAMESPACE@_STL_HAS_ITERATOR_CATEGORY
  538. # define @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(T,I) \
  539. @KWSYS_NAMESPACE@_stl::iterator_category( I )
  540. #elif @KWSYS_NAMESPACE@_STL_HAS___ITERATOR_CATEGORY
  541. # define @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(T,I) \
  542. @KWSYS_NAMESPACE@_stl::__iterator_category( I )
  543. #endif
  544. #if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES && defined(@KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY)
  545. template <class _InputIterator>
  546. void insert_unique(_InputIterator __f, _InputIterator __l)
  547. {
  548. insert_unique(__f, __l,
  549. @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(_InputIterator, __f));
  550. }
  551. template <class _InputIterator>
  552. void insert_equal(_InputIterator __f, _InputIterator __l)
  553. {
  554. insert_equal(__f, __l,
  555. @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(_InputIterator, __f));
  556. }
  557. template <class _InputIterator>
  558. void insert_unique(_InputIterator __f, _InputIterator __l,
  559. @KWSYS_NAMESPACE@_stl::input_iterator_tag)
  560. {
  561. for ( ; __f != __l; ++__f)
  562. insert_unique(*__f);
  563. }
  564. template <class _InputIterator>
  565. void insert_equal(_InputIterator __f, _InputIterator __l,
  566. @KWSYS_NAMESPACE@_stl::input_iterator_tag)
  567. {
  568. for ( ; __f != __l; ++__f)
  569. insert_equal(*__f);
  570. }
  571. template <class _ForwardIterator>
  572. void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
  573. @KWSYS_NAMESPACE@_stl::forward_iterator_tag)
  574. {
  575. size_type __n = 0;
  576. @KWSYS_NAMESPACE@_stl::distance(__f, __l, __n);
  577. resize(_M_num_elements + __n);
  578. for ( ; __n > 0; --__n, ++__f)
  579. insert_unique_noresize(*__f);
  580. }
  581. template <class _ForwardIterator>
  582. void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
  583. @KWSYS_NAMESPACE@_stl::forward_iterator_tag)
  584. {
  585. size_type __n = 0;
  586. @KWSYS_NAMESPACE@_stl::distance(__f, __l, __n);
  587. resize(_M_num_elements + __n);
  588. for ( ; __n > 0; --__n, ++__f)
  589. insert_equal_noresize(*__f);
  590. }
  591. #else
  592. void insert_unique(const value_type* __f, const value_type* __l)
  593. {
  594. size_type __n = __l - __f;
  595. resize(_M_num_elements + __n);
  596. for ( ; __n > 0; --__n, ++__f)
  597. insert_unique_noresize(*__f);
  598. }
  599. void insert_equal(const value_type* __f, const value_type* __l)
  600. {
  601. size_type __n = __l - __f;
  602. resize(_M_num_elements + __n);
  603. for ( ; __n > 0; --__n, ++__f)
  604. insert_equal_noresize(*__f);
  605. }
  606. void insert_unique(const_iterator __f, const_iterator __l)
  607. {
  608. size_type __n = 0;
  609. @KWSYS_NAMESPACE@_stl::distance(__f, __l, __n);
  610. resize(_M_num_elements + __n);
  611. for ( ; __n > 0; --__n, ++__f)
  612. insert_unique_noresize(*__f);
  613. }
  614. void insert_equal(const_iterator __f, const_iterator __l)
  615. {
  616. size_type __n = 0;
  617. @KWSYS_NAMESPACE@_stl::distance(__f, __l, __n);
  618. resize(_M_num_elements + __n);
  619. for ( ; __n > 0; --__n, ++__f)
  620. insert_equal_noresize(*__f);
  621. }
  622. #endif
  623. reference find_or_insert(const value_type& __obj);
  624. iterator find(const key_type& __key)
  625. {
  626. size_type __n = _M_bkt_num_key(__key);
  627. _Node* __first;
  628. for ( __first = _M_buckets[__n];
  629. __first && !_M_equals(_M_get_key(__first->_M_val), __key);
  630. __first = __first->_M_next)
  631. {}
  632. return iterator(__first, this);
  633. }
  634. const_iterator find(const key_type& __key) const
  635. {
  636. size_type __n = _M_bkt_num_key(__key);
  637. const _Node* __first;
  638. for ( __first = _M_buckets[__n];
  639. __first && !_M_equals(_M_get_key(__first->_M_val), __key);
  640. __first = __first->_M_next)
  641. {}
  642. return const_iterator(__first, this);
  643. }
  644. size_type count(const key_type& __key) const
  645. {
  646. const size_type __n = _M_bkt_num_key(__key);
  647. size_type __result = 0;
  648. for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next)
  649. if (_M_equals(_M_get_key(__cur->_M_val), __key))
  650. ++__result;
  651. return __result;
  652. }
  653. @KWSYS_NAMESPACE@_stl::pair<iterator, iterator>
  654. equal_range(const key_type& __key);
  655. @KWSYS_NAMESPACE@_stl::pair<const_iterator, const_iterator>
  656. equal_range(const key_type& __key) const;
  657. size_type erase(const key_type& __key);
  658. void erase(const iterator& __it);
  659. void erase(iterator __first, iterator __last);
  660. void erase(const const_iterator& __it);
  661. void erase(const_iterator __first, const_iterator __last);
  662. void resize(size_type __num_elements_hint);
  663. void clear();
  664. private:
  665. size_type _M_next_size(size_type __n) const
  666. { return _stl_next_prime(__n); }
  667. void _M_initialize_buckets(size_type __n)
  668. {
  669. const size_type __n_buckets = _M_next_size(__n);
  670. _M_buckets.reserve(__n_buckets);
  671. _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
  672. _M_num_elements = 0;
  673. }
  674. size_type _M_bkt_num_key(const key_type& __key) const
  675. {
  676. return _M_bkt_num_key(__key, _M_buckets.size());
  677. }
  678. size_type _M_bkt_num(const value_type& __obj) const
  679. {
  680. return _M_bkt_num_key(_M_get_key(__obj));
  681. }
  682. size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
  683. {
  684. return _M_hash(__key) % __n;
  685. }
  686. size_type _M_bkt_num(const value_type& __obj, size_t __n) const
  687. {
  688. return _M_bkt_num_key(_M_get_key(__obj), __n);
  689. }
  690. void construct(_Val* p, const _Val& v)
  691. {
  692. new (p) _Val(v);
  693. }
  694. void destroy(_Val* p)
  695. {
  696. (void)p;
  697. p->~_Val();
  698. }
  699. _Node* _M_new_node(const value_type& __obj)
  700. {
  701. _Node* __n = _M_get_node();
  702. __n->_M_next = 0;
  703. try {
  704. construct(&__n->_M_val, __obj);
  705. return __n;
  706. }
  707. catch(...) {_M_put_node(__n); throw;}
  708. }
  709. void _M_delete_node(_Node* __n)
  710. {
  711. destroy(&__n->_M_val);
  712. _M_put_node(__n);
  713. }
  714. void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
  715. void _M_erase_bucket(const size_type __n, _Node* __last);
  716. void _M_copy_from(const hashtable& __ht);
  717. };
  718. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  719. class _All>
  720. _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
  721. _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
  722. {
  723. const _Node* __old = _M_cur;
  724. _M_cur = _M_cur->_M_next;
  725. if (!_M_cur) {
  726. size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
  727. while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
  728. _M_cur = _M_ht->_M_buckets[__bucket];
  729. }
  730. return *this;
  731. }
  732. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  733. class _All>
  734. inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
  735. _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
  736. {
  737. iterator __tmp = *this;
  738. ++*this;
  739. return __tmp;
  740. }
  741. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  742. class _All>
  743. _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
  744. _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
  745. {
  746. const _Node* __old = _M_cur;
  747. _M_cur = _M_cur->_M_next;
  748. if (!_M_cur) {
  749. size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
  750. while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
  751. _M_cur = _M_ht->_M_buckets[__bucket];
  752. }
  753. return *this;
  754. }
  755. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  756. class _All>
  757. inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
  758. _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
  759. {
  760. const_iterator __tmp = *this;
  761. ++*this;
  762. return __tmp;
  763. }
  764. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  765. bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
  766. const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2)
  767. {
  768. typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node;
  769. if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
  770. return false;
  771. for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) {
  772. _Node* __cur1 = __ht1._M_buckets[__n];
  773. _Node* __cur2 = __ht2._M_buckets[__n];
  774. for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val;
  775. __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
  776. {}
  777. if (__cur1 || __cur2)
  778. return false;
  779. }
  780. return true;
  781. }
  782. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  783. inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
  784. const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) {
  785. return !(__ht1 == __ht2);
  786. }
  787. template <class _Val, class _Key, class _HF, class _Extract, class _EqKey,
  788. class _All>
  789. inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
  790. hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) {
  791. __ht1.swap(__ht2);
  792. }
  793. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  794. @KWSYS_NAMESPACE@_stl::pair<@KWSYS_NAMESPACE@_CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool>
  795. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  796. ::insert_unique_noresize(const value_type& __obj)
  797. {
  798. const size_type __n = _M_bkt_num(__obj);
  799. _Node* __first = _M_buckets[__n];
  800. for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  801. if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
  802. return @KWSYS_NAMESPACE@_stl::pair<iterator, bool>(iterator(__cur, this), false);
  803. _Node* __tmp = _M_new_node(__obj);
  804. __tmp->_M_next = __first;
  805. _M_buckets[__n] = __tmp;
  806. ++_M_num_elements;
  807. return @KWSYS_NAMESPACE@_stl::pair<iterator, bool>(iterator(__tmp, this), true);
  808. }
  809. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  810. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator
  811. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  812. ::insert_equal_noresize(const value_type& __obj)
  813. {
  814. const size_type __n = _M_bkt_num(__obj);
  815. _Node* __first = _M_buckets[__n];
  816. for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  817. if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
  818. _Node* __tmp = _M_new_node(__obj);
  819. __tmp->_M_next = __cur->_M_next;
  820. __cur->_M_next = __tmp;
  821. ++_M_num_elements;
  822. return iterator(__tmp, this);
  823. }
  824. _Node* __tmp = _M_new_node(__obj);
  825. __tmp->_M_next = __first;
  826. _M_buckets[__n] = __tmp;
  827. ++_M_num_elements;
  828. return iterator(__tmp, this);
  829. }
  830. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  831. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference
  832. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj)
  833. {
  834. resize(_M_num_elements + 1);
  835. size_type __n = _M_bkt_num(__obj);
  836. _Node* __first = _M_buckets[__n];
  837. for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  838. if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
  839. return __cur->_M_val;
  840. _Node* __tmp = _M_new_node(__obj);
  841. __tmp->_M_next = __first;
  842. _M_buckets[__n] = __tmp;
  843. ++_M_num_elements;
  844. return __tmp->_M_val;
  845. }
  846. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  847. @KWSYS_NAMESPACE@_stl::pair<@KWSYS_NAMESPACE@_CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator,
  848. @KWSYS_NAMESPACE@_CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator>
  849. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
  850. {
  851. typedef @KWSYS_NAMESPACE@_stl::pair<iterator, iterator> _Pii;
  852. const size_type __n = _M_bkt_num_key(__key);
  853. for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next)
  854. if (_M_equals(_M_get_key(__first->_M_val), __key)) {
  855. for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next)
  856. if (!_M_equals(_M_get_key(__cur->_M_val), __key))
  857. return _Pii(iterator(__first, this), iterator(__cur, this));
  858. for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
  859. if (_M_buckets[__m])
  860. return _Pii(iterator(__first, this),
  861. iterator(_M_buckets[__m], this));
  862. return _Pii(iterator(__first, this), end());
  863. }
  864. return _Pii(end(), end());
  865. }
  866. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  867. @KWSYS_NAMESPACE@_stl::pair<@KWSYS_NAMESPACE@_CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator,
  868. @KWSYS_NAMESPACE@_CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator>
  869. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  870. ::equal_range(const key_type& __key) const
  871. {
  872. typedef @KWSYS_NAMESPACE@_stl::pair<const_iterator, const_iterator> _Pii;
  873. const size_type __n = _M_bkt_num_key(__key);
  874. for (const _Node* __first = _M_buckets[__n] ;
  875. __first;
  876. __first = __first->_M_next) {
  877. if (_M_equals(_M_get_key(__first->_M_val), __key)) {
  878. for (const _Node* __cur = __first->_M_next;
  879. __cur;
  880. __cur = __cur->_M_next)
  881. if (!_M_equals(_M_get_key(__cur->_M_val), __key))
  882. return _Pii(const_iterator(__first, this),
  883. const_iterator(__cur, this));
  884. for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
  885. if (_M_buckets[__m])
  886. return _Pii(const_iterator(__first, this),
  887. const_iterator(_M_buckets[__m], this));
  888. return _Pii(const_iterator(__first, this), end());
  889. }
  890. }
  891. return _Pii(end(), end());
  892. }
  893. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  894. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type
  895. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key)
  896. {
  897. const size_type __n = _M_bkt_num_key(__key);
  898. _Node* __first = _M_buckets[__n];
  899. size_type __erased = 0;
  900. if (__first) {
  901. _Node* __cur = __first;
  902. _Node* __next = __cur->_M_next;
  903. while (__next) {
  904. if (_M_equals(_M_get_key(__next->_M_val), __key)) {
  905. __cur->_M_next = __next->_M_next;
  906. _M_delete_node(__next);
  907. __next = __cur->_M_next;
  908. ++__erased;
  909. --_M_num_elements;
  910. }
  911. else {
  912. __cur = __next;
  913. __next = __cur->_M_next;
  914. }
  915. }
  916. if (_M_equals(_M_get_key(__first->_M_val), __key)) {
  917. _M_buckets[__n] = __first->_M_next;
  918. _M_delete_node(__first);
  919. ++__erased;
  920. --_M_num_elements;
  921. }
  922. }
  923. return __erased;
  924. }
  925. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  926. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it)
  927. {
  928. _Node* __p = __it._M_cur;
  929. if (__p) {
  930. const size_type __n = _M_bkt_num(__p->_M_val);
  931. _Node* __cur = _M_buckets[__n];
  932. if (__cur == __p) {
  933. _M_buckets[__n] = __cur->_M_next;
  934. _M_delete_node(__cur);
  935. --_M_num_elements;
  936. }
  937. else {
  938. _Node* __next = __cur->_M_next;
  939. while (__next) {
  940. if (__next == __p) {
  941. __cur->_M_next = __next->_M_next;
  942. _M_delete_node(__next);
  943. --_M_num_elements;
  944. break;
  945. }
  946. else {
  947. __cur = __next;
  948. __next = __cur->_M_next;
  949. }
  950. }
  951. }
  952. }
  953. }
  954. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  955. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  956. ::erase(iterator __first, iterator __last)
  957. {
  958. size_type __f_bucket = __first._M_cur ?
  959. _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
  960. size_type __l_bucket = __last._M_cur ?
  961. _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
  962. if (__first._M_cur == __last._M_cur)
  963. return;
  964. else if (__f_bucket == __l_bucket)
  965. _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
  966. else {
  967. _M_erase_bucket(__f_bucket, __first._M_cur, 0);
  968. for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
  969. _M_erase_bucket(__n, 0);
  970. if (__l_bucket != _M_buckets.size())
  971. _M_erase_bucket(__l_bucket, __last._M_cur);
  972. }
  973. }
  974. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  975. inline void
  976. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first,
  977. const_iterator __last)
  978. {
  979. erase(iterator(const_cast<_Node*>(__first._M_cur),
  980. const_cast<hashtable*>(__first._M_ht)),
  981. iterator(const_cast<_Node*>(__last._M_cur),
  982. const_cast<hashtable*>(__last._M_ht)));
  983. }
  984. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  985. inline void
  986. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it)
  987. {
  988. erase(iterator(const_cast<_Node*>(__it._M_cur),
  989. const_cast<hashtable*>(__it._M_ht)));
  990. }
  991. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  992. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  993. ::resize(size_type __num_elements_hint)
  994. {
  995. const size_type __old_n = _M_buckets.size();
  996. if (__num_elements_hint > __old_n) {
  997. const size_type __n = _M_next_size(__num_elements_hint);
  998. if (__n > __old_n) {
  999. _M_buckets_type __tmp(
  1000. __n, (_Node*)(0)
  1001. @KWSYS_NAMESPACE@_HASH_BUCKETS_GET_ALLOCATOR(_M_buckets));
  1002. try {
  1003. for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
  1004. _Node* __first = _M_buckets[__bucket];
  1005. while (__first) {
  1006. size_type __new_bucket = _M_bkt_num(__first->_M_val, __n);
  1007. _M_buckets[__bucket] = __first->_M_next;
  1008. __first->_M_next = __tmp[__new_bucket];
  1009. __tmp[__new_bucket] = __first;
  1010. __first = _M_buckets[__bucket];
  1011. }
  1012. }
  1013. _M_buckets.swap(__tmp);
  1014. }
  1015. catch(...) {
  1016. for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
  1017. while (__tmp[__bucket]) {
  1018. _Node* __next = __tmp[__bucket]->_M_next;
  1019. _M_delete_node(__tmp[__bucket]);
  1020. __tmp[__bucket] = __next;
  1021. }
  1022. }
  1023. throw;
  1024. }
  1025. }
  1026. }
  1027. }
  1028. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  1029. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  1030. ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
  1031. {
  1032. _Node* __cur = _M_buckets[__n];
  1033. if (__cur == __first)
  1034. _M_erase_bucket(__n, __last);
  1035. else {
  1036. _Node* __next;
  1037. for (__next = __cur->_M_next;
  1038. __next != __first;
  1039. __cur = __next, __next = __cur->_M_next)
  1040. ;
  1041. while (__next != __last) {
  1042. __cur->_M_next = __next->_M_next;
  1043. _M_delete_node(__next);
  1044. __next = __cur->_M_next;
  1045. --_M_num_elements;
  1046. }
  1047. }
  1048. }
  1049. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  1050. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  1051. ::_M_erase_bucket(const size_type __n, _Node* __last)
  1052. {
  1053. _Node* __cur = _M_buckets[__n];
  1054. while (__cur != __last) {
  1055. _Node* __next = __cur->_M_next;
  1056. _M_delete_node(__cur);
  1057. __cur = __next;
  1058. _M_buckets[__n] = __cur;
  1059. --_M_num_elements;
  1060. }
  1061. }
  1062. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  1063. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear()
  1064. {
  1065. for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
  1066. _Node* __cur = _M_buckets[__i];
  1067. while (__cur != 0) {
  1068. _Node* __next = __cur->_M_next;
  1069. _M_delete_node(__cur);
  1070. __cur = __next;
  1071. }
  1072. _M_buckets[__i] = 0;
  1073. }
  1074. _M_num_elements = 0;
  1075. }
  1076. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  1077. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  1078. ::_M_copy_from(const hashtable& __ht)
  1079. {
  1080. _M_buckets.clear();
  1081. _M_buckets.reserve(__ht._M_buckets.size());
  1082. _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
  1083. try {
  1084. for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
  1085. const _Node* __cur = __ht._M_buckets[__i];
  1086. if (__cur) {
  1087. _Node* __copy = _M_new_node(__cur->_M_val);
  1088. _M_buckets[__i] = __copy;
  1089. for (_Node* __next = __cur->_M_next;
  1090. __next;
  1091. __cur = __next, __next = __cur->_M_next) {
  1092. __copy->_M_next = _M_new_node(__next->_M_val);
  1093. __copy = __copy->_M_next;
  1094. }
  1095. }
  1096. }
  1097. _M_num_elements = __ht._M_num_elements;
  1098. }
  1099. catch(...) {clear(); throw;}
  1100. }
  1101. } // namespace @KWSYS_NAMESPACE@
  1102. // Normally the comparison operators should be found in the @KWSYS_NAMESPACE@
  1103. // namespace by argument dependent lookup. For compilers that do not
  1104. // support it we must bring them into the global namespace now.
  1105. #if !@KWSYS_NAMESPACE@_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
  1106. using @KWSYS_NAMESPACE@::operator==;
  1107. using @KWSYS_NAMESPACE@::operator!=;
  1108. #endif
  1109. #if defined(_MSC_VER)
  1110. # pragma warning (pop)
  1111. #endif
  1112. #endif