hash_set 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. // Hashing set implementation -*- C++ -*-
  2. // Copyright (C) 2001-2017 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
  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/hash_set
  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_HASH_SET
  50. #define _BACKWARD_HASH_SET 1
  51. #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
  52. #include "backward_warning.h"
  53. #endif
  54. #include <bits/c++config.h>
  55. #include <backward/hashtable.h>
  56. #include <bits/concept_check.h>
  57. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  58. {
  59. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  60. using std::equal_to;
  61. using std::allocator;
  62. using std::pair;
  63. using std::_Identity;
  64. /**
  65. * This is an SGI extension.
  66. * @ingroup SGIextensions
  67. * @doctodo
  68. */
  69. template<class _Value, class _HashFcn = hash<_Value>,
  70. class _EqualKey = equal_to<_Value>,
  71. class _Alloc = allocator<_Value> >
  72. class hash_set
  73. {
  74. // concept requirements
  75. __glibcxx_class_requires(_Value, _SGIAssignableConcept)
  76. __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
  77. __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
  78. private:
  79. typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
  80. _EqualKey, _Alloc> _Ht;
  81. _Ht _M_ht;
  82. public:
  83. typedef typename _Ht::key_type key_type;
  84. typedef typename _Ht::value_type value_type;
  85. typedef typename _Ht::hasher hasher;
  86. typedef typename _Ht::key_equal key_equal;
  87. typedef typename _Ht::size_type size_type;
  88. typedef typename _Ht::difference_type difference_type;
  89. typedef typename _Alloc::pointer pointer;
  90. typedef typename _Alloc::const_pointer const_pointer;
  91. typedef typename _Alloc::reference reference;
  92. typedef typename _Alloc::const_reference const_reference;
  93. typedef typename _Ht::const_iterator iterator;
  94. typedef typename _Ht::const_iterator const_iterator;
  95. typedef typename _Ht::allocator_type allocator_type;
  96. hasher
  97. hash_funct() const
  98. { return _M_ht.hash_funct(); }
  99. key_equal
  100. key_eq() const
  101. { return _M_ht.key_eq(); }
  102. allocator_type
  103. get_allocator() const
  104. { return _M_ht.get_allocator(); }
  105. hash_set()
  106. : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
  107. explicit
  108. hash_set(size_type __n)
  109. : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
  110. hash_set(size_type __n, const hasher& __hf)
  111. : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
  112. hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
  113. const allocator_type& __a = allocator_type())
  114. : _M_ht(__n, __hf, __eql, __a) {}
  115. template<class _InputIterator>
  116. hash_set(_InputIterator __f, _InputIterator __l)
  117. : _M_ht(100, hasher(), key_equal(), allocator_type())
  118. { _M_ht.insert_unique(__f, __l); }
  119. template<class _InputIterator>
  120. hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
  121. : _M_ht(__n, hasher(), key_equal(), allocator_type())
  122. { _M_ht.insert_unique(__f, __l); }
  123. template<class _InputIterator>
  124. hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
  125. const hasher& __hf)
  126. : _M_ht(__n, __hf, key_equal(), allocator_type())
  127. { _M_ht.insert_unique(__f, __l); }
  128. template<class _InputIterator>
  129. hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
  130. const hasher& __hf, const key_equal& __eql,
  131. const allocator_type& __a = allocator_type())
  132. : _M_ht(__n, __hf, __eql, __a)
  133. { _M_ht.insert_unique(__f, __l); }
  134. size_type
  135. size() const
  136. { return _M_ht.size(); }
  137. size_type
  138. max_size() const
  139. { return _M_ht.max_size(); }
  140. bool
  141. empty() const
  142. { return _M_ht.empty(); }
  143. void
  144. swap(hash_set& __hs)
  145. { _M_ht.swap(__hs._M_ht); }
  146. template<class _Val, class _HF, class _EqK, class _Al>
  147. friend bool
  148. operator==(const hash_set<_Val, _HF, _EqK, _Al>&,
  149. const hash_set<_Val, _HF, _EqK, _Al>&);
  150. iterator
  151. begin() const
  152. { return _M_ht.begin(); }
  153. iterator
  154. end() const
  155. { return _M_ht.end(); }
  156. pair<iterator, bool>
  157. insert(const value_type& __obj)
  158. {
  159. pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj);
  160. return pair<iterator,bool>(__p.first, __p.second);
  161. }
  162. template<class _InputIterator>
  163. void
  164. insert(_InputIterator __f, _InputIterator __l)
  165. { _M_ht.insert_unique(__f, __l); }
  166. pair<iterator, bool>
  167. insert_noresize(const value_type& __obj)
  168. {
  169. pair<typename _Ht::iterator, bool> __p
  170. = _M_ht.insert_unique_noresize(__obj);
  171. return pair<iterator, bool>(__p.first, __p.second);
  172. }
  173. iterator
  174. find(const key_type& __key) const
  175. { return _M_ht.find(__key); }
  176. size_type
  177. count(const key_type& __key) const
  178. { return _M_ht.count(__key); }
  179. pair<iterator, iterator>
  180. equal_range(const key_type& __key) const
  181. { return _M_ht.equal_range(__key); }
  182. size_type
  183. erase(const key_type& __key)
  184. {return _M_ht.erase(__key); }
  185. void
  186. erase(iterator __it)
  187. { _M_ht.erase(__it); }
  188. void
  189. erase(iterator __f, iterator __l)
  190. { _M_ht.erase(__f, __l); }
  191. void
  192. clear()
  193. { _M_ht.clear(); }
  194. void
  195. resize(size_type __hint)
  196. { _M_ht.resize(__hint); }
  197. size_type
  198. bucket_count() const
  199. { return _M_ht.bucket_count(); }
  200. size_type
  201. max_bucket_count() const
  202. { return _M_ht.max_bucket_count(); }
  203. size_type
  204. elems_in_bucket(size_type __n) const
  205. { return _M_ht.elems_in_bucket(__n); }
  206. };
  207. template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
  208. inline bool
  209. operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
  210. const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
  211. { return __hs1._M_ht == __hs2._M_ht; }
  212. template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
  213. inline bool
  214. operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
  215. const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
  216. { return !(__hs1 == __hs2); }
  217. template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
  218. inline void
  219. swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
  220. hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
  221. { __hs1.swap(__hs2); }
  222. /**
  223. * This is an SGI extension.
  224. * @ingroup SGIextensions
  225. * @doctodo
  226. */
  227. template<class _Value,
  228. class _HashFcn = hash<_Value>,
  229. class _EqualKey = equal_to<_Value>,
  230. class _Alloc = allocator<_Value> >
  231. class hash_multiset
  232. {
  233. // concept requirements
  234. __glibcxx_class_requires(_Value, _SGIAssignableConcept)
  235. __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
  236. __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
  237. private:
  238. typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
  239. _EqualKey, _Alloc> _Ht;
  240. _Ht _M_ht;
  241. public:
  242. typedef typename _Ht::key_type key_type;
  243. typedef typename _Ht::value_type value_type;
  244. typedef typename _Ht::hasher hasher;
  245. typedef typename _Ht::key_equal key_equal;
  246. typedef typename _Ht::size_type size_type;
  247. typedef typename _Ht::difference_type difference_type;
  248. typedef typename _Alloc::pointer pointer;
  249. typedef typename _Alloc::const_pointer const_pointer;
  250. typedef typename _Alloc::reference reference;
  251. typedef typename _Alloc::const_reference const_reference;
  252. typedef typename _Ht::const_iterator iterator;
  253. typedef typename _Ht::const_iterator const_iterator;
  254. typedef typename _Ht::allocator_type allocator_type;
  255. hasher
  256. hash_funct() const
  257. { return _M_ht.hash_funct(); }
  258. key_equal
  259. key_eq() const
  260. { return _M_ht.key_eq(); }
  261. allocator_type
  262. get_allocator() const
  263. { return _M_ht.get_allocator(); }
  264. hash_multiset()
  265. : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
  266. explicit
  267. hash_multiset(size_type __n)
  268. : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
  269. hash_multiset(size_type __n, const hasher& __hf)
  270. : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
  271. hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
  272. const allocator_type& __a = allocator_type())
  273. : _M_ht(__n, __hf, __eql, __a) {}
  274. template<class _InputIterator>
  275. hash_multiset(_InputIterator __f, _InputIterator __l)
  276. : _M_ht(100, hasher(), key_equal(), allocator_type())
  277. { _M_ht.insert_equal(__f, __l); }
  278. template<class _InputIterator>
  279. hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
  280. : _M_ht(__n, hasher(), key_equal(), allocator_type())
  281. { _M_ht.insert_equal(__f, __l); }
  282. template<class _InputIterator>
  283. hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
  284. const hasher& __hf)
  285. : _M_ht(__n, __hf, key_equal(), allocator_type())
  286. { _M_ht.insert_equal(__f, __l); }
  287. template<class _InputIterator>
  288. hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
  289. const hasher& __hf, const key_equal& __eql,
  290. const allocator_type& __a = allocator_type())
  291. : _M_ht(__n, __hf, __eql, __a)
  292. { _M_ht.insert_equal(__f, __l); }
  293. size_type
  294. size() const
  295. { return _M_ht.size(); }
  296. size_type
  297. max_size() const
  298. { return _M_ht.max_size(); }
  299. bool
  300. empty() const
  301. { return _M_ht.empty(); }
  302. void
  303. swap(hash_multiset& hs)
  304. { _M_ht.swap(hs._M_ht); }
  305. template<class _Val, class _HF, class _EqK, class _Al>
  306. friend bool
  307. operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&,
  308. const hash_multiset<_Val, _HF, _EqK, _Al>&);
  309. iterator
  310. begin() const
  311. { return _M_ht.begin(); }
  312. iterator
  313. end() const
  314. { return _M_ht.end(); }
  315. iterator
  316. insert(const value_type& __obj)
  317. { return _M_ht.insert_equal(__obj); }
  318. template<class _InputIterator>
  319. void
  320. insert(_InputIterator __f, _InputIterator __l)
  321. { _M_ht.insert_equal(__f,__l); }
  322. iterator
  323. insert_noresize(const value_type& __obj)
  324. { return _M_ht.insert_equal_noresize(__obj); }
  325. iterator
  326. find(const key_type& __key) const
  327. { return _M_ht.find(__key); }
  328. size_type
  329. count(const key_type& __key) const
  330. { return _M_ht.count(__key); }
  331. pair<iterator, iterator>
  332. equal_range(const key_type& __key) const
  333. { return _M_ht.equal_range(__key); }
  334. size_type
  335. erase(const key_type& __key)
  336. { return _M_ht.erase(__key); }
  337. void
  338. erase(iterator __it)
  339. { _M_ht.erase(__it); }
  340. void
  341. erase(iterator __f, iterator __l)
  342. { _M_ht.erase(__f, __l); }
  343. void
  344. clear()
  345. { _M_ht.clear(); }
  346. void
  347. resize(size_type __hint)
  348. { _M_ht.resize(__hint); }
  349. size_type
  350. bucket_count() const
  351. { return _M_ht.bucket_count(); }
  352. size_type
  353. max_bucket_count() const
  354. { return _M_ht.max_bucket_count(); }
  355. size_type
  356. elems_in_bucket(size_type __n) const
  357. { return _M_ht.elems_in_bucket(__n); }
  358. };
  359. template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
  360. inline bool
  361. operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
  362. const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
  363. { return __hs1._M_ht == __hs2._M_ht; }
  364. template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
  365. inline bool
  366. operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
  367. const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
  368. { return !(__hs1 == __hs2); }
  369. template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
  370. inline void
  371. swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
  372. hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
  373. { __hs1.swap(__hs2); }
  374. _GLIBCXX_END_NAMESPACE_VERSION
  375. } // namespace
  376. namespace std _GLIBCXX_VISIBILITY(default)
  377. {
  378. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  379. // Specialization of insert_iterator so that it will work for hash_set
  380. // and hash_multiset.
  381. template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
  382. class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn,
  383. _EqualKey, _Alloc> >
  384. {
  385. protected:
  386. typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>
  387. _Container;
  388. _Container* container;
  389. public:
  390. typedef _Container container_type;
  391. typedef output_iterator_tag iterator_category;
  392. typedef void value_type;
  393. typedef void difference_type;
  394. typedef void pointer;
  395. typedef void reference;
  396. insert_iterator(_Container& __x)
  397. : container(&__x) {}
  398. insert_iterator(_Container& __x, typename _Container::iterator)
  399. : container(&__x) {}
  400. insert_iterator<_Container>&
  401. operator=(const typename _Container::value_type& __value)
  402. {
  403. container->insert(__value);
  404. return *this;
  405. }
  406. insert_iterator<_Container>&
  407. operator*()
  408. { return *this; }
  409. insert_iterator<_Container>&
  410. operator++()
  411. { return *this; }
  412. insert_iterator<_Container>&
  413. operator++(int)
  414. { return *this; }
  415. };
  416. template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
  417. class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn,
  418. _EqualKey, _Alloc> >
  419. {
  420. protected:
  421. typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>
  422. _Container;
  423. _Container* container;
  424. typename _Container::iterator iter;
  425. public:
  426. typedef _Container container_type;
  427. typedef output_iterator_tag iterator_category;
  428. typedef void value_type;
  429. typedef void difference_type;
  430. typedef void pointer;
  431. typedef void reference;
  432. insert_iterator(_Container& __x)
  433. : container(&__x) {}
  434. insert_iterator(_Container& __x, typename _Container::iterator)
  435. : container(&__x) {}
  436. insert_iterator<_Container>&
  437. operator=(const typename _Container::value_type& __value)
  438. {
  439. container->insert(__value);
  440. return *this;
  441. }
  442. insert_iterator<_Container>&
  443. operator*()
  444. { return *this; }
  445. insert_iterator<_Container>&
  446. operator++()
  447. { return *this; }
  448. insert_iterator<_Container>&
  449. operator++(int) { return *this; }
  450. };
  451. _GLIBCXX_END_NAMESPACE_VERSION
  452. } // namespace
  453. #endif