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 10 #ifndef _LIBCPP_HASH_SET 11 #define _LIBCPP_HASH_SET 12 13 /* 14 15 hash_set synopsis 16 17 namespace __gnu_cxx 18 { 19 20 template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, 21 class Alloc = allocator<Value>> 22 class hash_set 23 { 24 public: 25 // types 26 typedef Value key_type; 27 typedef key_type value_type; 28 typedef Hash hasher; 29 typedef Pred key_equal; 30 typedef Alloc allocator_type; 31 typedef value_type& reference; 32 typedef const value_type& const_reference; 33 typedef typename allocator_traits<allocator_type>::pointer pointer; 34 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; 35 typedef typename allocator_traits<allocator_type>::size_type size_type; 36 typedef typename allocator_traits<allocator_type>::difference_type difference_type; 37 38 typedef /unspecified/ iterator; 39 typedef /unspecified/ const_iterator; 40 41 explicit hash_set(size_type n = 193, const hasher& hf = hasher(), 42 const key_equal& eql = key_equal(), 43 const allocator_type& a = allocator_type()); 44 template <class InputIterator> 45 hash_set(InputIterator f, InputIterator l, 46 size_type n = 193, const hasher& hf = hasher(), 47 const key_equal& eql = key_equal(), 48 const allocator_type& a = allocator_type()); 49 hash_set(const hash_set&); 50 ~hash_set(); 51 hash_set& operator=(const hash_set&); 52 53 allocator_type get_allocator() const; 54 55 bool empty() const; 56 size_type size() const; 57 size_type max_size() const; 58 59 iterator begin(); 60 iterator end(); 61 const_iterator begin() const; 62 const_iterator end() const; 63 64 pair<iterator, bool> insert(const value_type& obj); 65 template <class InputIterator> 66 void insert(InputIterator first, InputIterator last); 67 68 void erase(const_iterator position); 69 size_type erase(const key_type& k); 70 void erase(const_iterator first, const_iterator last); 71 void clear(); 72 73 void swap(hash_set&); 74 75 hasher hash_funct() const; 76 key_equal key_eq() const; 77 78 iterator find(const key_type& k); 79 const_iterator find(const key_type& k) const; 80 size_type count(const key_type& k) const; 81 pair<iterator, iterator> equal_range(const key_type& k); 82 pair<const_iterator, const_iterator> equal_range(const key_type& k) const; 83 84 size_type bucket_count() const; 85 size_type max_bucket_count() const; 86 87 size_type elems_in_bucket(size_type n) const; 88 89 void resize(size_type n); 90 }; 91 92 template <class Value, class Hash, class Pred, class Alloc> 93 void swap(hash_set<Value, Hash, Pred, Alloc>& x, 94 hash_set<Value, Hash, Pred, Alloc>& y); 95 96 template <class Value, class Hash, class Pred, class Alloc> 97 bool 98 operator==(const hash_set<Value, Hash, Pred, Alloc>& x, 99 const hash_set<Value, Hash, Pred, Alloc>& y); 100 101 template <class Value, class Hash, class Pred, class Alloc> 102 bool 103 operator!=(const hash_set<Value, Hash, Pred, Alloc>& x, 104 const hash_set<Value, Hash, Pred, Alloc>& y); 105 106 template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, 107 class Alloc = allocator<Value>> 108 class hash_multiset 109 { 110 public: 111 // types 112 typedef Value key_type; 113 typedef key_type value_type; 114 typedef Hash hasher; 115 typedef Pred key_equal; 116 typedef Alloc allocator_type; 117 typedef value_type& reference; 118 typedef const value_type& const_reference; 119 typedef typename allocator_traits<allocator_type>::pointer pointer; 120 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; 121 typedef typename allocator_traits<allocator_type>::size_type size_type; 122 typedef typename allocator_traits<allocator_type>::difference_type difference_type; 123 124 typedef /unspecified/ iterator; 125 typedef /unspecified/ const_iterator; 126 127 explicit hash_multiset(size_type n = 193, const hasher& hf = hasher(), 128 const key_equal& eql = key_equal(), 129 const allocator_type& a = allocator_type()); 130 template <class InputIterator> 131 hash_multiset(InputIterator f, InputIterator l, 132 size_type n = 193, const hasher& hf = hasher(), 133 const key_equal& eql = key_equal(), 134 const allocator_type& a = allocator_type()); 135 hash_multiset(const hash_multiset&); 136 ~hash_multiset(); 137 hash_multiset& operator=(const hash_multiset&); 138 139 allocator_type get_allocator() const; 140 141 bool empty() const; 142 size_type size() const; 143 size_type max_size() const; 144 145 iterator begin(); 146 iterator end(); 147 const_iterator begin() const; 148 const_iterator end() const; 149 150 iterator insert(const value_type& obj); 151 template <class InputIterator> 152 void insert(InputIterator first, InputIterator last); 153 154 void erase(const_iterator position); 155 size_type erase(const key_type& k); 156 void erase(const_iterator first, const_iterator last); 157 void clear(); 158 159 void swap(hash_multiset&); 160 161 hasher hash_funct() const; 162 key_equal key_eq() const; 163 164 iterator find(const key_type& k); 165 const_iterator find(const key_type& k) const; 166 size_type count(const key_type& k) const; 167 pair<iterator, iterator> equal_range(const key_type& k); 168 pair<const_iterator, const_iterator> equal_range(const key_type& k) const; 169 170 size_type bucket_count() const; 171 size_type max_bucket_count() const; 172 173 size_type elems_in_bucket(size_type n) const; 174 175 void resize(size_type n); 176 }; 177 178 template <class Value, class Hash, class Pred, class Alloc> 179 void swap(hash_multiset<Value, Hash, Pred, Alloc>& x, 180 hash_multiset<Value, Hash, Pred, Alloc>& y); 181 182 template <class Value, class Hash, class Pred, class Alloc> 183 bool 184 operator==(const hash_multiset<Value, Hash, Pred, Alloc>& x, 185 const hash_multiset<Value, Hash, Pred, Alloc>& y); 186 187 template <class Value, class Hash, class Pred, class Alloc> 188 bool 189 operator!=(const hash_multiset<Value, Hash, Pred, Alloc>& x, 190 const hash_multiset<Value, Hash, Pred, Alloc>& y); 191 } // __gnu_cxx 192 193 */ 194 195 #include <__config> 196 #include <__hash_table> 197 #include <functional> 198 #include <ext/__hash> 199 200 #if defined(__DEPRECATED) && __DEPRECATED 201 #if defined(_LIBCPP_WARNING) 202 _LIBCPP_WARNING("Use of the header <ext/hash_set> is deprecated. Migrate to <unordered_set>") 203 #else 204 # warning Use of the header <ext/hash_set> is deprecated. Migrate to <unordered_set> 205 #endif 206 #endif 207 208 namespace __gnu_cxx { 209 210 211 template <class _Value, class _Hash = hash<_Value>, class _Pred = std::equal_to<_Value>, 212 class _Alloc = std::allocator<_Value> > 213 class _LIBCPP_TEMPLATE_VIS hash_set 214 { 215 public: 216 // types 217 typedef _Value key_type; 218 typedef key_type value_type; 219 typedef _Hash hasher; 220 typedef _Pred key_equal; 221 typedef _Alloc allocator_type; 222 typedef value_type& reference; 223 typedef const value_type& const_reference; 224 225 private: 226 typedef std::__hash_table<value_type, hasher, key_equal, allocator_type> __table; 227 228 __table __table_; 229 230 public: 231 typedef typename __table::pointer pointer; 232 typedef typename __table::const_pointer const_pointer; 233 typedef typename __table::size_type size_type; 234 typedef typename __table::difference_type difference_type; 235 236 typedef typename __table::const_iterator iterator; 237 typedef typename __table::const_iterator const_iterator; 238 239 _LIBCPP_INLINE_VISIBILITY 240 hash_set() { } 241 explicit hash_set(size_type __n, const hasher& __hf = hasher(), 242 const key_equal& __eql = key_equal()); 243 hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, 244 const allocator_type& __a); 245 template <class _InputIterator> 246 hash_set(_InputIterator __first, _InputIterator __last); 247 template <class _InputIterator> 248 hash_set(_InputIterator __first, _InputIterator __last, 249 size_type __n, const hasher& __hf = hasher(), 250 const key_equal& __eql = key_equal()); 251 template <class _InputIterator> 252 hash_set(_InputIterator __first, _InputIterator __last, 253 size_type __n, const hasher& __hf, const key_equal& __eql, 254 const allocator_type& __a); 255 hash_set(const hash_set& __u); 256 257 _LIBCPP_INLINE_VISIBILITY 258 allocator_type get_allocator() const 259 {return allocator_type(__table_.__node_alloc());} 260 261 _LIBCPP_INLINE_VISIBILITY 262 bool empty() const {return __table_.size() == 0;} 263 _LIBCPP_INLINE_VISIBILITY 264 size_type size() const {return __table_.size();} 265 _LIBCPP_INLINE_VISIBILITY 266 size_type max_size() const {return __table_.max_size();} 267 268 _LIBCPP_INLINE_VISIBILITY 269 iterator begin() {return __table_.begin();} 270 _LIBCPP_INLINE_VISIBILITY 271 iterator end() {return __table_.end();} 272 _LIBCPP_INLINE_VISIBILITY 273 const_iterator begin() const {return __table_.begin();} 274 _LIBCPP_INLINE_VISIBILITY 275 const_iterator end() const {return __table_.end();} 276 277 _LIBCPP_INLINE_VISIBILITY 278 std::pair<iterator, bool> insert(const value_type& __x) 279 {return __table_.__insert_unique(__x);} 280 _LIBCPP_INLINE_VISIBILITY 281 iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;} 282 template <class _InputIterator> 283 _LIBCPP_INLINE_VISIBILITY 284 void insert(_InputIterator __first, _InputIterator __last); 285 286 _LIBCPP_INLINE_VISIBILITY 287 void erase(const_iterator __p) {__table_.erase(__p);} 288 _LIBCPP_INLINE_VISIBILITY 289 size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);} 290 _LIBCPP_INLINE_VISIBILITY 291 void erase(const_iterator __first, const_iterator __last) 292 {__table_.erase(__first, __last);} 293 _LIBCPP_INLINE_VISIBILITY 294 void clear() {__table_.clear();} 295 296 _LIBCPP_INLINE_VISIBILITY 297 void swap(hash_set& __u) {__table_.swap(__u.__table_);} 298 299 _LIBCPP_INLINE_VISIBILITY 300 hasher hash_funct() const {return __table_.hash_function();} 301 _LIBCPP_INLINE_VISIBILITY 302 key_equal key_eq() const {return __table_.key_eq();} 303 304 _LIBCPP_INLINE_VISIBILITY 305 iterator find(const key_type& __k) {return __table_.find(__k);} 306 _LIBCPP_INLINE_VISIBILITY 307 const_iterator find(const key_type& __k) const {return __table_.find(__k);} 308 _LIBCPP_INLINE_VISIBILITY 309 size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} 310 _LIBCPP_INLINE_VISIBILITY 311 std::pair<iterator, iterator> equal_range(const key_type& __k) 312 {return __table_.__equal_range_unique(__k);} 313 _LIBCPP_INLINE_VISIBILITY 314 std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const 315 {return __table_.__equal_range_unique(__k);} 316 317 _LIBCPP_INLINE_VISIBILITY 318 size_type bucket_count() const {return __table_.bucket_count();} 319 _LIBCPP_INLINE_VISIBILITY 320 size_type max_bucket_count() const {return __table_.max_bucket_count();} 321 322 _LIBCPP_INLINE_VISIBILITY 323 size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);} 324 325 _LIBCPP_INLINE_VISIBILITY 326 void resize(size_type __n) {__table_.rehash(__n);} 327 }; 328 329 template <class _Value, class _Hash, class _Pred, class _Alloc> 330 hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n, 331 const hasher& __hf, const key_equal& __eql) 332 : __table_(__hf, __eql) 333 { 334 __table_.rehash(__n); 335 } 336 337 template <class _Value, class _Hash, class _Pred, class _Alloc> 338 hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n, 339 const hasher& __hf, const key_equal& __eql, const allocator_type& __a) 340 : __table_(__hf, __eql, __a) 341 { 342 __table_.rehash(__n); 343 } 344 345 template <class _Value, class _Hash, class _Pred, class _Alloc> 346 template <class _InputIterator> 347 hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( 348 _InputIterator __first, _InputIterator __last) 349 { 350 insert(__first, __last); 351 } 352 353 template <class _Value, class _Hash, class _Pred, class _Alloc> 354 template <class _InputIterator> 355 hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( 356 _InputIterator __first, _InputIterator __last, size_type __n, 357 const hasher& __hf, const key_equal& __eql) 358 : __table_(__hf, __eql) 359 { 360 __table_.rehash(__n); 361 insert(__first, __last); 362 } 363 364 template <class _Value, class _Hash, class _Pred, class _Alloc> 365 template <class _InputIterator> 366 hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( 367 _InputIterator __first, _InputIterator __last, size_type __n, 368 const hasher& __hf, const key_equal& __eql, const allocator_type& __a) 369 : __table_(__hf, __eql, __a) 370 { 371 __table_.rehash(__n); 372 insert(__first, __last); 373 } 374 375 template <class _Value, class _Hash, class _Pred, class _Alloc> 376 hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( 377 const hash_set& __u) 378 : __table_(__u.__table_) 379 { 380 __table_.rehash(__u.bucket_count()); 381 insert(__u.begin(), __u.end()); 382 } 383 384 template <class _Value, class _Hash, class _Pred, class _Alloc> 385 template <class _InputIterator> 386 inline 387 void 388 hash_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, 389 _InputIterator __last) 390 { 391 for (; __first != __last; ++__first) 392 __table_.__insert_unique(*__first); 393 } 394 395 template <class _Value, class _Hash, class _Pred, class _Alloc> 396 inline _LIBCPP_INLINE_VISIBILITY 397 void 398 swap(hash_set<_Value, _Hash, _Pred, _Alloc>& __x, 399 hash_set<_Value, _Hash, _Pred, _Alloc>& __y) 400 { 401 __x.swap(__y); 402 } 403 404 template <class _Value, class _Hash, class _Pred, class _Alloc> 405 bool 406 operator==(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x, 407 const hash_set<_Value, _Hash, _Pred, _Alloc>& __y) 408 { 409 if (__x.size() != __y.size()) 410 return false; 411 typedef typename hash_set<_Value, _Hash, _Pred, _Alloc>::const_iterator 412 const_iterator; 413 for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); 414 __i != __ex; ++__i) 415 { 416 const_iterator __j = __y.find(*__i); 417 if (__j == __ey || !(*__i == *__j)) 418 return false; 419 } 420 return true; 421 } 422 423 template <class _Value, class _Hash, class _Pred, class _Alloc> 424 inline _LIBCPP_INLINE_VISIBILITY 425 bool 426 operator!=(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x, 427 const hash_set<_Value, _Hash, _Pred, _Alloc>& __y) 428 { 429 return !(__x == __y); 430 } 431 432 template <class _Value, class _Hash = hash<_Value>, class _Pred = std::equal_to<_Value>, 433 class _Alloc = std::allocator<_Value> > 434 class _LIBCPP_TEMPLATE_VIS hash_multiset 435 { 436 public: 437 // types 438 typedef _Value key_type; 439 typedef key_type value_type; 440 typedef _Hash hasher; 441 typedef _Pred key_equal; 442 typedef _Alloc allocator_type; 443 typedef value_type& reference; 444 typedef const value_type& const_reference; 445 446 private: 447 typedef std::__hash_table<value_type, hasher, key_equal, allocator_type> __table; 448 449 __table __table_; 450 451 public: 452 typedef typename __table::pointer pointer; 453 typedef typename __table::const_pointer const_pointer; 454 typedef typename __table::size_type size_type; 455 typedef typename __table::difference_type difference_type; 456 457 typedef typename __table::const_iterator iterator; 458 typedef typename __table::const_iterator const_iterator; 459 460 _LIBCPP_INLINE_VISIBILITY 461 hash_multiset() { } 462 explicit hash_multiset(size_type __n, const hasher& __hf = hasher(), 463 const key_equal& __eql = key_equal()); 464 hash_multiset(size_type __n, const hasher& __hf, 465 const key_equal& __eql, const allocator_type& __a); 466 template <class _InputIterator> 467 hash_multiset(_InputIterator __first, _InputIterator __last); 468 template <class _InputIterator> 469 hash_multiset(_InputIterator __first, _InputIterator __last, 470 size_type __n, const hasher& __hf = hasher(), 471 const key_equal& __eql = key_equal()); 472 template <class _InputIterator> 473 hash_multiset(_InputIterator __first, _InputIterator __last, 474 size_type __n , const hasher& __hf, 475 const key_equal& __eql, const allocator_type& __a); 476 hash_multiset(const hash_multiset& __u); 477 478 _LIBCPP_INLINE_VISIBILITY 479 allocator_type get_allocator() const 480 {return allocator_type(__table_.__node_alloc());} 481 482 _LIBCPP_INLINE_VISIBILITY 483 bool empty() const {return __table_.size() == 0;} 484 _LIBCPP_INLINE_VISIBILITY 485 size_type size() const {return __table_.size();} 486 _LIBCPP_INLINE_VISIBILITY 487 size_type max_size() const {return __table_.max_size();} 488 489 _LIBCPP_INLINE_VISIBILITY 490 iterator begin() {return __table_.begin();} 491 _LIBCPP_INLINE_VISIBILITY 492 iterator end() {return __table_.end();} 493 _LIBCPP_INLINE_VISIBILITY 494 const_iterator begin() const {return __table_.begin();} 495 _LIBCPP_INLINE_VISIBILITY 496 const_iterator end() const {return __table_.end();} 497 498 _LIBCPP_INLINE_VISIBILITY 499 iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);} 500 _LIBCPP_INLINE_VISIBILITY 501 iterator insert(const_iterator, const value_type& __x) {return insert(__x);} 502 template <class _InputIterator> 503 _LIBCPP_INLINE_VISIBILITY 504 void insert(_InputIterator __first, _InputIterator __last); 505 506 _LIBCPP_INLINE_VISIBILITY 507 void erase(const_iterator __p) {__table_.erase(__p);} 508 _LIBCPP_INLINE_VISIBILITY 509 size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);} 510 _LIBCPP_INLINE_VISIBILITY 511 void erase(const_iterator __first, const_iterator __last) 512 {__table_.erase(__first, __last);} 513 _LIBCPP_INLINE_VISIBILITY 514 void clear() {__table_.clear();} 515 516 _LIBCPP_INLINE_VISIBILITY 517 void swap(hash_multiset& __u) {__table_.swap(__u.__table_);} 518 519 _LIBCPP_INLINE_VISIBILITY 520 hasher hash_funct() const {return __table_.hash_function();} 521 _LIBCPP_INLINE_VISIBILITY 522 key_equal key_eq() const {return __table_.key_eq();} 523 524 _LIBCPP_INLINE_VISIBILITY 525 iterator find(const key_type& __k) {return __table_.find(__k);} 526 _LIBCPP_INLINE_VISIBILITY 527 const_iterator find(const key_type& __k) const {return __table_.find(__k);} 528 _LIBCPP_INLINE_VISIBILITY 529 size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} 530 _LIBCPP_INLINE_VISIBILITY 531 std::pair<iterator, iterator> equal_range(const key_type& __k) 532 {return __table_.__equal_range_multi(__k);} 533 _LIBCPP_INLINE_VISIBILITY 534 std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const 535 {return __table_.__equal_range_multi(__k);} 536 537 _LIBCPP_INLINE_VISIBILITY 538 size_type bucket_count() const {return __table_.bucket_count();} 539 _LIBCPP_INLINE_VISIBILITY 540 size_type max_bucket_count() const {return __table_.max_bucket_count();} 541 542 _LIBCPP_INLINE_VISIBILITY 543 size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);} 544 545 _LIBCPP_INLINE_VISIBILITY 546 void resize(size_type __n) {__table_.rehash(__n);} 547 }; 548 549 template <class _Value, class _Hash, class _Pred, class _Alloc> 550 hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( 551 size_type __n, const hasher& __hf, const key_equal& __eql) 552 : __table_(__hf, __eql) 553 { 554 __table_.rehash(__n); 555 } 556 557 template <class _Value, class _Hash, class _Pred, class _Alloc> 558 hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( 559 size_type __n, const hasher& __hf, const key_equal& __eql, 560 const allocator_type& __a) 561 : __table_(__hf, __eql, __a) 562 { 563 __table_.rehash(__n); 564 } 565 566 template <class _Value, class _Hash, class _Pred, class _Alloc> 567 template <class _InputIterator> 568 hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( 569 _InputIterator __first, _InputIterator __last) 570 { 571 insert(__first, __last); 572 } 573 574 template <class _Value, class _Hash, class _Pred, class _Alloc> 575 template <class _InputIterator> 576 hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( 577 _InputIterator __first, _InputIterator __last, size_type __n, 578 const hasher& __hf, const key_equal& __eql) 579 : __table_(__hf, __eql) 580 { 581 __table_.rehash(__n); 582 insert(__first, __last); 583 } 584 585 template <class _Value, class _Hash, class _Pred, class _Alloc> 586 template <class _InputIterator> 587 hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( 588 _InputIterator __first, _InputIterator __last, size_type __n, 589 const hasher& __hf, const key_equal& __eql, const allocator_type& __a) 590 : __table_(__hf, __eql, __a) 591 { 592 __table_.rehash(__n); 593 insert(__first, __last); 594 } 595 596 template <class _Value, class _Hash, class _Pred, class _Alloc> 597 hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( 598 const hash_multiset& __u) 599 : __table_(__u.__table_) 600 { 601 __table_.rehash(__u.bucket_count()); 602 insert(__u.begin(), __u.end()); 603 } 604 605 template <class _Value, class _Hash, class _Pred, class _Alloc> 606 template <class _InputIterator> 607 inline 608 void 609 hash_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, 610 _InputIterator __last) 611 { 612 for (; __first != __last; ++__first) 613 __table_.__insert_multi(*__first); 614 } 615 616 template <class _Value, class _Hash, class _Pred, class _Alloc> 617 inline _LIBCPP_INLINE_VISIBILITY 618 void 619 swap(hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 620 hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 621 { 622 __x.swap(__y); 623 } 624 625 template <class _Value, class _Hash, class _Pred, class _Alloc> 626 bool 627 operator==(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 628 const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 629 { 630 if (__x.size() != __y.size()) 631 return false; 632 typedef typename hash_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator 633 const_iterator; 634 typedef std::pair<const_iterator, const_iterator> _EqRng; 635 for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) 636 { 637 _EqRng __xeq = __x.equal_range(*__i); 638 _EqRng __yeq = __y.equal_range(*__i); 639 if (_VSTD::distance(__xeq.first, __xeq.second) != 640 _VSTD::distance(__yeq.first, __yeq.second) || 641 !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first)) 642 return false; 643 __i = __xeq.second; 644 } 645 return true; 646 } 647 648 template <class _Value, class _Hash, class _Pred, class _Alloc> 649 inline _LIBCPP_INLINE_VISIBILITY 650 bool 651 operator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 652 const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 653 { 654 return !(__x == __y); 655 } 656 657 } // __gnu_cxx 658 659 #endif // _LIBCPP_HASH_SET 660