hash_set 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP_HASH_SET
  10. #define _LIBCPP_HASH_SET
  11. /*
  12. hash_set synopsis
  13. namespace __gnu_cxx
  14. {
  15. template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
  16. class Alloc = allocator<Value>>
  17. class hash_set
  18. {
  19. public:
  20. // types
  21. typedef Value key_type;
  22. typedef key_type value_type;
  23. typedef Hash hasher;
  24. typedef Pred key_equal;
  25. typedef Alloc allocator_type;
  26. typedef value_type& reference;
  27. typedef const value_type& const_reference;
  28. typedef typename allocator_traits<allocator_type>::pointer pointer;
  29. typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
  30. typedef typename allocator_traits<allocator_type>::size_type size_type;
  31. typedef typename allocator_traits<allocator_type>::difference_type difference_type;
  32. typedef /unspecified/ iterator;
  33. typedef /unspecified/ const_iterator;
  34. explicit hash_set(size_type n = 193, const hasher& hf = hasher(),
  35. const key_equal& eql = key_equal(),
  36. const allocator_type& a = allocator_type());
  37. template <class InputIterator>
  38. hash_set(InputIterator f, InputIterator l,
  39. size_type n = 193, const hasher& hf = hasher(),
  40. const key_equal& eql = key_equal(),
  41. const allocator_type& a = allocator_type());
  42. hash_set(const hash_set&);
  43. ~hash_set();
  44. hash_set& operator=(const hash_set&);
  45. allocator_type get_allocator() const;
  46. bool empty() const;
  47. size_type size() const;
  48. size_type max_size() const;
  49. iterator begin();
  50. iterator end();
  51. const_iterator begin() const;
  52. const_iterator end() const;
  53. pair<iterator, bool> insert(const value_type& obj);
  54. template <class InputIterator>
  55. void insert(InputIterator first, InputIterator last);
  56. void erase(const_iterator position);
  57. size_type erase(const key_type& k);
  58. void erase(const_iterator first, const_iterator last);
  59. void clear();
  60. void swap(hash_set&);
  61. hasher hash_funct() const;
  62. key_equal key_eq() const;
  63. iterator find(const key_type& k);
  64. const_iterator find(const key_type& k) const;
  65. size_type count(const key_type& k) const;
  66. pair<iterator, iterator> equal_range(const key_type& k);
  67. pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
  68. size_type bucket_count() const;
  69. size_type max_bucket_count() const;
  70. size_type elems_in_bucket(size_type n) const;
  71. void resize(size_type n);
  72. };
  73. template <class Value, class Hash, class Pred, class Alloc>
  74. void swap(hash_set<Value, Hash, Pred, Alloc>& x,
  75. hash_set<Value, Hash, Pred, Alloc>& y);
  76. template <class Value, class Hash, class Pred, class Alloc>
  77. bool
  78. operator==(const hash_set<Value, Hash, Pred, Alloc>& x,
  79. const hash_set<Value, Hash, Pred, Alloc>& y);
  80. template <class Value, class Hash, class Pred, class Alloc>
  81. bool
  82. operator!=(const hash_set<Value, Hash, Pred, Alloc>& x,
  83. const hash_set<Value, Hash, Pred, Alloc>& y);
  84. template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
  85. class Alloc = allocator<Value>>
  86. class hash_multiset
  87. {
  88. public:
  89. // types
  90. typedef Value key_type;
  91. typedef key_type value_type;
  92. typedef Hash hasher;
  93. typedef Pred key_equal;
  94. typedef Alloc allocator_type;
  95. typedef value_type& reference;
  96. typedef const value_type& const_reference;
  97. typedef typename allocator_traits<allocator_type>::pointer pointer;
  98. typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
  99. typedef typename allocator_traits<allocator_type>::size_type size_type;
  100. typedef typename allocator_traits<allocator_type>::difference_type difference_type;
  101. typedef /unspecified/ iterator;
  102. typedef /unspecified/ const_iterator;
  103. explicit hash_multiset(size_type n = 193, const hasher& hf = hasher(),
  104. const key_equal& eql = key_equal(),
  105. const allocator_type& a = allocator_type());
  106. template <class InputIterator>
  107. hash_multiset(InputIterator f, InputIterator l,
  108. size_type n = 193, const hasher& hf = hasher(),
  109. const key_equal& eql = key_equal(),
  110. const allocator_type& a = allocator_type());
  111. hash_multiset(const hash_multiset&);
  112. ~hash_multiset();
  113. hash_multiset& operator=(const hash_multiset&);
  114. allocator_type get_allocator() const;
  115. bool empty() const;
  116. size_type size() const;
  117. size_type max_size() const;
  118. iterator begin();
  119. iterator end();
  120. const_iterator begin() const;
  121. const_iterator end() const;
  122. iterator insert(const value_type& obj);
  123. template <class InputIterator>
  124. void insert(InputIterator first, InputIterator last);
  125. void erase(const_iterator position);
  126. size_type erase(const key_type& k);
  127. void erase(const_iterator first, const_iterator last);
  128. void clear();
  129. void swap(hash_multiset&);
  130. hasher hash_funct() const;
  131. key_equal key_eq() const;
  132. iterator find(const key_type& k);
  133. const_iterator find(const key_type& k) const;
  134. size_type count(const key_type& k) const;
  135. pair<iterator, iterator> equal_range(const key_type& k);
  136. pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
  137. size_type bucket_count() const;
  138. size_type max_bucket_count() const;
  139. size_type elems_in_bucket(size_type n) const;
  140. void resize(size_type n);
  141. };
  142. template <class Value, class Hash, class Pred, class Alloc>
  143. void swap(hash_multiset<Value, Hash, Pred, Alloc>& x,
  144. hash_multiset<Value, Hash, Pred, Alloc>& y);
  145. template <class Value, class Hash, class Pred, class Alloc>
  146. bool
  147. operator==(const hash_multiset<Value, Hash, Pred, Alloc>& x,
  148. const hash_multiset<Value, Hash, Pred, Alloc>& y);
  149. template <class Value, class Hash, class Pred, class Alloc>
  150. bool
  151. operator!=(const hash_multiset<Value, Hash, Pred, Alloc>& x,
  152. const hash_multiset<Value, Hash, Pred, Alloc>& y);
  153. } // __gnu_cxx
  154. */
  155. #include <__config>
  156. #include <__hash_table>
  157. #include <algorithm>
  158. #include <ext/__hash>
  159. #include <functional>
  160. #if defined(__DEPRECATED) && __DEPRECATED
  161. # if defined(_LIBCPP_WARNING)
  162. _LIBCPP_WARNING("Use of the header <ext/hash_set> is deprecated. Migrate to <unordered_set>")
  163. # else
  164. # warning Use of the header <ext/hash_set> is deprecated. Migrate to <unordered_set>
  165. # endif
  166. #endif
  167. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  168. # pragma GCC system_header
  169. #endif
  170. namespace __gnu_cxx {
  171. template <class _Value,
  172. class _Hash = hash<_Value>,
  173. class _Pred = std::equal_to<_Value>,
  174. class _Alloc = std::allocator<_Value> >
  175. class _LIBCPP_TEMPLATE_VIS hash_set {
  176. public:
  177. // types
  178. typedef _Value key_type;
  179. typedef key_type value_type;
  180. typedef _Hash hasher;
  181. typedef _Pred key_equal;
  182. typedef _Alloc allocator_type;
  183. typedef value_type& reference;
  184. typedef const value_type& const_reference;
  185. private:
  186. typedef std::__hash_table<value_type, hasher, key_equal, allocator_type> __table;
  187. __table __table_;
  188. public:
  189. typedef typename __table::pointer pointer;
  190. typedef typename __table::const_pointer const_pointer;
  191. typedef typename __table::size_type size_type;
  192. typedef typename __table::difference_type difference_type;
  193. typedef typename __table::const_iterator iterator;
  194. typedef typename __table::const_iterator const_iterator;
  195. _LIBCPP_HIDE_FROM_ABI hash_set() {}
  196. _LIBCPP_HIDE_FROM_ABI explicit hash_set(
  197. size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
  198. _LIBCPP_HIDE_FROM_ABI hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a);
  199. template <class _InputIterator>
  200. _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last);
  201. template <class _InputIterator>
  202. _LIBCPP_HIDE_FROM_ABI
  203. hash_set(_InputIterator __first,
  204. _InputIterator __last,
  205. size_type __n,
  206. const hasher& __hf = hasher(),
  207. const key_equal& __eql = key_equal());
  208. template <class _InputIterator>
  209. _LIBCPP_HIDE_FROM_ABI
  210. hash_set(_InputIterator __first,
  211. _InputIterator __last,
  212. size_type __n,
  213. const hasher& __hf,
  214. const key_equal& __eql,
  215. const allocator_type& __a);
  216. _LIBCPP_HIDE_FROM_ABI hash_set(const hash_set& __u);
  217. _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return allocator_type(__table_.__node_alloc()); }
  218. _LIBCPP_HIDE_FROM_ABI bool empty() const { return __table_.size() == 0; }
  219. _LIBCPP_HIDE_FROM_ABI size_type size() const { return __table_.size(); }
  220. _LIBCPP_HIDE_FROM_ABI size_type max_size() const { return __table_.max_size(); }
  221. _LIBCPP_HIDE_FROM_ABI iterator begin() { return __table_.begin(); }
  222. _LIBCPP_HIDE_FROM_ABI iterator end() { return __table_.end(); }
  223. _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { return __table_.begin(); }
  224. _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __table_.end(); }
  225. _LIBCPP_HIDE_FROM_ABI std::pair<iterator, bool> insert(const value_type& __x) {
  226. return __table_.__insert_unique(__x);
  227. }
  228. _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) { return insert(__x).first; }
  229. template <class _InputIterator>
  230. _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last);
  231. _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __p) { __table_.erase(__p); }
  232. _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __table_.__erase_unique(__k); }
  233. _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __first, const_iterator __last) { __table_.erase(__first, __last); }
  234. _LIBCPP_HIDE_FROM_ABI void clear() { __table_.clear(); }
  235. _LIBCPP_HIDE_FROM_ABI void swap(hash_set& __u) { __table_.swap(__u.__table_); }
  236. _LIBCPP_HIDE_FROM_ABI hasher hash_funct() const { return __table_.hash_function(); }
  237. _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq(); }
  238. _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
  239. _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
  240. _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_unique(__k); }
  241. _LIBCPP_HIDE_FROM_ABI std::pair<iterator, iterator> equal_range(const key_type& __k) {
  242. return __table_.__equal_range_unique(__k);
  243. }
  244. _LIBCPP_HIDE_FROM_ABI std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
  245. return __table_.__equal_range_unique(__k);
  246. }
  247. _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const { return __table_.bucket_count(); }
  248. _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const { return __table_.max_bucket_count(); }
  249. _LIBCPP_HIDE_FROM_ABI size_type elems_in_bucket(size_type __n) const { return __table_.bucket_size(__n); }
  250. _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { __table_.__rehash_unique(__n); }
  251. };
  252. template <class _Value, class _Hash, class _Pred, class _Alloc>
  253. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n, const hasher& __hf, const key_equal& __eql)
  254. : __table_(__hf, __eql) {
  255. __table_.__rehash_unique(__n);
  256. }
  257. template <class _Value, class _Hash, class _Pred, class _Alloc>
  258. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
  259. size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
  260. : __table_(__hf, __eql, __a) {
  261. __table_.__rehash_unique(__n);
  262. }
  263. template <class _Value, class _Hash, class _Pred, class _Alloc>
  264. template <class _InputIterator>
  265. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(_InputIterator __first, _InputIterator __last) {
  266. insert(__first, __last);
  267. }
  268. template <class _Value, class _Hash, class _Pred, class _Alloc>
  269. template <class _InputIterator>
  270. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
  271. _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql)
  272. : __table_(__hf, __eql) {
  273. __table_.__rehash_unique(__n);
  274. insert(__first, __last);
  275. }
  276. template <class _Value, class _Hash, class _Pred, class _Alloc>
  277. template <class _InputIterator>
  278. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
  279. _InputIterator __first,
  280. _InputIterator __last,
  281. size_type __n,
  282. const hasher& __hf,
  283. const key_equal& __eql,
  284. const allocator_type& __a)
  285. : __table_(__hf, __eql, __a) {
  286. __table_.__rehash_unique(__n);
  287. insert(__first, __last);
  288. }
  289. template <class _Value, class _Hash, class _Pred, class _Alloc>
  290. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(const hash_set& __u) : __table_(__u.__table_) {
  291. __table_.__rehash_unique(__u.bucket_count());
  292. insert(__u.begin(), __u.end());
  293. }
  294. template <class _Value, class _Hash, class _Pred, class _Alloc>
  295. template <class _InputIterator>
  296. inline void hash_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) {
  297. for (; __first != __last; ++__first)
  298. __table_.__insert_unique(*__first);
  299. }
  300. template <class _Value, class _Hash, class _Pred, class _Alloc>
  301. inline _LIBCPP_HIDE_FROM_ABI void
  302. swap(hash_set<_Value, _Hash, _Pred, _Alloc>& __x, hash_set<_Value, _Hash, _Pred, _Alloc>& __y) {
  303. __x.swap(__y);
  304. }
  305. template <class _Value, class _Hash, class _Pred, class _Alloc>
  306. _LIBCPP_HIDE_FROM_ABI bool
  307. operator==(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x, const hash_set<_Value, _Hash, _Pred, _Alloc>& __y) {
  308. if (__x.size() != __y.size())
  309. return false;
  310. typedef typename hash_set<_Value, _Hash, _Pred, _Alloc>::const_iterator const_iterator;
  311. for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); __i != __ex; ++__i) {
  312. const_iterator __j = __y.find(*__i);
  313. if (__j == __ey || !(*__i == *__j))
  314. return false;
  315. }
  316. return true;
  317. }
  318. template <class _Value, class _Hash, class _Pred, class _Alloc>
  319. inline _LIBCPP_HIDE_FROM_ABI bool
  320. operator!=(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x, const hash_set<_Value, _Hash, _Pred, _Alloc>& __y) {
  321. return !(__x == __y);
  322. }
  323. template <class _Value,
  324. class _Hash = hash<_Value>,
  325. class _Pred = std::equal_to<_Value>,
  326. class _Alloc = std::allocator<_Value> >
  327. class _LIBCPP_TEMPLATE_VIS hash_multiset {
  328. public:
  329. // types
  330. typedef _Value key_type;
  331. typedef key_type value_type;
  332. typedef _Hash hasher;
  333. typedef _Pred key_equal;
  334. typedef _Alloc allocator_type;
  335. typedef value_type& reference;
  336. typedef const value_type& const_reference;
  337. private:
  338. typedef std::__hash_table<value_type, hasher, key_equal, allocator_type> __table;
  339. __table __table_;
  340. public:
  341. typedef typename __table::pointer pointer;
  342. typedef typename __table::const_pointer const_pointer;
  343. typedef typename __table::size_type size_type;
  344. typedef typename __table::difference_type difference_type;
  345. typedef typename __table::const_iterator iterator;
  346. typedef typename __table::const_iterator const_iterator;
  347. _LIBCPP_HIDE_FROM_ABI hash_multiset() {}
  348. explicit _LIBCPP_HIDE_FROM_ABI
  349. hash_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
  350. _LIBCPP_HIDE_FROM_ABI
  351. hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a);
  352. template <class _InputIterator>
  353. _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last);
  354. template <class _InputIterator>
  355. _LIBCPP_HIDE_FROM_ABI
  356. hash_multiset(_InputIterator __first,
  357. _InputIterator __last,
  358. size_type __n,
  359. const hasher& __hf = hasher(),
  360. const key_equal& __eql = key_equal());
  361. template <class _InputIterator>
  362. _LIBCPP_HIDE_FROM_ABI hash_multiset(
  363. _InputIterator __first,
  364. _InputIterator __last,
  365. size_type __n,
  366. const hasher& __hf,
  367. const key_equal& __eql,
  368. const allocator_type& __a);
  369. _LIBCPP_HIDE_FROM_ABI hash_multiset(const hash_multiset& __u);
  370. _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return allocator_type(__table_.__node_alloc()); }
  371. _LIBCPP_HIDE_FROM_ABI bool empty() const { return __table_.size() == 0; }
  372. _LIBCPP_HIDE_FROM_ABI size_type size() const { return __table_.size(); }
  373. _LIBCPP_HIDE_FROM_ABI size_type max_size() const { return __table_.max_size(); }
  374. _LIBCPP_HIDE_FROM_ABI iterator begin() { return __table_.begin(); }
  375. _LIBCPP_HIDE_FROM_ABI iterator end() { return __table_.end(); }
  376. _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { return __table_.begin(); }
  377. _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __table_.end(); }
  378. _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return __table_.__insert_multi(__x); }
  379. _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) { return insert(__x); }
  380. template <class _InputIterator>
  381. _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last);
  382. _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __p) { __table_.erase(__p); }
  383. _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __table_.__erase_multi(__k); }
  384. _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __first, const_iterator __last) { __table_.erase(__first, __last); }
  385. _LIBCPP_HIDE_FROM_ABI void clear() { __table_.clear(); }
  386. _LIBCPP_HIDE_FROM_ABI void swap(hash_multiset& __u) { __table_.swap(__u.__table_); }
  387. _LIBCPP_HIDE_FROM_ABI hasher hash_funct() const { return __table_.hash_function(); }
  388. _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq(); }
  389. _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
  390. _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
  391. _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_multi(__k); }
  392. _LIBCPP_HIDE_FROM_ABI std::pair<iterator, iterator> equal_range(const key_type& __k) {
  393. return __table_.__equal_range_multi(__k);
  394. }
  395. _LIBCPP_HIDE_FROM_ABI std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
  396. return __table_.__equal_range_multi(__k);
  397. }
  398. _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const { return __table_.bucket_count(); }
  399. _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const { return __table_.max_bucket_count(); }
  400. _LIBCPP_HIDE_FROM_ABI size_type elems_in_bucket(size_type __n) const { return __table_.bucket_size(__n); }
  401. _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { __table_.__rehash_multi(__n); }
  402. };
  403. template <class _Value, class _Hash, class _Pred, class _Alloc>
  404. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql)
  405. : __table_(__hf, __eql) {
  406. __table_.__rehash_multi(__n);
  407. }
  408. template <class _Value, class _Hash, class _Pred, class _Alloc>
  409. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
  410. size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
  411. : __table_(__hf, __eql, __a) {
  412. __table_.__rehash_multi(__n);
  413. }
  414. template <class _Value, class _Hash, class _Pred, class _Alloc>
  415. template <class _InputIterator>
  416. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(_InputIterator __first, _InputIterator __last) {
  417. insert(__first, __last);
  418. }
  419. template <class _Value, class _Hash, class _Pred, class _Alloc>
  420. template <class _InputIterator>
  421. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
  422. _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql)
  423. : __table_(__hf, __eql) {
  424. __table_.__rehash_multi(__n);
  425. insert(__first, __last);
  426. }
  427. template <class _Value, class _Hash, class _Pred, class _Alloc>
  428. template <class _InputIterator>
  429. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
  430. _InputIterator __first,
  431. _InputIterator __last,
  432. size_type __n,
  433. const hasher& __hf,
  434. const key_equal& __eql,
  435. const allocator_type& __a)
  436. : __table_(__hf, __eql, __a) {
  437. __table_.__rehash_multi(__n);
  438. insert(__first, __last);
  439. }
  440. template <class _Value, class _Hash, class _Pred, class _Alloc>
  441. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(const hash_multiset& __u) : __table_(__u.__table_) {
  442. __table_.__rehash_multi(__u.bucket_count());
  443. insert(__u.begin(), __u.end());
  444. }
  445. template <class _Value, class _Hash, class _Pred, class _Alloc>
  446. template <class _InputIterator>
  447. inline void hash_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) {
  448. for (; __first != __last; ++__first)
  449. __table_.__insert_multi(*__first);
  450. }
  451. template <class _Value, class _Hash, class _Pred, class _Alloc>
  452. inline _LIBCPP_HIDE_FROM_ABI void
  453. swap(hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x, hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) {
  454. __x.swap(__y);
  455. }
  456. template <class _Value, class _Hash, class _Pred, class _Alloc>
  457. _LIBCPP_HIDE_FROM_ABI bool operator==(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
  458. const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) {
  459. if (__x.size() != __y.size())
  460. return false;
  461. typedef typename hash_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator const_iterator;
  462. typedef std::pair<const_iterator, const_iterator> _EqRng;
  463. for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) {
  464. _EqRng __xeq = __x.equal_range(*__i);
  465. _EqRng __yeq = __y.equal_range(*__i);
  466. if (std::distance(__xeq.first, __xeq.second) != std::distance(__yeq.first, __yeq.second) ||
  467. !std::is_permutation(__xeq.first, __xeq.second, __yeq.first))
  468. return false;
  469. __i = __xeq.second;
  470. }
  471. return true;
  472. }
  473. template <class _Value, class _Hash, class _Pred, class _Alloc>
  474. inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
  475. const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) {
  476. return !(__x == __y);
  477. }
  478. } // namespace __gnu_cxx
  479. #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
  480. # include <concepts>
  481. # include <iterator>
  482. # include <type_traits>
  483. #endif
  484. #endif // _LIBCPP_HASH_SET