hash_set 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  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 <__assert> // all public C++ headers provide the assertion handler
  156. #include <__config>
  157. #include <__hash_table>
  158. #include <algorithm>
  159. #include <ext/__hash>
  160. #include <functional>
  161. #if defined(__DEPRECATED) && __DEPRECATED
  162. #if defined(_LIBCPP_WARNING)
  163. _LIBCPP_WARNING("Use of the header <ext/hash_set> is deprecated. Migrate to <unordered_set>")
  164. #else
  165. # warning Use of the header <ext/hash_set> is deprecated. Migrate to <unordered_set>
  166. #endif
  167. #endif
  168. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  169. # pragma GCC system_header
  170. #endif
  171. namespace __gnu_cxx {
  172. template <class _Value, class _Hash = hash<_Value>, class _Pred = std::equal_to<_Value>,
  173. class _Alloc = std::allocator<_Value> >
  174. class _LIBCPP_TEMPLATE_VIS hash_set
  175. {
  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_INLINE_VISIBILITY
  196. hash_set() { }
  197. _LIBCPP_HIDE_FROM_ABI explicit hash_set(size_type __n, const hasher& __hf = hasher(),
  198. const key_equal& __eql = key_equal());
  199. _LIBCPP_HIDE_FROM_ABI hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
  200. const allocator_type& __a);
  201. template <class _InputIterator>
  202. _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last);
  203. template <class _InputIterator>
  204. _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last,
  205. size_type __n, const hasher& __hf = hasher(),
  206. const key_equal& __eql = key_equal());
  207. template <class _InputIterator>
  208. _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last,
  209. size_type __n, const hasher& __hf, const key_equal& __eql,
  210. const allocator_type& __a);
  211. _LIBCPP_HIDE_FROM_ABI hash_set(const hash_set& __u);
  212. _LIBCPP_INLINE_VISIBILITY
  213. allocator_type get_allocator() const
  214. {return allocator_type(__table_.__node_alloc());}
  215. _LIBCPP_INLINE_VISIBILITY
  216. bool empty() const {return __table_.size() == 0;}
  217. _LIBCPP_INLINE_VISIBILITY
  218. size_type size() const {return __table_.size();}
  219. _LIBCPP_INLINE_VISIBILITY
  220. size_type max_size() const {return __table_.max_size();}
  221. _LIBCPP_INLINE_VISIBILITY
  222. iterator begin() {return __table_.begin();}
  223. _LIBCPP_INLINE_VISIBILITY
  224. iterator end() {return __table_.end();}
  225. _LIBCPP_INLINE_VISIBILITY
  226. const_iterator begin() const {return __table_.begin();}
  227. _LIBCPP_INLINE_VISIBILITY
  228. const_iterator end() const {return __table_.end();}
  229. _LIBCPP_INLINE_VISIBILITY
  230. std::pair<iterator, bool> insert(const value_type& __x)
  231. {return __table_.__insert_unique(__x);}
  232. _LIBCPP_INLINE_VISIBILITY
  233. iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}
  234. template <class _InputIterator>
  235. _LIBCPP_INLINE_VISIBILITY
  236. void insert(_InputIterator __first, _InputIterator __last);
  237. _LIBCPP_INLINE_VISIBILITY
  238. void erase(const_iterator __p) {__table_.erase(__p);}
  239. _LIBCPP_INLINE_VISIBILITY
  240. size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
  241. _LIBCPP_INLINE_VISIBILITY
  242. void erase(const_iterator __first, const_iterator __last)
  243. {__table_.erase(__first, __last);}
  244. _LIBCPP_INLINE_VISIBILITY
  245. void clear() {__table_.clear();}
  246. _LIBCPP_INLINE_VISIBILITY
  247. void swap(hash_set& __u) {__table_.swap(__u.__table_);}
  248. _LIBCPP_INLINE_VISIBILITY
  249. hasher hash_funct() const {return __table_.hash_function();}
  250. _LIBCPP_INLINE_VISIBILITY
  251. key_equal key_eq() const {return __table_.key_eq();}
  252. _LIBCPP_INLINE_VISIBILITY
  253. iterator find(const key_type& __k) {return __table_.find(__k);}
  254. _LIBCPP_INLINE_VISIBILITY
  255. const_iterator find(const key_type& __k) const {return __table_.find(__k);}
  256. _LIBCPP_INLINE_VISIBILITY
  257. size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
  258. _LIBCPP_INLINE_VISIBILITY
  259. std::pair<iterator, iterator> equal_range(const key_type& __k)
  260. {return __table_.__equal_range_unique(__k);}
  261. _LIBCPP_INLINE_VISIBILITY
  262. std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
  263. {return __table_.__equal_range_unique(__k);}
  264. _LIBCPP_INLINE_VISIBILITY
  265. size_type bucket_count() const {return __table_.bucket_count();}
  266. _LIBCPP_INLINE_VISIBILITY
  267. size_type max_bucket_count() const {return __table_.max_bucket_count();}
  268. _LIBCPP_INLINE_VISIBILITY
  269. size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);}
  270. _LIBCPP_INLINE_VISIBILITY
  271. void resize(size_type __n) {__table_.__rehash_unique(__n);}
  272. };
  273. template <class _Value, class _Hash, class _Pred, class _Alloc>
  274. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n,
  275. const hasher& __hf, const key_equal& __eql)
  276. : __table_(__hf, __eql)
  277. {
  278. __table_.__rehash_unique(__n);
  279. }
  280. template <class _Value, class _Hash, class _Pred, class _Alloc>
  281. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n,
  282. const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
  283. : __table_(__hf, __eql, __a)
  284. {
  285. __table_.__rehash_unique(__n);
  286. }
  287. template <class _Value, class _Hash, class _Pred, class _Alloc>
  288. template <class _InputIterator>
  289. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
  290. _InputIterator __first, _InputIterator __last)
  291. {
  292. insert(__first, __last);
  293. }
  294. template <class _Value, class _Hash, class _Pred, class _Alloc>
  295. template <class _InputIterator>
  296. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
  297. _InputIterator __first, _InputIterator __last, size_type __n,
  298. const hasher& __hf, const key_equal& __eql)
  299. : __table_(__hf, __eql)
  300. {
  301. __table_.__rehash_unique(__n);
  302. insert(__first, __last);
  303. }
  304. template <class _Value, class _Hash, class _Pred, class _Alloc>
  305. template <class _InputIterator>
  306. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
  307. _InputIterator __first, _InputIterator __last, size_type __n,
  308. const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
  309. : __table_(__hf, __eql, __a)
  310. {
  311. __table_.__rehash_unique(__n);
  312. insert(__first, __last);
  313. }
  314. template <class _Value, class _Hash, class _Pred, class _Alloc>
  315. hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
  316. const hash_set& __u)
  317. : __table_(__u.__table_)
  318. {
  319. __table_.__rehash_unique(__u.bucket_count());
  320. insert(__u.begin(), __u.end());
  321. }
  322. template <class _Value, class _Hash, class _Pred, class _Alloc>
  323. template <class _InputIterator>
  324. inline
  325. void
  326. hash_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
  327. _InputIterator __last)
  328. {
  329. for (; __first != __last; ++__first)
  330. __table_.__insert_unique(*__first);
  331. }
  332. template <class _Value, class _Hash, class _Pred, class _Alloc>
  333. inline _LIBCPP_INLINE_VISIBILITY
  334. void
  335. swap(hash_set<_Value, _Hash, _Pred, _Alloc>& __x,
  336. hash_set<_Value, _Hash, _Pred, _Alloc>& __y)
  337. {
  338. __x.swap(__y);
  339. }
  340. template <class _Value, class _Hash, class _Pred, class _Alloc>
  341. _LIBCPP_HIDE_FROM_ABI bool
  342. operator==(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x,
  343. const hash_set<_Value, _Hash, _Pred, _Alloc>& __y)
  344. {
  345. if (__x.size() != __y.size())
  346. return false;
  347. typedef typename hash_set<_Value, _Hash, _Pred, _Alloc>::const_iterator
  348. const_iterator;
  349. for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
  350. __i != __ex; ++__i)
  351. {
  352. const_iterator __j = __y.find(*__i);
  353. if (__j == __ey || !(*__i == *__j))
  354. return false;
  355. }
  356. return true;
  357. }
  358. template <class _Value, class _Hash, class _Pred, class _Alloc>
  359. inline _LIBCPP_INLINE_VISIBILITY
  360. bool
  361. operator!=(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x,
  362. const hash_set<_Value, _Hash, _Pred, _Alloc>& __y)
  363. {
  364. return !(__x == __y);
  365. }
  366. template <class _Value, class _Hash = hash<_Value>, class _Pred = std::equal_to<_Value>,
  367. class _Alloc = std::allocator<_Value> >
  368. class _LIBCPP_TEMPLATE_VIS hash_multiset
  369. {
  370. public:
  371. // types
  372. typedef _Value key_type;
  373. typedef key_type value_type;
  374. typedef _Hash hasher;
  375. typedef _Pred key_equal;
  376. typedef _Alloc allocator_type;
  377. typedef value_type& reference;
  378. typedef const value_type& const_reference;
  379. private:
  380. typedef std::__hash_table<value_type, hasher, key_equal, allocator_type> __table;
  381. __table __table_;
  382. public:
  383. typedef typename __table::pointer pointer;
  384. typedef typename __table::const_pointer const_pointer;
  385. typedef typename __table::size_type size_type;
  386. typedef typename __table::difference_type difference_type;
  387. typedef typename __table::const_iterator iterator;
  388. typedef typename __table::const_iterator const_iterator;
  389. _LIBCPP_INLINE_VISIBILITY
  390. hash_multiset() { }
  391. explicit _LIBCPP_HIDE_FROM_ABI hash_multiset(size_type __n, const hasher& __hf = hasher(),
  392. const key_equal& __eql = key_equal());
  393. _LIBCPP_HIDE_FROM_ABI hash_multiset(size_type __n, const hasher& __hf,
  394. const key_equal& __eql, const allocator_type& __a);
  395. template <class _InputIterator>
  396. _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last);
  397. template <class _InputIterator>
  398. _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last,
  399. size_type __n, const hasher& __hf = hasher(),
  400. const key_equal& __eql = key_equal());
  401. template <class _InputIterator>
  402. _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last,
  403. size_type __n , const hasher& __hf,
  404. const key_equal& __eql, const allocator_type& __a);
  405. _LIBCPP_HIDE_FROM_ABI hash_multiset(const hash_multiset& __u);
  406. _LIBCPP_INLINE_VISIBILITY
  407. allocator_type get_allocator() const
  408. {return allocator_type(__table_.__node_alloc());}
  409. _LIBCPP_INLINE_VISIBILITY
  410. bool empty() const {return __table_.size() == 0;}
  411. _LIBCPP_INLINE_VISIBILITY
  412. size_type size() const {return __table_.size();}
  413. _LIBCPP_INLINE_VISIBILITY
  414. size_type max_size() const {return __table_.max_size();}
  415. _LIBCPP_INLINE_VISIBILITY
  416. iterator begin() {return __table_.begin();}
  417. _LIBCPP_INLINE_VISIBILITY
  418. iterator end() {return __table_.end();}
  419. _LIBCPP_INLINE_VISIBILITY
  420. const_iterator begin() const {return __table_.begin();}
  421. _LIBCPP_INLINE_VISIBILITY
  422. const_iterator end() const {return __table_.end();}
  423. _LIBCPP_INLINE_VISIBILITY
  424. iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
  425. _LIBCPP_INLINE_VISIBILITY
  426. iterator insert(const_iterator, const value_type& __x) {return insert(__x);}
  427. template <class _InputIterator>
  428. _LIBCPP_INLINE_VISIBILITY
  429. void insert(_InputIterator __first, _InputIterator __last);
  430. _LIBCPP_INLINE_VISIBILITY
  431. void erase(const_iterator __p) {__table_.erase(__p);}
  432. _LIBCPP_INLINE_VISIBILITY
  433. size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
  434. _LIBCPP_INLINE_VISIBILITY
  435. void erase(const_iterator __first, const_iterator __last)
  436. {__table_.erase(__first, __last);}
  437. _LIBCPP_INLINE_VISIBILITY
  438. void clear() {__table_.clear();}
  439. _LIBCPP_INLINE_VISIBILITY
  440. void swap(hash_multiset& __u) {__table_.swap(__u.__table_);}
  441. _LIBCPP_INLINE_VISIBILITY
  442. hasher hash_funct() const {return __table_.hash_function();}
  443. _LIBCPP_INLINE_VISIBILITY
  444. key_equal key_eq() const {return __table_.key_eq();}
  445. _LIBCPP_INLINE_VISIBILITY
  446. iterator find(const key_type& __k) {return __table_.find(__k);}
  447. _LIBCPP_INLINE_VISIBILITY
  448. const_iterator find(const key_type& __k) const {return __table_.find(__k);}
  449. _LIBCPP_INLINE_VISIBILITY
  450. size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
  451. _LIBCPP_INLINE_VISIBILITY
  452. std::pair<iterator, iterator> equal_range(const key_type& __k)
  453. {return __table_.__equal_range_multi(__k);}
  454. _LIBCPP_INLINE_VISIBILITY
  455. std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
  456. {return __table_.__equal_range_multi(__k);}
  457. _LIBCPP_INLINE_VISIBILITY
  458. size_type bucket_count() const {return __table_.bucket_count();}
  459. _LIBCPP_INLINE_VISIBILITY
  460. size_type max_bucket_count() const {return __table_.max_bucket_count();}
  461. _LIBCPP_INLINE_VISIBILITY
  462. size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);}
  463. _LIBCPP_INLINE_VISIBILITY
  464. void resize(size_type __n) {__table_.__rehash_multi(__n);}
  465. };
  466. template <class _Value, class _Hash, class _Pred, class _Alloc>
  467. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
  468. size_type __n, const hasher& __hf, const key_equal& __eql)
  469. : __table_(__hf, __eql)
  470. {
  471. __table_.__rehash_multi(__n);
  472. }
  473. template <class _Value, class _Hash, class _Pred, class _Alloc>
  474. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
  475. size_type __n, const hasher& __hf, const key_equal& __eql,
  476. const allocator_type& __a)
  477. : __table_(__hf, __eql, __a)
  478. {
  479. __table_.__rehash_multi(__n);
  480. }
  481. template <class _Value, class _Hash, class _Pred, class _Alloc>
  482. template <class _InputIterator>
  483. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
  484. _InputIterator __first, _InputIterator __last)
  485. {
  486. insert(__first, __last);
  487. }
  488. template <class _Value, class _Hash, class _Pred, class _Alloc>
  489. template <class _InputIterator>
  490. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
  491. _InputIterator __first, _InputIterator __last, size_type __n,
  492. const hasher& __hf, const key_equal& __eql)
  493. : __table_(__hf, __eql)
  494. {
  495. __table_.__rehash_multi(__n);
  496. insert(__first, __last);
  497. }
  498. template <class _Value, class _Hash, class _Pred, class _Alloc>
  499. template <class _InputIterator>
  500. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
  501. _InputIterator __first, _InputIterator __last, size_type __n,
  502. const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
  503. : __table_(__hf, __eql, __a)
  504. {
  505. __table_.__rehash_multi(__n);
  506. insert(__first, __last);
  507. }
  508. template <class _Value, class _Hash, class _Pred, class _Alloc>
  509. hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
  510. const hash_multiset& __u)
  511. : __table_(__u.__table_)
  512. {
  513. __table_.__rehash_multi(__u.bucket_count());
  514. insert(__u.begin(), __u.end());
  515. }
  516. template <class _Value, class _Hash, class _Pred, class _Alloc>
  517. template <class _InputIterator>
  518. inline
  519. void
  520. hash_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
  521. _InputIterator __last)
  522. {
  523. for (; __first != __last; ++__first)
  524. __table_.__insert_multi(*__first);
  525. }
  526. template <class _Value, class _Hash, class _Pred, class _Alloc>
  527. inline _LIBCPP_INLINE_VISIBILITY
  528. void
  529. swap(hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
  530. hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
  531. {
  532. __x.swap(__y);
  533. }
  534. template <class _Value, class _Hash, class _Pred, class _Alloc>
  535. _LIBCPP_HIDE_FROM_ABI bool
  536. operator==(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
  537. const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
  538. {
  539. if (__x.size() != __y.size())
  540. return false;
  541. typedef typename hash_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator
  542. const_iterator;
  543. typedef std::pair<const_iterator, const_iterator> _EqRng;
  544. for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
  545. {
  546. _EqRng __xeq = __x.equal_range(*__i);
  547. _EqRng __yeq = __y.equal_range(*__i);
  548. if (_VSTD::distance(__xeq.first, __xeq.second) !=
  549. _VSTD::distance(__yeq.first, __yeq.second) ||
  550. !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
  551. return false;
  552. __i = __xeq.second;
  553. }
  554. return true;
  555. }
  556. template <class _Value, class _Hash, class _Pred, class _Alloc>
  557. inline _LIBCPP_INLINE_VISIBILITY
  558. bool
  559. operator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
  560. const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
  561. {
  562. return !(__x == __y);
  563. }
  564. } // namespace __gnu_cxx
  565. #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
  566. # include <concepts>
  567. # include <iterator>
  568. # include <type_traits>
  569. #endif
  570. #endif // _LIBCPP_HASH_SET