1 2 // Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard. 3 // Copyright (C) 2005-2011 Daniel James. 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 7 // See http://www.boost.org/libs/unordered for documentation 8 9 #ifndef BOOST_UNORDERED_UNORDERED_SET_HPP_INCLUDED 10 #define BOOST_UNORDERED_UNORDERED_SET_HPP_INCLUDED 11 12 #include <boost/config.hpp> 13 #if defined(BOOST_HAS_PRAGMA_ONCE) 14 #pragma once 15 #endif 16 17 #include <boost/unordered/detail/set.hpp> 18 #include <boost/functional/hash.hpp> 19 #include <boost/move/move.hpp> 20 21 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 22 #include <initializer_list> 23 #endif 24 25 #if defined(BOOST_MSVC) 26 #pragma warning(push) 27 #if BOOST_MSVC >= 1400 28 #pragma warning(disable:4396) //the inline specifier cannot be used when a 29 // friend declaration refers to a specialization 30 // of a function template 31 #endif 32 #endif 33 34 namespace boost 35 { 36 namespace unordered 37 { 38 template <class T, class H, class P, class A> 39 class unordered_set 40 { 41 #if defined(BOOST_UNORDERED_USE_MOVE) 42 BOOST_COPYABLE_AND_MOVABLE(unordered_set) 43 #endif 44 public: 45 46 typedef T key_type; 47 typedef T value_type; 48 typedef H hasher; 49 typedef P key_equal; 50 typedef A allocator_type; 51 52 private: 53 54 typedef boost::unordered::detail::set<A, T, H, P> types; 55 typedef typename types::traits allocator_traits; 56 typedef typename types::table table; 57 58 public: 59 60 typedef typename allocator_traits::pointer pointer; 61 typedef typename allocator_traits::const_pointer const_pointer; 62 63 typedef value_type& reference; 64 typedef value_type const& const_reference; 65 66 typedef std::size_t size_type; 67 typedef std::ptrdiff_t difference_type; 68 69 typedef typename table::cl_iterator const_local_iterator; 70 typedef typename table::cl_iterator local_iterator; 71 typedef typename table::c_iterator const_iterator; 72 typedef typename table::c_iterator iterator; 73 74 private: 75 76 table table_; 77 78 public: 79 80 // constructors 81 82 explicit unordered_set( 83 size_type = boost::unordered::detail::default_bucket_count, 84 const hasher& = hasher(), 85 const key_equal& = key_equal(), 86 const allocator_type& = allocator_type()); 87 88 explicit unordered_set(allocator_type const&); 89 90 template <class InputIt> 91 unordered_set(InputIt, InputIt); 92 93 template <class InputIt> 94 unordered_set( 95 InputIt, InputIt, 96 size_type, 97 const hasher& = hasher(), 98 const key_equal& = key_equal()); 99 100 template <class InputIt> 101 unordered_set( 102 InputIt, InputIt, 103 size_type, 104 const hasher&, 105 const key_equal&, 106 const allocator_type&); 107 108 // copy/move constructors 109 110 unordered_set(unordered_set const&); 111 112 unordered_set(unordered_set const&, allocator_type const&); 113 114 #if defined(BOOST_UNORDERED_USE_MOVE) 115 unordered_set(BOOST_RV_REF(unordered_set) other) BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)116 BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) 117 : table_(other.table_, boost::unordered::detail::move_tag()) 118 { 119 } 120 #elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 121 unordered_set(unordered_set&& other) BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)122 BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) 123 : table_(other.table_, boost::unordered::detail::move_tag()) 124 { 125 } 126 #endif 127 128 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 129 unordered_set(unordered_set&&, allocator_type const&); 130 #endif 131 132 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 133 unordered_set( 134 std::initializer_list<value_type>, 135 size_type = boost::unordered::detail::default_bucket_count, 136 const hasher& = hasher(), 137 const key_equal&l = key_equal(), 138 const allocator_type& = allocator_type()); 139 #endif 140 141 // Destructor 142 143 ~unordered_set() BOOST_NOEXCEPT; 144 145 // Assign 146 147 #if defined(BOOST_UNORDERED_USE_MOVE) operator =(BOOST_COPY_ASSIGN_REF (unordered_set)x)148 unordered_set& operator=(BOOST_COPY_ASSIGN_REF(unordered_set) x) 149 { 150 table_.assign(x.table_); 151 return *this; 152 } 153 operator =(BOOST_RV_REF (unordered_set)x)154 unordered_set& operator=(BOOST_RV_REF(unordered_set) x) 155 { 156 table_.move_assign(x.table_); 157 return *this; 158 } 159 #else operator =(unordered_set const & x)160 unordered_set& operator=(unordered_set const& x) 161 { 162 table_.assign(x.table_); 163 return *this; 164 } 165 166 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) operator =(unordered_set && x)167 unordered_set& operator=(unordered_set&& x) 168 { 169 table_.move_assign(x.table_); 170 return *this; 171 } 172 #endif 173 #endif 174 175 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 176 unordered_set& operator=(std::initializer_list<value_type>); 177 #endif 178 get_allocator() const179 allocator_type get_allocator() const BOOST_NOEXCEPT 180 { 181 return table_.node_alloc(); 182 } 183 184 // size and capacity 185 empty() const186 bool empty() const BOOST_NOEXCEPT 187 { 188 return table_.size_ == 0; 189 } 190 size() const191 size_type size() const BOOST_NOEXCEPT 192 { 193 return table_.size_; 194 } 195 196 size_type max_size() const BOOST_NOEXCEPT; 197 198 // iterators 199 begin()200 iterator begin() BOOST_NOEXCEPT 201 { 202 return table_.begin(); 203 } 204 begin() const205 const_iterator begin() const BOOST_NOEXCEPT 206 { 207 return table_.begin(); 208 } 209 end()210 iterator end() BOOST_NOEXCEPT 211 { 212 return iterator(); 213 } 214 end() const215 const_iterator end() const BOOST_NOEXCEPT 216 { 217 return const_iterator(); 218 } 219 cbegin() const220 const_iterator cbegin() const BOOST_NOEXCEPT 221 { 222 return table_.begin(); 223 } 224 cend() const225 const_iterator cend() const BOOST_NOEXCEPT 226 { 227 return const_iterator(); 228 } 229 230 // emplace 231 232 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 233 template <class... Args> emplace(BOOST_FWD_REF (Args)...args)234 std::pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args) 235 { 236 return table_.emplace(boost::forward<Args>(args)...); 237 } 238 239 template <class... Args> emplace_hint(const_iterator,BOOST_FWD_REF (Args)...args)240 iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args) 241 { 242 return table_.emplace(boost::forward<Args>(args)...).first; 243 } 244 #else 245 246 #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) 247 248 // 0 argument emplace requires special treatment in case 249 // the container is instantiated with a value type that 250 // doesn't have a default constructor. 251 emplace(boost::unordered::detail::empty_emplace=boost::unordered::detail::empty_emplace (),value_type v=value_type ())252 std::pair<iterator, bool> emplace( 253 boost::unordered::detail::empty_emplace 254 = boost::unordered::detail::empty_emplace(), 255 value_type v = value_type()) 256 { 257 return this->emplace(boost::move(v)); 258 } 259 emplace_hint(const_iterator hint,boost::unordered::detail::empty_emplace=boost::unordered::detail::empty_emplace (),value_type v=value_type ())260 iterator emplace_hint(const_iterator hint, 261 boost::unordered::detail::empty_emplace 262 = boost::unordered::detail::empty_emplace(), 263 value_type v = value_type() 264 ) 265 { 266 return this->emplace_hint(hint, boost::move(v)); 267 } 268 269 #endif 270 271 template <typename A0> emplace(BOOST_FWD_REF (A0)a0)272 std::pair<iterator, bool> emplace(BOOST_FWD_REF(A0) a0) 273 { 274 return table_.emplace( 275 boost::unordered::detail::create_emplace_args( 276 boost::forward<A0>(a0)) 277 ); 278 } 279 280 template <typename A0> emplace_hint(const_iterator,BOOST_FWD_REF (A0)a0)281 iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0) 282 { 283 return table_.emplace( 284 boost::unordered::detail::create_emplace_args( 285 boost::forward<A0>(a0)) 286 ).first; 287 } 288 289 template <typename A0, typename A1> emplace(BOOST_FWD_REF (A0)a0,BOOST_FWD_REF (A1)a1)290 std::pair<iterator, bool> emplace( 291 BOOST_FWD_REF(A0) a0, 292 BOOST_FWD_REF(A1) a1) 293 { 294 return table_.emplace( 295 boost::unordered::detail::create_emplace_args( 296 boost::forward<A0>(a0), 297 boost::forward<A1>(a1)) 298 ); 299 } 300 301 template <typename A0, typename A1> emplace_hint(const_iterator,BOOST_FWD_REF (A0)a0,BOOST_FWD_REF (A1)a1)302 iterator emplace_hint(const_iterator, 303 BOOST_FWD_REF(A0) a0, 304 BOOST_FWD_REF(A1) a1) 305 { 306 return table_.emplace( 307 boost::unordered::detail::create_emplace_args( 308 boost::forward<A0>(a0), 309 boost::forward<A1>(a1)) 310 ).first; 311 } 312 313 template <typename A0, typename A1, typename A2> emplace(BOOST_FWD_REF (A0)a0,BOOST_FWD_REF (A1)a1,BOOST_FWD_REF (A2)a2)314 std::pair<iterator, bool> emplace( 315 BOOST_FWD_REF(A0) a0, 316 BOOST_FWD_REF(A1) a1, 317 BOOST_FWD_REF(A2) a2) 318 { 319 return table_.emplace( 320 boost::unordered::detail::create_emplace_args( 321 boost::forward<A0>(a0), 322 boost::forward<A1>(a1), 323 boost::forward<A2>(a2)) 324 ); 325 } 326 327 template <typename A0, typename A1, typename A2> emplace_hint(const_iterator,BOOST_FWD_REF (A0)a0,BOOST_FWD_REF (A1)a1,BOOST_FWD_REF (A2)a2)328 iterator emplace_hint(const_iterator, 329 BOOST_FWD_REF(A0) a0, 330 BOOST_FWD_REF(A1) a1, 331 BOOST_FWD_REF(A2) a2) 332 { 333 return table_.emplace( 334 boost::unordered::detail::create_emplace_args( 335 boost::forward<A0>(a0), 336 boost::forward<A1>(a1), 337 boost::forward<A2>(a2)) 338 ).first; 339 } 340 341 #define BOOST_UNORDERED_EMPLACE(z, n, _) \ 342 template < \ 343 BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \ 344 > \ 345 std::pair<iterator, bool> emplace( \ 346 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \ 347 ) \ 348 { \ 349 return table_.emplace( \ 350 boost::unordered::detail::create_emplace_args( \ 351 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \ 352 a) \ 353 )); \ 354 } \ 355 \ 356 template < \ 357 BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \ 358 > \ 359 iterator emplace_hint( \ 360 const_iterator, \ 361 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \ 362 ) \ 363 { \ 364 return table_.emplace( \ 365 boost::unordered::detail::create_emplace_args( \ 366 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \ 367 a) \ 368 )).first; \ 369 } 370 371 BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT, 372 BOOST_UNORDERED_EMPLACE, _) 373 374 #undef BOOST_UNORDERED_EMPLACE 375 376 #endif 377 insert(value_type const & x)378 std::pair<iterator, bool> insert(value_type const& x) 379 { 380 return this->emplace(x); 381 } 382 insert(BOOST_UNORDERED_RV_REF (value_type)x)383 std::pair<iterator, bool> insert(BOOST_UNORDERED_RV_REF(value_type) x) 384 { 385 return this->emplace(boost::move(x)); 386 } 387 insert(const_iterator hint,value_type const & x)388 iterator insert(const_iterator hint, value_type const& x) 389 { 390 return this->emplace_hint(hint, x); 391 } 392 insert(const_iterator hint,BOOST_UNORDERED_RV_REF (value_type)x)393 iterator insert(const_iterator hint, 394 BOOST_UNORDERED_RV_REF(value_type) x) 395 { 396 return this->emplace_hint(hint, boost::move(x)); 397 } 398 399 template <class InputIt> void insert(InputIt, InputIt); 400 401 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 402 void insert(std::initializer_list<value_type>); 403 #endif 404 405 iterator erase(const_iterator); 406 size_type erase(const key_type&); 407 iterator erase(const_iterator, const_iterator); quick_erase(const_iterator it)408 void quick_erase(const_iterator it) { erase(it); } erase_return_void(const_iterator it)409 void erase_return_void(const_iterator it) { erase(it); } 410 411 void clear(); 412 void swap(unordered_set&); 413 414 // observers 415 416 hasher hash_function() const; 417 key_equal key_eq() const; 418 419 // lookup 420 421 const_iterator find(const key_type&) const; 422 423 template <class CompatibleKey, class CompatibleHash, 424 class CompatiblePredicate> 425 const_iterator find( 426 CompatibleKey const&, 427 CompatibleHash const&, 428 CompatiblePredicate const&) const; 429 430 size_type count(const key_type&) const; 431 432 std::pair<const_iterator, const_iterator> 433 equal_range(const key_type&) const; 434 435 // bucket interface 436 bucket_count() const437 size_type bucket_count() const BOOST_NOEXCEPT 438 { 439 return table_.bucket_count_; 440 } 441 max_bucket_count() const442 size_type max_bucket_count() const BOOST_NOEXCEPT 443 { 444 return table_.max_bucket_count(); 445 } 446 447 size_type bucket_size(size_type) const; 448 bucket(const key_type & k) const449 size_type bucket(const key_type& k) const 450 { 451 return table_.hash_to_bucket(table_.hash(k)); 452 } 453 begin(size_type n)454 local_iterator begin(size_type n) 455 { 456 return local_iterator( 457 table_.begin(n), n, table_.bucket_count_); 458 } 459 begin(size_type n) const460 const_local_iterator begin(size_type n) const 461 { 462 return const_local_iterator( 463 table_.begin(n), n, table_.bucket_count_); 464 } 465 end(size_type)466 local_iterator end(size_type) 467 { 468 return local_iterator(); 469 } 470 end(size_type) const471 const_local_iterator end(size_type) const 472 { 473 return const_local_iterator(); 474 } 475 cbegin(size_type n) const476 const_local_iterator cbegin(size_type n) const 477 { 478 return const_local_iterator( 479 table_.begin(n), n, table_.bucket_count_); 480 } 481 cend(size_type) const482 const_local_iterator cend(size_type) const 483 { 484 return const_local_iterator(); 485 } 486 487 // hash policy 488 max_load_factor() const489 float max_load_factor() const BOOST_NOEXCEPT 490 { 491 return table_.mlf_; 492 } 493 494 float load_factor() const BOOST_NOEXCEPT; 495 void max_load_factor(float) BOOST_NOEXCEPT; 496 void rehash(size_type); 497 void reserve(size_type); 498 499 #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582) 500 friend bool operator==<T,H,P,A>( 501 unordered_set const&, unordered_set const&); 502 friend bool operator!=<T,H,P,A>( 503 unordered_set const&, unordered_set const&); 504 #endif 505 }; // class template unordered_set 506 507 template <class T, class H, class P, class A> 508 class unordered_multiset 509 { 510 #if defined(BOOST_UNORDERED_USE_MOVE) 511 BOOST_COPYABLE_AND_MOVABLE(unordered_multiset) 512 #endif 513 public: 514 515 typedef T key_type; 516 typedef T value_type; 517 typedef H hasher; 518 typedef P key_equal; 519 typedef A allocator_type; 520 521 private: 522 523 typedef boost::unordered::detail::multiset<A, T, H, P> types; 524 typedef typename types::traits allocator_traits; 525 typedef typename types::table table; 526 527 public: 528 529 typedef typename allocator_traits::pointer pointer; 530 typedef typename allocator_traits::const_pointer const_pointer; 531 532 typedef value_type& reference; 533 typedef value_type const& const_reference; 534 535 typedef std::size_t size_type; 536 typedef std::ptrdiff_t difference_type; 537 538 typedef typename table::cl_iterator const_local_iterator; 539 typedef typename table::cl_iterator local_iterator; 540 typedef typename table::c_iterator const_iterator; 541 typedef typename table::c_iterator iterator; 542 543 private: 544 545 table table_; 546 547 public: 548 549 // constructors 550 551 explicit unordered_multiset( 552 size_type = boost::unordered::detail::default_bucket_count, 553 const hasher& = hasher(), 554 const key_equal& = key_equal(), 555 const allocator_type& = allocator_type()); 556 557 explicit unordered_multiset(allocator_type const&); 558 559 template <class InputIt> 560 unordered_multiset(InputIt, InputIt); 561 562 template <class InputIt> 563 unordered_multiset( 564 InputIt, InputIt, 565 size_type, 566 const hasher& = hasher(), 567 const key_equal& = key_equal()); 568 569 template <class InputIt> 570 unordered_multiset( 571 InputIt, InputIt, 572 size_type, 573 const hasher&, 574 const key_equal&, 575 const allocator_type&); 576 577 // copy/move constructors 578 579 unordered_multiset(unordered_multiset const&); 580 581 unordered_multiset(unordered_multiset const&, allocator_type const&); 582 583 #if defined(BOOST_UNORDERED_USE_MOVE) 584 unordered_multiset(BOOST_RV_REF(unordered_multiset) other) BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)585 BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) 586 : table_(other.table_, boost::unordered::detail::move_tag()) 587 { 588 } 589 #elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 590 unordered_multiset(unordered_multiset&& other) BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)591 BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) 592 : table_(other.table_, boost::unordered::detail::move_tag()) 593 { 594 } 595 #endif 596 597 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 598 unordered_multiset(unordered_multiset&&, allocator_type const&); 599 #endif 600 601 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 602 unordered_multiset( 603 std::initializer_list<value_type>, 604 size_type = boost::unordered::detail::default_bucket_count, 605 const hasher& = hasher(), 606 const key_equal&l = key_equal(), 607 const allocator_type& = allocator_type()); 608 #endif 609 610 // Destructor 611 612 ~unordered_multiset() BOOST_NOEXCEPT; 613 614 // Assign 615 616 #if defined(BOOST_UNORDERED_USE_MOVE) operator =(BOOST_COPY_ASSIGN_REF (unordered_multiset)x)617 unordered_multiset& operator=( 618 BOOST_COPY_ASSIGN_REF(unordered_multiset) x) 619 { 620 table_.assign(x.table_); 621 return *this; 622 } 623 operator =(BOOST_RV_REF (unordered_multiset)x)624 unordered_multiset& operator=(BOOST_RV_REF(unordered_multiset) x) 625 { 626 table_.move_assign(x.table_); 627 return *this; 628 } 629 #else operator =(unordered_multiset const & x)630 unordered_multiset& operator=(unordered_multiset const& x) 631 { 632 table_.assign(x.table_); 633 return *this; 634 } 635 636 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) operator =(unordered_multiset && x)637 unordered_multiset& operator=(unordered_multiset&& x) 638 { 639 table_.move_assign(x.table_); 640 return *this; 641 } 642 #endif 643 #endif 644 645 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 646 unordered_multiset& operator=(std::initializer_list<value_type>); 647 #endif 648 get_allocator() const649 allocator_type get_allocator() const BOOST_NOEXCEPT 650 { 651 return table_.node_alloc(); 652 } 653 654 // size and capacity 655 empty() const656 bool empty() const BOOST_NOEXCEPT 657 { 658 return table_.size_ == 0; 659 } 660 size() const661 size_type size() const BOOST_NOEXCEPT 662 { 663 return table_.size_; 664 } 665 666 size_type max_size() const BOOST_NOEXCEPT; 667 668 // iterators 669 begin()670 iterator begin() BOOST_NOEXCEPT 671 { 672 return iterator(table_.begin()); 673 } 674 begin() const675 const_iterator begin() const BOOST_NOEXCEPT 676 { 677 return const_iterator(table_.begin()); 678 } 679 end()680 iterator end() BOOST_NOEXCEPT 681 { 682 return iterator(); 683 } 684 end() const685 const_iterator end() const BOOST_NOEXCEPT 686 { 687 return const_iterator(); 688 } 689 cbegin() const690 const_iterator cbegin() const BOOST_NOEXCEPT 691 { 692 return const_iterator(table_.begin()); 693 } 694 cend() const695 const_iterator cend() const BOOST_NOEXCEPT 696 { 697 return const_iterator(); 698 } 699 700 // emplace 701 702 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 703 template <class... Args> emplace(BOOST_FWD_REF (Args)...args)704 iterator emplace(BOOST_FWD_REF(Args)... args) 705 { 706 return table_.emplace(boost::forward<Args>(args)...); 707 } 708 709 template <class... Args> emplace_hint(const_iterator,BOOST_FWD_REF (Args)...args)710 iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args) 711 { 712 return table_.emplace(boost::forward<Args>(args)...); 713 } 714 #else 715 716 #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) 717 718 // 0 argument emplace requires special treatment in case 719 // the container is instantiated with a value type that 720 // doesn't have a default constructor. 721 emplace(boost::unordered::detail::empty_emplace=boost::unordered::detail::empty_emplace (),value_type v=value_type ())722 iterator emplace( 723 boost::unordered::detail::empty_emplace 724 = boost::unordered::detail::empty_emplace(), 725 value_type v = value_type()) 726 { 727 return this->emplace(boost::move(v)); 728 } 729 emplace_hint(const_iterator hint,boost::unordered::detail::empty_emplace=boost::unordered::detail::empty_emplace (),value_type v=value_type ())730 iterator emplace_hint(const_iterator hint, 731 boost::unordered::detail::empty_emplace 732 = boost::unordered::detail::empty_emplace(), 733 value_type v = value_type() 734 ) 735 { 736 return this->emplace_hint(hint, boost::move(v)); 737 } 738 739 #endif 740 741 template <typename A0> emplace(BOOST_FWD_REF (A0)a0)742 iterator emplace(BOOST_FWD_REF(A0) a0) 743 { 744 return table_.emplace( 745 boost::unordered::detail::create_emplace_args( 746 boost::forward<A0>(a0)) 747 ); 748 } 749 750 template <typename A0> emplace_hint(const_iterator,BOOST_FWD_REF (A0)a0)751 iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0) 752 { 753 return table_.emplace( 754 boost::unordered::detail::create_emplace_args( 755 boost::forward<A0>(a0)) 756 ); 757 } 758 759 template <typename A0, typename A1> emplace(BOOST_FWD_REF (A0)a0,BOOST_FWD_REF (A1)a1)760 iterator emplace( 761 BOOST_FWD_REF(A0) a0, 762 BOOST_FWD_REF(A1) a1) 763 { 764 return table_.emplace( 765 boost::unordered::detail::create_emplace_args( 766 boost::forward<A0>(a0), 767 boost::forward<A1>(a1)) 768 ); 769 } 770 771 template <typename A0, typename A1> emplace_hint(const_iterator,BOOST_FWD_REF (A0)a0,BOOST_FWD_REF (A1)a1)772 iterator emplace_hint(const_iterator, 773 BOOST_FWD_REF(A0) a0, 774 BOOST_FWD_REF(A1) a1) 775 { 776 return table_.emplace( 777 boost::unordered::detail::create_emplace_args( 778 boost::forward<A0>(a0), 779 boost::forward<A1>(a1)) 780 ); 781 } 782 783 template <typename A0, typename A1, typename A2> emplace(BOOST_FWD_REF (A0)a0,BOOST_FWD_REF (A1)a1,BOOST_FWD_REF (A2)a2)784 iterator emplace( 785 BOOST_FWD_REF(A0) a0, 786 BOOST_FWD_REF(A1) a1, 787 BOOST_FWD_REF(A2) a2) 788 { 789 return table_.emplace( 790 boost::unordered::detail::create_emplace_args( 791 boost::forward<A0>(a0), 792 boost::forward<A1>(a1), 793 boost::forward<A2>(a2)) 794 ); 795 } 796 797 template <typename A0, typename A1, typename A2> emplace_hint(const_iterator,BOOST_FWD_REF (A0)a0,BOOST_FWD_REF (A1)a1,BOOST_FWD_REF (A2)a2)798 iterator emplace_hint(const_iterator, 799 BOOST_FWD_REF(A0) a0, 800 BOOST_FWD_REF(A1) a1, 801 BOOST_FWD_REF(A2) a2) 802 { 803 return table_.emplace( 804 boost::unordered::detail::create_emplace_args( 805 boost::forward<A0>(a0), 806 boost::forward<A1>(a1), 807 boost::forward<A2>(a2)) 808 ); 809 } 810 811 #define BOOST_UNORDERED_EMPLACE(z, n, _) \ 812 template < \ 813 BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \ 814 > \ 815 iterator emplace( \ 816 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \ 817 ) \ 818 { \ 819 return table_.emplace( \ 820 boost::unordered::detail::create_emplace_args( \ 821 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \ 822 a) \ 823 )); \ 824 } \ 825 \ 826 template < \ 827 BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \ 828 > \ 829 iterator emplace_hint( \ 830 const_iterator, \ 831 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \ 832 ) \ 833 { \ 834 return table_.emplace( \ 835 boost::unordered::detail::create_emplace_args( \ 836 BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \ 837 a) \ 838 )); \ 839 } 840 841 BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT, 842 BOOST_UNORDERED_EMPLACE, _) 843 844 #undef BOOST_UNORDERED_EMPLACE 845 846 #endif 847 insert(value_type const & x)848 iterator insert(value_type const& x) 849 { 850 return this->emplace(x); 851 } 852 insert(BOOST_UNORDERED_RV_REF (value_type)x)853 iterator insert(BOOST_UNORDERED_RV_REF(value_type) x) 854 { 855 return this->emplace(boost::move(x)); 856 } 857 insert(const_iterator hint,value_type const & x)858 iterator insert(const_iterator hint, value_type const& x) 859 { 860 return this->emplace_hint(hint, x); 861 } 862 insert(const_iterator hint,BOOST_UNORDERED_RV_REF (value_type)x)863 iterator insert(const_iterator hint, 864 BOOST_UNORDERED_RV_REF(value_type) x) 865 { 866 return this->emplace_hint(hint, boost::move(x)); 867 } 868 869 template <class InputIt> void insert(InputIt, InputIt); 870 871 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 872 void insert(std::initializer_list<value_type>); 873 #endif 874 875 iterator erase(const_iterator); 876 size_type erase(const key_type&); 877 iterator erase(const_iterator, const_iterator); quick_erase(const_iterator it)878 void quick_erase(const_iterator it) { erase(it); } erase_return_void(const_iterator it)879 void erase_return_void(const_iterator it) { erase(it); } 880 881 void clear(); 882 void swap(unordered_multiset&); 883 884 // observers 885 886 hasher hash_function() const; 887 key_equal key_eq() const; 888 889 // lookup 890 891 const_iterator find(const key_type&) const; 892 893 template <class CompatibleKey, class CompatibleHash, 894 class CompatiblePredicate> 895 const_iterator find( 896 CompatibleKey const&, 897 CompatibleHash const&, 898 CompatiblePredicate const&) const; 899 900 size_type count(const key_type&) const; 901 902 std::pair<const_iterator, const_iterator> 903 equal_range(const key_type&) const; 904 905 // bucket interface 906 bucket_count() const907 size_type bucket_count() const BOOST_NOEXCEPT 908 { 909 return table_.bucket_count_; 910 } 911 max_bucket_count() const912 size_type max_bucket_count() const BOOST_NOEXCEPT 913 { 914 return table_.max_bucket_count(); 915 } 916 917 size_type bucket_size(size_type) const; 918 bucket(const key_type & k) const919 size_type bucket(const key_type& k) const 920 { 921 return table_.hash_to_bucket(table_.hash(k)); 922 } 923 begin(size_type n)924 local_iterator begin(size_type n) 925 { 926 return local_iterator( 927 table_.begin(n), n, table_.bucket_count_); 928 } 929 begin(size_type n) const930 const_local_iterator begin(size_type n) const 931 { 932 return const_local_iterator( 933 table_.begin(n), n, table_.bucket_count_); 934 } 935 end(size_type)936 local_iterator end(size_type) 937 { 938 return local_iterator(); 939 } 940 end(size_type) const941 const_local_iterator end(size_type) const 942 { 943 return const_local_iterator(); 944 } 945 cbegin(size_type n) const946 const_local_iterator cbegin(size_type n) const 947 { 948 return const_local_iterator( 949 table_.begin(n), n, table_.bucket_count_); 950 } 951 cend(size_type) const952 const_local_iterator cend(size_type) const 953 { 954 return const_local_iterator(); 955 } 956 957 // hash policy 958 max_load_factor() const959 float max_load_factor() const BOOST_NOEXCEPT 960 { 961 return table_.mlf_; 962 } 963 964 float load_factor() const BOOST_NOEXCEPT; 965 void max_load_factor(float) BOOST_NOEXCEPT; 966 void rehash(size_type); 967 void reserve(size_type); 968 969 #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582) 970 friend bool operator==<T,H,P,A>( 971 unordered_multiset const&, unordered_multiset const&); 972 friend bool operator!=<T,H,P,A>( 973 unordered_multiset const&, unordered_multiset const&); 974 #endif 975 }; // class template unordered_multiset 976 977 //////////////////////////////////////////////////////////////////////////////// 978 979 template <class T, class H, class P, class A> unordered_set(size_type n,const hasher & hf,const key_equal & eql,const allocator_type & a)980 unordered_set<T,H,P,A>::unordered_set( 981 size_type n, const hasher &hf, const key_equal &eql, 982 const allocator_type &a) 983 : table_(n, hf, eql, a) 984 { 985 } 986 987 template <class T, class H, class P, class A> unordered_set(allocator_type const & a)988 unordered_set<T,H,P,A>::unordered_set(allocator_type const& a) 989 : table_(boost::unordered::detail::default_bucket_count, 990 hasher(), key_equal(), a) 991 { 992 } 993 994 template <class T, class H, class P, class A> unordered_set(unordered_set const & other,allocator_type const & a)995 unordered_set<T,H,P,A>::unordered_set( 996 unordered_set const& other, allocator_type const& a) 997 : table_(other.table_, a) 998 { 999 } 1000 1001 template <class T, class H, class P, class A> 1002 template <class InputIt> unordered_set(InputIt f,InputIt l)1003 unordered_set<T,H,P,A>::unordered_set(InputIt f, InputIt l) 1004 : table_(boost::unordered::detail::initial_size(f, l), 1005 hasher(), key_equal(), allocator_type()) 1006 { 1007 table_.insert_range(f, l); 1008 } 1009 1010 template <class T, class H, class P, class A> 1011 template <class InputIt> unordered_set(InputIt f,InputIt l,size_type n,const hasher & hf,const key_equal & eql)1012 unordered_set<T,H,P,A>::unordered_set( 1013 InputIt f, InputIt l, 1014 size_type n, 1015 const hasher &hf, 1016 const key_equal &eql) 1017 : table_(boost::unordered::detail::initial_size(f, l, n), 1018 hf, eql, allocator_type()) 1019 { 1020 table_.insert_range(f, l); 1021 } 1022 1023 template <class T, class H, class P, class A> 1024 template <class InputIt> unordered_set(InputIt f,InputIt l,size_type n,const hasher & hf,const key_equal & eql,const allocator_type & a)1025 unordered_set<T,H,P,A>::unordered_set( 1026 InputIt f, InputIt l, 1027 size_type n, 1028 const hasher &hf, 1029 const key_equal &eql, 1030 const allocator_type &a) 1031 : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a) 1032 { 1033 table_.insert_range(f, l); 1034 } 1035 1036 template <class T, class H, class P, class A> ~unordered_set()1037 unordered_set<T,H,P,A>::~unordered_set() BOOST_NOEXCEPT {} 1038 1039 template <class T, class H, class P, class A> unordered_set(unordered_set const & other)1040 unordered_set<T,H,P,A>::unordered_set( 1041 unordered_set const& other) 1042 : table_(other.table_) 1043 { 1044 } 1045 1046 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 1047 1048 template <class T, class H, class P, class A> unordered_set(unordered_set && other,allocator_type const & a)1049 unordered_set<T,H,P,A>::unordered_set( 1050 unordered_set&& other, allocator_type const& a) 1051 : table_(other.table_, a, boost::unordered::detail::move_tag()) 1052 { 1053 } 1054 1055 #endif 1056 1057 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 1058 1059 template <class T, class H, class P, class A> unordered_set(std::initializer_list<value_type> list,size_type n,const hasher & hf,const key_equal & eql,const allocator_type & a)1060 unordered_set<T,H,P,A>::unordered_set( 1061 std::initializer_list<value_type> list, size_type n, 1062 const hasher &hf, const key_equal &eql, const allocator_type &a) 1063 : table_( 1064 boost::unordered::detail::initial_size( 1065 list.begin(), list.end(), n), 1066 hf, eql, a) 1067 { 1068 table_.insert_range(list.begin(), list.end()); 1069 } 1070 1071 template <class T, class H, class P, class A> operator =(std::initializer_list<value_type> list)1072 unordered_set<T,H,P,A>& unordered_set<T,H,P,A>::operator=( 1073 std::initializer_list<value_type> list) 1074 { 1075 table_.clear(); 1076 table_.insert_range(list.begin(), list.end()); 1077 return *this; 1078 } 1079 1080 #endif 1081 1082 // size and capacity 1083 1084 template <class T, class H, class P, class A> max_size() const1085 std::size_t unordered_set<T,H,P,A>::max_size() const BOOST_NOEXCEPT 1086 { 1087 return table_.max_size(); 1088 } 1089 1090 // modifiers 1091 1092 template <class T, class H, class P, class A> 1093 template <class InputIt> insert(InputIt first,InputIt last)1094 void unordered_set<T,H,P,A>::insert(InputIt first, InputIt last) 1095 { 1096 table_.insert_range(first, last); 1097 } 1098 1099 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 1100 template <class T, class H, class P, class A> insert(std::initializer_list<value_type> list)1101 void unordered_set<T,H,P,A>::insert( 1102 std::initializer_list<value_type> list) 1103 { 1104 table_.insert_range(list.begin(), list.end()); 1105 } 1106 #endif 1107 1108 template <class T, class H, class P, class A> 1109 typename unordered_set<T,H,P,A>::iterator erase(const_iterator position)1110 unordered_set<T,H,P,A>::erase(const_iterator position) 1111 { 1112 return table_.erase(position); 1113 } 1114 1115 template <class T, class H, class P, class A> 1116 typename unordered_set<T,H,P,A>::size_type erase(const key_type & k)1117 unordered_set<T,H,P,A>::erase(const key_type& k) 1118 { 1119 return table_.erase_key(k); 1120 } 1121 1122 template <class T, class H, class P, class A> 1123 typename unordered_set<T,H,P,A>::iterator erase(const_iterator first,const_iterator last)1124 unordered_set<T,H,P,A>::erase( 1125 const_iterator first, const_iterator last) 1126 { 1127 return table_.erase_range(first, last); 1128 } 1129 1130 template <class T, class H, class P, class A> clear()1131 void unordered_set<T,H,P,A>::clear() 1132 { 1133 table_.clear(); 1134 } 1135 1136 template <class T, class H, class P, class A> swap(unordered_set & other)1137 void unordered_set<T,H,P,A>::swap(unordered_set& other) 1138 { 1139 table_.swap(other.table_); 1140 } 1141 1142 // observers 1143 1144 template <class T, class H, class P, class A> 1145 typename unordered_set<T,H,P,A>::hasher hash_function() const1146 unordered_set<T,H,P,A>::hash_function() const 1147 { 1148 return table_.hash_function(); 1149 } 1150 1151 template <class T, class H, class P, class A> 1152 typename unordered_set<T,H,P,A>::key_equal key_eq() const1153 unordered_set<T,H,P,A>::key_eq() const 1154 { 1155 return table_.key_eq(); 1156 } 1157 1158 // lookup 1159 1160 template <class T, class H, class P, class A> 1161 typename unordered_set<T,H,P,A>::const_iterator find(const key_type & k) const1162 unordered_set<T,H,P,A>::find(const key_type& k) const 1163 { 1164 return table_.find_node(k); 1165 } 1166 1167 template <class T, class H, class P, class A> 1168 template <class CompatibleKey, class CompatibleHash, 1169 class CompatiblePredicate> 1170 typename unordered_set<T,H,P,A>::const_iterator find(CompatibleKey const & k,CompatibleHash const & hash,CompatiblePredicate const & eq) const1171 unordered_set<T,H,P,A>::find( 1172 CompatibleKey const& k, 1173 CompatibleHash const& hash, 1174 CompatiblePredicate const& eq) const 1175 { 1176 return table_.generic_find_node(k, hash, eq); 1177 } 1178 1179 template <class T, class H, class P, class A> 1180 typename unordered_set<T,H,P,A>::size_type count(const key_type & k) const1181 unordered_set<T,H,P,A>::count(const key_type& k) const 1182 { 1183 return table_.count(k); 1184 } 1185 1186 template <class T, class H, class P, class A> 1187 std::pair< 1188 typename unordered_set<T,H,P,A>::const_iterator, 1189 typename unordered_set<T,H,P,A>::const_iterator> equal_range(const key_type & k) const1190 unordered_set<T,H,P,A>::equal_range(const key_type& k) const 1191 { 1192 return table_.equal_range(k); 1193 } 1194 1195 template <class T, class H, class P, class A> 1196 typename unordered_set<T,H,P,A>::size_type bucket_size(size_type n) const1197 unordered_set<T,H,P,A>::bucket_size(size_type n) const 1198 { 1199 return table_.bucket_size(n); 1200 } 1201 1202 // hash policy 1203 1204 template <class T, class H, class P, class A> load_factor() const1205 float unordered_set<T,H,P,A>::load_factor() const BOOST_NOEXCEPT 1206 { 1207 return table_.load_factor(); 1208 } 1209 1210 template <class T, class H, class P, class A> max_load_factor(float m)1211 void unordered_set<T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT 1212 { 1213 table_.max_load_factor(m); 1214 } 1215 1216 template <class T, class H, class P, class A> rehash(size_type n)1217 void unordered_set<T,H,P,A>::rehash(size_type n) 1218 { 1219 table_.rehash(n); 1220 } 1221 1222 template <class T, class H, class P, class A> reserve(size_type n)1223 void unordered_set<T,H,P,A>::reserve(size_type n) 1224 { 1225 table_.reserve(n); 1226 } 1227 1228 template <class T, class H, class P, class A> operator ==(unordered_set<T,H,P,A> const & m1,unordered_set<T,H,P,A> const & m2)1229 inline bool operator==( 1230 unordered_set<T,H,P,A> const& m1, 1231 unordered_set<T,H,P,A> const& m2) 1232 { 1233 #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613)) 1234 struct dummy { unordered_set<T,H,P,A> x; }; 1235 #endif 1236 return m1.table_.equals(m2.table_); 1237 } 1238 1239 template <class T, class H, class P, class A> operator !=(unordered_set<T,H,P,A> const & m1,unordered_set<T,H,P,A> const & m2)1240 inline bool operator!=( 1241 unordered_set<T,H,P,A> const& m1, 1242 unordered_set<T,H,P,A> const& m2) 1243 { 1244 #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613)) 1245 struct dummy { unordered_set<T,H,P,A> x; }; 1246 #endif 1247 return !m1.table_.equals(m2.table_); 1248 } 1249 1250 template <class T, class H, class P, class A> swap(unordered_set<T,H,P,A> & m1,unordered_set<T,H,P,A> & m2)1251 inline void swap( 1252 unordered_set<T,H,P,A> &m1, 1253 unordered_set<T,H,P,A> &m2) 1254 { 1255 #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613)) 1256 struct dummy { unordered_set<T,H,P,A> x; }; 1257 #endif 1258 m1.swap(m2); 1259 } 1260 1261 //////////////////////////////////////////////////////////////////////////////// 1262 1263 template <class T, class H, class P, class A> unordered_multiset(size_type n,const hasher & hf,const key_equal & eql,const allocator_type & a)1264 unordered_multiset<T,H,P,A>::unordered_multiset( 1265 size_type n, const hasher &hf, const key_equal &eql, 1266 const allocator_type &a) 1267 : table_(n, hf, eql, a) 1268 { 1269 } 1270 1271 template <class T, class H, class P, class A> unordered_multiset(allocator_type const & a)1272 unordered_multiset<T,H,P,A>::unordered_multiset(allocator_type const& a) 1273 : table_(boost::unordered::detail::default_bucket_count, 1274 hasher(), key_equal(), a) 1275 { 1276 } 1277 1278 template <class T, class H, class P, class A> unordered_multiset(unordered_multiset const & other,allocator_type const & a)1279 unordered_multiset<T,H,P,A>::unordered_multiset( 1280 unordered_multiset const& other, allocator_type const& a) 1281 : table_(other.table_, a) 1282 { 1283 } 1284 1285 template <class T, class H, class P, class A> 1286 template <class InputIt> unordered_multiset(InputIt f,InputIt l)1287 unordered_multiset<T,H,P,A>::unordered_multiset(InputIt f, InputIt l) 1288 : table_(boost::unordered::detail::initial_size(f, l), 1289 hasher(), key_equal(), allocator_type()) 1290 { 1291 table_.insert_range(f, l); 1292 } 1293 1294 template <class T, class H, class P, class A> 1295 template <class InputIt> unordered_multiset(InputIt f,InputIt l,size_type n,const hasher & hf,const key_equal & eql)1296 unordered_multiset<T,H,P,A>::unordered_multiset( 1297 InputIt f, InputIt l, 1298 size_type n, 1299 const hasher &hf, 1300 const key_equal &eql) 1301 : table_(boost::unordered::detail::initial_size(f, l, n), 1302 hf, eql, allocator_type()) 1303 { 1304 table_.insert_range(f, l); 1305 } 1306 1307 template <class T, class H, class P, class A> 1308 template <class InputIt> unordered_multiset(InputIt f,InputIt l,size_type n,const hasher & hf,const key_equal & eql,const allocator_type & a)1309 unordered_multiset<T,H,P,A>::unordered_multiset( 1310 InputIt f, InputIt l, 1311 size_type n, 1312 const hasher &hf, 1313 const key_equal &eql, 1314 const allocator_type &a) 1315 : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a) 1316 { 1317 table_.insert_range(f, l); 1318 } 1319 1320 template <class T, class H, class P, class A> ~unordered_multiset()1321 unordered_multiset<T,H,P,A>::~unordered_multiset() BOOST_NOEXCEPT {} 1322 1323 template <class T, class H, class P, class A> unordered_multiset(unordered_multiset const & other)1324 unordered_multiset<T,H,P,A>::unordered_multiset( 1325 unordered_multiset const& other) 1326 : table_(other.table_) 1327 { 1328 } 1329 1330 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 1331 1332 template <class T, class H, class P, class A> unordered_multiset(unordered_multiset && other,allocator_type const & a)1333 unordered_multiset<T,H,P,A>::unordered_multiset( 1334 unordered_multiset&& other, allocator_type const& a) 1335 : table_(other.table_, a, boost::unordered::detail::move_tag()) 1336 { 1337 } 1338 1339 #endif 1340 1341 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 1342 1343 template <class T, class H, class P, class A> unordered_multiset(std::initializer_list<value_type> list,size_type n,const hasher & hf,const key_equal & eql,const allocator_type & a)1344 unordered_multiset<T,H,P,A>::unordered_multiset( 1345 std::initializer_list<value_type> list, size_type n, 1346 const hasher &hf, const key_equal &eql, const allocator_type &a) 1347 : table_( 1348 boost::unordered::detail::initial_size( 1349 list.begin(), list.end(), n), 1350 hf, eql, a) 1351 { 1352 table_.insert_range(list.begin(), list.end()); 1353 } 1354 1355 template <class T, class H, class P, class A> operator =(std::initializer_list<value_type> list)1356 unordered_multiset<T,H,P,A>& unordered_multiset<T,H,P,A>::operator=( 1357 std::initializer_list<value_type> list) 1358 { 1359 table_.clear(); 1360 table_.insert_range(list.begin(), list.end()); 1361 return *this; 1362 } 1363 1364 #endif 1365 1366 // size and capacity 1367 1368 template <class T, class H, class P, class A> max_size() const1369 std::size_t unordered_multiset<T,H,P,A>::max_size() const BOOST_NOEXCEPT 1370 { 1371 return table_.max_size(); 1372 } 1373 1374 // modifiers 1375 1376 template <class T, class H, class P, class A> 1377 template <class InputIt> insert(InputIt first,InputIt last)1378 void unordered_multiset<T,H,P,A>::insert(InputIt first, InputIt last) 1379 { 1380 table_.insert_range(first, last); 1381 } 1382 1383 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) 1384 template <class T, class H, class P, class A> insert(std::initializer_list<value_type> list)1385 void unordered_multiset<T,H,P,A>::insert( 1386 std::initializer_list<value_type> list) 1387 { 1388 table_.insert_range(list.begin(), list.end()); 1389 } 1390 #endif 1391 1392 template <class T, class H, class P, class A> 1393 typename unordered_multiset<T,H,P,A>::iterator erase(const_iterator position)1394 unordered_multiset<T,H,P,A>::erase(const_iterator position) 1395 { 1396 return table_.erase(position); 1397 } 1398 1399 template <class T, class H, class P, class A> 1400 typename unordered_multiset<T,H,P,A>::size_type erase(const key_type & k)1401 unordered_multiset<T,H,P,A>::erase(const key_type& k) 1402 { 1403 return table_.erase_key(k); 1404 } 1405 1406 template <class T, class H, class P, class A> 1407 typename unordered_multiset<T,H,P,A>::iterator erase(const_iterator first,const_iterator last)1408 unordered_multiset<T,H,P,A>::erase( 1409 const_iterator first, const_iterator last) 1410 { 1411 return table_.erase_range(first, last); 1412 } 1413 1414 template <class T, class H, class P, class A> clear()1415 void unordered_multiset<T,H,P,A>::clear() 1416 { 1417 table_.clear(); 1418 } 1419 1420 template <class T, class H, class P, class A> swap(unordered_multiset & other)1421 void unordered_multiset<T,H,P,A>::swap(unordered_multiset& other) 1422 { 1423 table_.swap(other.table_); 1424 } 1425 1426 // observers 1427 1428 template <class T, class H, class P, class A> 1429 typename unordered_multiset<T,H,P,A>::hasher hash_function() const1430 unordered_multiset<T,H,P,A>::hash_function() const 1431 { 1432 return table_.hash_function(); 1433 } 1434 1435 template <class T, class H, class P, class A> 1436 typename unordered_multiset<T,H,P,A>::key_equal key_eq() const1437 unordered_multiset<T,H,P,A>::key_eq() const 1438 { 1439 return table_.key_eq(); 1440 } 1441 1442 // lookup 1443 1444 template <class T, class H, class P, class A> 1445 typename unordered_multiset<T,H,P,A>::const_iterator find(const key_type & k) const1446 unordered_multiset<T,H,P,A>::find(const key_type& k) const 1447 { 1448 return table_.find_node(k); 1449 } 1450 1451 template <class T, class H, class P, class A> 1452 template <class CompatibleKey, class CompatibleHash, 1453 class CompatiblePredicate> 1454 typename unordered_multiset<T,H,P,A>::const_iterator find(CompatibleKey const & k,CompatibleHash const & hash,CompatiblePredicate const & eq) const1455 unordered_multiset<T,H,P,A>::find( 1456 CompatibleKey const& k, 1457 CompatibleHash const& hash, 1458 CompatiblePredicate const& eq) const 1459 { 1460 return table_.generic_find_node(k, hash, eq); 1461 } 1462 1463 template <class T, class H, class P, class A> 1464 typename unordered_multiset<T,H,P,A>::size_type count(const key_type & k) const1465 unordered_multiset<T,H,P,A>::count(const key_type& k) const 1466 { 1467 return table_.count(k); 1468 } 1469 1470 template <class T, class H, class P, class A> 1471 std::pair< 1472 typename unordered_multiset<T,H,P,A>::const_iterator, 1473 typename unordered_multiset<T,H,P,A>::const_iterator> equal_range(const key_type & k) const1474 unordered_multiset<T,H,P,A>::equal_range(const key_type& k) const 1475 { 1476 return table_.equal_range(k); 1477 } 1478 1479 template <class T, class H, class P, class A> 1480 typename unordered_multiset<T,H,P,A>::size_type bucket_size(size_type n) const1481 unordered_multiset<T,H,P,A>::bucket_size(size_type n) const 1482 { 1483 return table_.bucket_size(n); 1484 } 1485 1486 // hash policy 1487 1488 template <class T, class H, class P, class A> load_factor() const1489 float unordered_multiset<T,H,P,A>::load_factor() const BOOST_NOEXCEPT 1490 { 1491 return table_.load_factor(); 1492 } 1493 1494 template <class T, class H, class P, class A> max_load_factor(float m)1495 void unordered_multiset<T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT 1496 { 1497 table_.max_load_factor(m); 1498 } 1499 1500 template <class T, class H, class P, class A> rehash(size_type n)1501 void unordered_multiset<T,H,P,A>::rehash(size_type n) 1502 { 1503 table_.rehash(n); 1504 } 1505 1506 template <class T, class H, class P, class A> reserve(size_type n)1507 void unordered_multiset<T,H,P,A>::reserve(size_type n) 1508 { 1509 table_.reserve(n); 1510 } 1511 1512 template <class T, class H, class P, class A> operator ==(unordered_multiset<T,H,P,A> const & m1,unordered_multiset<T,H,P,A> const & m2)1513 inline bool operator==( 1514 unordered_multiset<T,H,P,A> const& m1, 1515 unordered_multiset<T,H,P,A> const& m2) 1516 { 1517 #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613)) 1518 struct dummy { unordered_multiset<T,H,P,A> x; }; 1519 #endif 1520 return m1.table_.equals(m2.table_); 1521 } 1522 1523 template <class T, class H, class P, class A> operator !=(unordered_multiset<T,H,P,A> const & m1,unordered_multiset<T,H,P,A> const & m2)1524 inline bool operator!=( 1525 unordered_multiset<T,H,P,A> const& m1, 1526 unordered_multiset<T,H,P,A> const& m2) 1527 { 1528 #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613)) 1529 struct dummy { unordered_multiset<T,H,P,A> x; }; 1530 #endif 1531 return !m1.table_.equals(m2.table_); 1532 } 1533 1534 template <class T, class H, class P, class A> swap(unordered_multiset<T,H,P,A> & m1,unordered_multiset<T,H,P,A> & m2)1535 inline void swap( 1536 unordered_multiset<T,H,P,A> &m1, 1537 unordered_multiset<T,H,P,A> &m2) 1538 { 1539 #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613)) 1540 struct dummy { unordered_multiset<T,H,P,A> x; }; 1541 #endif 1542 m1.swap(m2); 1543 } 1544 } // namespace unordered 1545 } // namespace boost 1546 1547 #if defined(BOOST_MSVC) 1548 #pragma warning(pop) 1549 #endif 1550 1551 #endif // BOOST_UNORDERED_UNORDERED_SET_HPP_INCLUDED 1552