hash_set 24 KB

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