hash_set 24 KB

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