You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

570 lines
17KB

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