Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/bits/stl_multiset.h
1 // Multiset implementation -*- C++ -*- 2 3 // Copyright (C) 2001-2025 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /* 26 * 27 * Copyright (c) 1994 28 * Hewlett-Packard Company 29 * 30 * Permission to use, copy, modify, distribute and sell this software 31 * and its documentation for any purpose is hereby granted without fee, 32 * provided that the above copyright notice appear in all copies and 33 * that both that copyright notice and this permission notice appear 34 * in supporting documentation. Hewlett-Packard Company makes no 35 * representations about the suitability of this software for any 36 * purpose. It is provided "as is" without express or implied warranty. 37 * 38 * 39 * Copyright (c) 1996 40 * Silicon Graphics Computer Systems, Inc. 41 * 42 * Permission to use, copy, modify, distribute and sell this software 43 * and its documentation for any purpose is hereby granted without fee, 44 * provided that the above copyright notice appear in all copies and 45 * that both that copyright notice and this permission notice appear 46 * in supporting documentation. Silicon Graphics makes no 47 * representations about the suitability of this software for any 48 * purpose. It is provided "as is" without express or implied warranty. 49 */ 50 51 /** @file bits/stl_multiset.h 52 * This is an internal header file, included by other library headers. 53 * Do not attempt to use it directly. @headername{set} 54 */ 55 56 #ifndef _STL_MULTISET_H 57 #define _STL_MULTISET_H 1 58 59 #include <bits/concept_check.h> 60 #if __cplusplus >= 201103L 61 #include <initializer_list> 62 #endif 63 #if __glibcxx_containers_ranges // C++ >= 23 64 # include <bits/ranges_base.h> // ranges::begin, ranges::distance etc. 65 #endif 66 67 namespace std _GLIBCXX_VISIBILITY(default) 68 { 69 _GLIBCXX_BEGIN_NAMESPACE_VERSION 70 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 71 72 template<typename _Key, typename _Compare, typename _Alloc> 73 class set; 74 75 /** 76 * @brief A standard container made up of elements, which can be retrieved 77 * in logarithmic time. 78 * 79 * @ingroup associative_containers 80 * @headerfile set 81 * @since C++98 82 * 83 * @tparam _Key Type of key objects. 84 * @tparam _Compare Comparison function object type, defaults to less<_Key>. 85 * @tparam _Alloc Allocator type, defaults to allocator<_Key>. 86 * 87 * Meets the requirements of a <a href="tables.html#65">container</a>, a 88 * <a href="tables.html#66">reversible container</a>, and an 89 * <a href="tables.html#69">associative container</a> (using equivalent 90 * keys). For a @c multiset<Key> the key_type and value_type are Key. 91 * 92 * Multisets support bidirectional iterators. 93 * 94 * The private tree data is declared exactly the same way for set and 95 * multiset; the distinction is made entirely in how the tree functions are 96 * called (*_unique versus *_equal, same as the standard). 97 */ 98 template <typename _Key, typename _Compare = std::less<_Key>, 99 typename _Alloc = std::allocator<_Key> > 100 class multiset 101 { 102 #ifdef _GLIBCXX_CONCEPT_CHECKS 103 // concept requirements 104 typedef typename _Alloc::value_type _Alloc_value_type; 105 # if __cplusplus < 201103L 106 __glibcxx_class_requires(_Key, _SGIAssignableConcept) 107 # endif 108 __glibcxx_class_requires4(_Compare, bool, _Key, _Key, 109 _BinaryFunctionConcept) 110 __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept) 111 #endif 112 113 #if __cplusplus >= 201103L 114 static_assert(is_same<typename remove_cv<_Key>::type, _Key>::value, 115 "std::multiset must have a non-const, non-volatile value_type"); 116 # if __cplusplus > 201703L || defined __STRICT_ANSI__ 117 static_assert(is_same<typename _Alloc::value_type, _Key>::value, 118 "std::multiset must have the same value_type as its allocator"); 119 # endif 120 #endif 121 122 public: 123 // typedefs: 124 typedef _Key key_type; 125 typedef _Key value_type; 126 typedef _Compare key_compare; 127 typedef _Compare value_compare; 128 typedef _Alloc allocator_type; 129 130 private: 131 /// This turns a red-black tree into a [multi]set. 132 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template 133 rebind<_Key>::other _Key_alloc_type; 134 135 typedef _Rb_tree<key_type, value_type, _Identity<value_type>, 136 key_compare, _Key_alloc_type> _Rep_type; 137 /// The actual tree structure. 138 _Rep_type _M_t; 139 140 typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits; 141 142 public: 143 typedef typename _Alloc_traits::pointer pointer; 144 typedef typename _Alloc_traits::const_pointer const_pointer; 145 typedef typename _Alloc_traits::reference reference; 146 typedef typename _Alloc_traits::const_reference const_reference; 147 // _GLIBCXX_RESOLVE_LIB_DEFECTS 148 // DR 103. set::iterator is required to be modifiable, 149 // but this allows modification of keys. 150 typedef typename _Rep_type::const_iterator iterator; 151 typedef typename _Rep_type::const_iterator const_iterator; 152 typedef typename _Rep_type::const_reverse_iterator reverse_iterator; 153 typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; 154 typedef typename _Rep_type::size_type size_type; 155 typedef typename _Rep_type::difference_type difference_type; 156 157 #ifdef __glibcxx_node_extract // >= C++17 158 using node_type = typename _Rep_type::node_type; 159 #endif 160 161 // allocation/deallocation 162 /** 163 * @brief Default constructor creates no elements. 164 */ 165 #if __cplusplus < 201103L 166 multiset() : _M_t() { } 167 #else 168 multiset() = default; 169 #endif 170 171 /** 172 * @brief Creates a %multiset with no elements. 173 * @param __comp Comparator to use. 174 * @param __a An allocator object. 175 */ 176 explicit 177 multiset(const _Compare& __comp, 178 const allocator_type& __a = allocator_type()) 179 : _M_t(__comp, _Key_alloc_type(__a)) { } 180 181 /** 182 * @brief Builds a %multiset from a range. 183 * @param __first An input iterator. 184 * @param __last An input iterator. 185 * 186 * Create a %multiset consisting of copies of the elements from 187 * [first,last). This is linear in N if the range is already sorted, 188 * and NlogN otherwise (where N is distance(__first,__last)). 189 */ 190 template<typename _InputIterator> 191 multiset(_InputIterator __first, _InputIterator __last) 192 : _M_t() 193 { _M_t._M_insert_range_equal(__first, __last); } 194 195 /** 196 * @brief Builds a %multiset from a range. 197 * @param __first An input iterator. 198 * @param __last An input iterator. 199 * @param __comp A comparison functor. 200 * @param __a An allocator object. 201 * 202 * Create a %multiset consisting of copies of the elements from 203 * [__first,__last). This is linear in N if the range is already sorted, 204 * and NlogN otherwise (where N is distance(__first,__last)). 205 */ 206 template<typename _InputIterator> 207 multiset(_InputIterator __first, _InputIterator __last, 208 const _Compare& __comp, 209 const allocator_type& __a = allocator_type()) 210 : _M_t(__comp, _Key_alloc_type(__a)) 211 { _M_t._M_insert_range_equal(__first, __last); } 212 213 /** 214 * @brief %Multiset copy constructor. 215 * 216 * Whether the allocator is copied depends on the allocator traits. 217 */ 218 #if __cplusplus < 201103L 219 multiset(const multiset& __x) 220 : _M_t(__x._M_t) { } 221 #else 222 multiset(const multiset&) = default; 223 224 /** 225 * @brief %Multiset move constructor. 226 * 227 * The newly-created %multiset contains the exact contents of the 228 * moved instance. The moved instance is a valid, but unspecified 229 * %multiset. 230 */ 231 multiset(multiset&&) = default; 232 233 /** 234 * @brief Builds a %multiset from an initializer_list. 235 * @param __l An initializer_list. 236 * @param __comp A comparison functor. 237 * @param __a An allocator object. 238 * 239 * Create a %multiset consisting of copies of the elements from 240 * the list. This is linear in N if the list is already sorted, 241 * and NlogN otherwise (where N is @a __l.size()). 242 */ 243 multiset(initializer_list<value_type> __l, 244 const _Compare& __comp = _Compare(), 245 const allocator_type& __a = allocator_type()) 246 : _M_t(__comp, _Key_alloc_type(__a)) 247 { _M_t._M_insert_range_equal(__l.begin(), __l.end()); } 248 249 /// Allocator-extended default constructor. 250 explicit 251 multiset(const allocator_type& __a) 252 : _M_t(_Key_alloc_type(__a)) { } 253 254 /// Allocator-extended copy constructor. 255 multiset(const multiset& __m, 256 const __type_identity_t<allocator_type>& __a) 257 : _M_t(__m._M_t, _Key_alloc_type(__a)) { } 258 259 /// Allocator-extended move constructor. 260 multiset(multiset&& __m, const __type_identity_t<allocator_type>& __a) 261 noexcept(is_nothrow_copy_constructible<_Compare>::value 262 && _Alloc_traits::_S_always_equal()) 263 : _M_t(std::move(__m._M_t), _Key_alloc_type(__a)) { } 264 265 /// Allocator-extended initialier-list constructor. 266 multiset(initializer_list<value_type> __l, const allocator_type& __a) 267 : _M_t(_Key_alloc_type(__a)) 268 { _M_t._M_insert_range_equal(__l.begin(), __l.end()); } 269 270 /// Allocator-extended range constructor. 271 template<typename _InputIterator> 272 multiset(_InputIterator __first, _InputIterator __last, 273 const allocator_type& __a) 274 : _M_t(_Key_alloc_type(__a)) 275 { _M_t._M_insert_range_equal(__first, __last); } 276 277 #if __glibcxx_containers_ranges // C++ >= 23 278 /** 279 * @brief Builds a %multiset from a range. 280 * @since C++23 281 */ 282 template<__detail::__container_compatible_range<_Key> _Rg> 283 multiset(from_range_t, _Rg&& __rg, 284 const _Compare& __comp, 285 const _Alloc& __a = _Alloc()) 286 : _M_t(__comp, _Key_alloc_type(__a)) 287 { insert_range(std::forward<_Rg>(__rg)); } 288 289 /// Allocator-extended range constructor. 290 template<__detail::__container_compatible_range<_Key> _Rg> 291 multiset(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc()) 292 : _M_t(_Key_alloc_type(__a)) 293 { insert_range(std::forward<_Rg>(__rg)); } 294 #endif 295 296 /** 297 * The dtor only erases the elements, and note that if the elements 298 * themselves are pointers, the pointed-to memory is not touched in any 299 * way. Managing the pointer is the user's responsibility. 300 */ 301 ~multiset() = default; 302 #endif 303 304 /** 305 * @brief %Multiset assignment operator. 306 * 307 * Whether the allocator is copied depends on the allocator traits. 308 */ 309 #if __cplusplus < 201103L 310 multiset& 311 operator=(const multiset& __x) 312 { 313 _M_t = __x._M_t; 314 return *this; 315 } 316 #else 317 multiset& 318 operator=(const multiset&) = default; 319 320 /// Move assignment operator. 321 multiset& 322 operator=(multiset&&) = default; 323 324 /** 325 * @brief %Multiset list assignment operator. 326 * @param __l An initializer_list. 327 * 328 * This function fills a %multiset with copies of the elements in the 329 * initializer list @a __l. 330 * 331 * Note that the assignment completely changes the %multiset and 332 * that the resulting %multiset's size is the same as the number 333 * of elements assigned. 334 */ 335 multiset& 336 operator=(initializer_list<value_type> __l) 337 { 338 _M_t._M_assign_equal(__l.begin(), __l.end()); 339 return *this; 340 } 341 #endif 342 343 // accessors: 344 345 /// Returns the comparison object. 346 key_compare 347 key_comp() const 348 { return _M_t.key_comp(); } 349 /// Returns the comparison object. 350 value_compare 351 value_comp() const 352 { return _M_t.key_comp(); } 353 /// Returns the memory allocation object. 354 allocator_type 355 get_allocator() const _GLIBCXX_NOEXCEPT 356 { return allocator_type(_M_t.get_allocator()); } 357 358 /** 359 * Returns a read-only (constant) iterator that points to the first 360 * element in the %multiset. Iteration is done in ascending order 361 * according to the keys. 362 */ 363 iterator 364 begin() const _GLIBCXX_NOEXCEPT 365 { return _M_t.begin(); } 366 367 /** 368 * Returns a read-only (constant) iterator that points one past the last 369 * element in the %multiset. Iteration is done in ascending order 370 * according to the keys. 371 */ 372 iterator 373 end() const _GLIBCXX_NOEXCEPT 374 { return _M_t.end(); } 375 376 /** 377 * Returns a read-only (constant) reverse iterator that points to the 378 * last element in the %multiset. Iteration is done in descending order 379 * according to the keys. 380 */ 381 reverse_iterator 382 rbegin() const _GLIBCXX_NOEXCEPT 383 { return _M_t.rbegin(); } 384 385 /** 386 * Returns a read-only (constant) reverse iterator that points to the 387 * last element in the %multiset. Iteration is done in descending order 388 * according to the keys. 389 */ 390 reverse_iterator 391 rend() const _GLIBCXX_NOEXCEPT 392 { return _M_t.rend(); } 393 394 #if __cplusplus >= 201103L 395 /** 396 * Returns a read-only (constant) iterator that points to the first 397 * element in the %multiset. Iteration is done in ascending order 398 * according to the keys. 399 */ 400 iterator 401 cbegin() const noexcept 402 { return _M_t.begin(); } 403 404 /** 405 * Returns a read-only (constant) iterator that points one past the last 406 * element in the %multiset. Iteration is done in ascending order 407 * according to the keys. 408 */ 409 iterator 410 cend() const noexcept 411 { return _M_t.end(); } 412 413 /** 414 * Returns a read-only (constant) reverse iterator that points to the 415 * last element in the %multiset. Iteration is done in descending order 416 * according to the keys. 417 */ 418 reverse_iterator 419 crbegin() const noexcept 420 { return _M_t.rbegin(); } 421 422 /** 423 * Returns a read-only (constant) reverse iterator that points to the 424 * last element in the %multiset. Iteration is done in descending order 425 * according to the keys. 426 */ 427 reverse_iterator 428 crend() const noexcept 429 { return _M_t.rend(); } 430 #endif 431 432 /// Returns true if the %set is empty. 433 _GLIBCXX_NODISCARD bool 434 empty() const _GLIBCXX_NOEXCEPT 435 { return _M_t.empty(); } 436 437 /// Returns the size of the %set. 438 size_type 439 size() const _GLIBCXX_NOEXCEPT 440 { return _M_t.size(); } 441 442 /// Returns the maximum size of the %set. 443 size_type 444 max_size() const _GLIBCXX_NOEXCEPT 445 { return _M_t.max_size(); } 446 447 /** 448 * @brief Swaps data with another %multiset. 449 * @param __x A %multiset of the same element and allocator types. 450 * 451 * This exchanges the elements between two multisets in constant time. 452 * (It is only swapping a pointer, an integer, and an instance of the @c 453 * Compare type (which itself is often stateless and empty), so it should 454 * be quite fast.) 455 * Note that the global std::swap() function is specialized such that 456 * std::swap(s1,s2) will feed to this function. 457 * 458 * Whether the allocators are swapped depends on the allocator traits. 459 */ 460 void 461 swap(multiset& __x) 462 _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value) 463 { _M_t.swap(__x._M_t); } 464 465 // insert/erase 466 #if __cplusplus >= 201103L 467 /** 468 * @brief Builds and inserts an element into the %multiset. 469 * @param __args Arguments used to generate the element instance to be 470 * inserted. 471 * @return An iterator that points to the inserted element. 472 * 473 * This function inserts an element into the %multiset. Contrary 474 * to a std::set the %multiset does not rely on unique keys and thus 475 * multiple copies of the same element can be inserted. 476 * 477 * Insertion requires logarithmic time. 478 */ 479 template<typename... _Args> 480 iterator 481 emplace(_Args&&... __args) 482 { return _M_t._M_emplace_equal(std::forward<_Args>(__args)...); } 483 484 /** 485 * @brief Builds and inserts an element into the %multiset. 486 * @param __pos An iterator that serves as a hint as to where the 487 * element should be inserted. 488 * @param __args Arguments used to generate the element instance to be 489 * inserted. 490 * @return An iterator that points to the inserted element. 491 * 492 * This function inserts an element into the %multiset. Contrary 493 * to a std::set the %multiset does not rely on unique keys and thus 494 * multiple copies of the same element can be inserted. 495 * 496 * Note that the first parameter is only a hint and can potentially 497 * improve the performance of the insertion process. A bad hint would 498 * cause no gains in efficiency. 499 * 500 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints 501 * for more on @a hinting. 502 * 503 * Insertion requires logarithmic time (if the hint is not taken). 504 */ 505 template<typename... _Args> 506 iterator 507 emplace_hint(const_iterator __pos, _Args&&... __args) 508 { 509 return _M_t._M_emplace_hint_equal(__pos, 510 std::forward<_Args>(__args)...); 511 } 512 #endif 513 514 /** 515 * @brief Inserts an element into the %multiset. 516 * @param __x Element to be inserted. 517 * @return An iterator that points to the inserted element. 518 * 519 * This function inserts an element into the %multiset. Contrary 520 * to a std::set the %multiset does not rely on unique keys and thus 521 * multiple copies of the same element can be inserted. 522 * 523 * Insertion requires logarithmic time. 524 */ 525 iterator 526 insert(const value_type& __x) 527 { return _M_t._M_insert_equal(__x); } 528 529 #if __cplusplus >= 201103L 530 iterator 531 insert(value_type&& __x) 532 { return _M_t._M_insert_equal(std::move(__x)); } 533 #endif 534 535 /** 536 * @brief Inserts an element into the %multiset. 537 * @param __position An iterator that serves as a hint as to where the 538 * element should be inserted. 539 * @param __x Element to be inserted. 540 * @return An iterator that points to the inserted element. 541 * 542 * This function inserts an element into the %multiset. Contrary 543 * to a std::set the %multiset does not rely on unique keys and thus 544 * multiple copies of the same element can be inserted. 545 * 546 * Note that the first parameter is only a hint and can potentially 547 * improve the performance of the insertion process. A bad hint would 548 * cause no gains in efficiency. 549 * 550 * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints 551 * for more on @a hinting. 552 * 553 * Insertion requires logarithmic time (if the hint is not taken). 554 */ 555 iterator 556 insert(const_iterator __position, const value_type& __x) 557 { return _M_t._M_insert_equal_(__position, __x); } 558 559 #if __cplusplus >= 201103L 560 iterator 561 insert(const_iterator __position, value_type&& __x) 562 { return _M_t._M_insert_equal_(__position, std::move(__x)); } 563 #endif 564 565 /** 566 * @brief A template function that tries to insert a range of elements. 567 * @param __first Iterator pointing to the start of the range to be 568 * inserted. 569 * @param __last Iterator pointing to the end of the range. 570 * 571 * Complexity similar to that of the range constructor. 572 */ 573 template<typename _InputIterator> 574 void 575 insert(_InputIterator __first, _InputIterator __last) 576 { _M_t._M_insert_range_equal(__first, __last); } 577 578 #if __cplusplus >= 201103L 579 /** 580 * @brief Attempts to insert a list of elements into the %multiset. 581 * @param __l A std::initializer_list<value_type> of elements 582 * to be inserted. 583 * 584 * Complexity similar to that of the range constructor. 585 */ 586 void 587 insert(initializer_list<value_type> __l) 588 { this->insert(__l.begin(), __l.end()); } 589 #endif 590 591 #if __glibcxx_containers_ranges // C++ >= 23 592 /** 593 * @brief Inserts a range of elements. 594 * @since C++23 595 * @param __rg An input range of elements that can be converted to 596 * the set's value type. 597 */ 598 template<__detail::__container_compatible_range<_Key> _Rg> 599 void 600 insert_range(_Rg&& __rg) 601 { 602 auto __first = ranges::begin(__rg); 603 const auto __last = ranges::end(__rg); 604 for (; __first != __last; ++__first) 605 _M_t._M_emplace_equal(*__first); 606 } 607 #endif 608 609 610 #ifdef __glibcxx_node_extract // >= C++17 611 /// Extract a node. 612 node_type 613 extract(const_iterator __pos) 614 { 615 __glibcxx_assert(__pos != end()); 616 return _M_t.extract(__pos); 617 } 618 619 /// Extract a node. 620 node_type 621 extract(const key_type& __x) 622 { return _M_t.extract(__x); } 623 624 /// Re-insert an extracted node. 625 iterator 626 insert(node_type&& __nh) 627 { return _M_t._M_reinsert_node_equal(std::move(__nh)); } 628 629 /// Re-insert an extracted node. 630 iterator 631 insert(const_iterator __hint, node_type&& __nh) 632 { return _M_t._M_reinsert_node_hint_equal(__hint, std::move(__nh)); } 633 634 template<typename, typename> 635 friend struct std::_Rb_tree_merge_helper; 636 637 template<typename _Compare1> 638 void 639 merge(multiset<_Key, _Compare1, _Alloc>& __source) 640 { 641 using _Merge_helper = _Rb_tree_merge_helper<multiset, _Compare1>; 642 _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source)); 643 } 644 645 template<typename _Compare1> 646 void 647 merge(multiset<_Key, _Compare1, _Alloc>&& __source) 648 { merge(__source); } 649 650 template<typename _Compare1> 651 void 652 merge(set<_Key, _Compare1, _Alloc>& __source) 653 { 654 using _Merge_helper = _Rb_tree_merge_helper<multiset, _Compare1>; 655 _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source)); 656 } 657 658 template<typename _Compare1> 659 void 660 merge(set<_Key, _Compare1, _Alloc>&& __source) 661 { merge(__source); } 662 #endif // C++17 663 664 #if __cplusplus >= 201103L 665 // _GLIBCXX_RESOLVE_LIB_DEFECTS 666 // DR 130. Associative erase should return an iterator. 667 /** 668 * @brief Erases an element from a %multiset. 669 * @param __position An iterator pointing to the element to be erased. 670 * @return An iterator pointing to the element immediately following 671 * @a position prior to the element being erased. If no such 672 * element exists, end() is returned. 673 * 674 * This function erases an element, pointed to by the given iterator, 675 * from a %multiset. Note that this function only erases the element, 676 * and that if the element is itself a pointer, the pointed-to memory is 677 * not touched in any way. Managing the pointer is the user's 678 * responsibility. 679 */ 680 _GLIBCXX_ABI_TAG_CXX11 681 iterator 682 erase(const_iterator __position) 683 { return _M_t.erase(__position); } 684 #else 685 /** 686 * @brief Erases an element from a %multiset. 687 * @param __position An iterator pointing to the element to be erased. 688 * 689 * This function erases an element, pointed to by the given iterator, 690 * from a %multiset. Note that this function only erases the element, 691 * and that if the element is itself a pointer, the pointed-to memory is 692 * not touched in any way. Managing the pointer is the user's 693 * responsibility. 694 */ 695 void 696 erase(iterator __position) 697 { _M_t.erase(__position); } 698 #endif 699 700 /** 701 * @brief Erases elements according to the provided key. 702 * @param __x Key of element to be erased. 703 * @return The number of elements erased. 704 * 705 * This function erases all elements located by the given key from a 706 * %multiset. 707 * Note that this function only erases the element, and that if 708 * the element is itself a pointer, the pointed-to memory is not touched 709 * in any way. Managing the pointer is the user's responsibility. 710 */ 711 size_type 712 erase(const key_type& __x) 713 { return _M_t.erase(__x); } 714 715 #if __cplusplus >= 201103L 716 // _GLIBCXX_RESOLVE_LIB_DEFECTS 717 // DR 130. Associative erase should return an iterator. 718 /** 719 * @brief Erases a [first,last) range of elements from a %multiset. 720 * @param __first Iterator pointing to the start of the range to be 721 * erased. 722 * @param __last Iterator pointing to the end of the range to 723 * be erased. 724 * @return The iterator @a last. 725 * 726 * This function erases a sequence of elements from a %multiset. 727 * Note that this function only erases the elements, and that if 728 * the elements themselves are pointers, the pointed-to memory is not 729 * touched in any way. Managing the pointer is the user's 730 * responsibility. 731 */ 732 _GLIBCXX_ABI_TAG_CXX11 733 iterator 734 erase(const_iterator __first, const_iterator __last) 735 { return _M_t.erase(__first, __last); } 736 #else 737 /** 738 * @brief Erases a [first,last) range of elements from a %multiset. 739 * @param first Iterator pointing to the start of the range to be 740 * erased. 741 * @param last Iterator pointing to the end of the range to be erased. 742 * 743 * This function erases a sequence of elements from a %multiset. 744 * Note that this function only erases the elements, and that if 745 * the elements themselves are pointers, the pointed-to memory is not 746 * touched in any way. Managing the pointer is the user's 747 * responsibility. 748 */ 749 void 750 erase(iterator __first, iterator __last) 751 { _M_t.erase(__first, __last); } 752 #endif 753 754 /** 755 * Erases all elements in a %multiset. Note that this function only 756 * erases the elements, and that if the elements themselves are pointers, 757 * the pointed-to memory is not touched in any way. Managing the pointer 758 * is the user's responsibility. 759 */ 760 void 761 clear() _GLIBCXX_NOEXCEPT 762 { _M_t.clear(); } 763 764 // multiset operations: 765 766 ///@{ 767 /** 768 * @brief Finds the number of elements with given key. 769 * @param __x Key of elements to be located. 770 * @return Number of elements with specified key. 771 */ 772 size_type 773 count(const key_type& __x) const 774 { return _M_t.count(__x); } 775 776 #if __cplusplus > 201103L 777 template<typename _Kt> 778 auto 779 count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x)) 780 { return _M_t._M_count_tr(__x); } 781 #endif 782 ///@} 783 784 #if __cplusplus > 201703L 785 ///@{ 786 /** 787 * @brief Finds whether an element with the given key exists. 788 * @param __x Key of elements to be located. 789 * @return True if there is any element with the specified key. 790 */ 791 bool 792 contains(const key_type& __x) const 793 { return _M_t.find(__x) != _M_t.end(); } 794 795 template<typename _Kt> 796 auto 797 contains(const _Kt& __x) const 798 -> decltype(_M_t._M_find_tr(__x), void(), true) 799 { return _M_t._M_find_tr(__x) != _M_t.end(); } 800 ///@} 801 #endif 802 803 // _GLIBCXX_RESOLVE_LIB_DEFECTS 804 // 214. set::find() missing const overload 805 ///@{ 806 /** 807 * @brief Tries to locate an element in a %set. 808 * @param __x Element to be located. 809 * @return Iterator pointing to sought-after element, or end() if not 810 * found. 811 * 812 * This function takes a key and tries to locate the element with which 813 * the key matches. If successful the function returns an iterator 814 * pointing to the sought after element. If unsuccessful it returns the 815 * past-the-end ( @c end() ) iterator. 816 */ 817 iterator 818 find(const key_type& __x) 819 { return _M_t.find(__x); } 820 821 const_iterator 822 find(const key_type& __x) const 823 { return _M_t.find(__x); } 824 825 #if __cplusplus > 201103L 826 template<typename _Kt> 827 auto 828 find(const _Kt& __x) 829 -> decltype(iterator{_M_t._M_find_tr(__x)}) 830 { return iterator{_M_t._M_find_tr(__x)}; } 831 832 template<typename _Kt> 833 auto 834 find(const _Kt& __x) const 835 -> decltype(const_iterator{_M_t._M_find_tr(__x)}) 836 { return const_iterator{_M_t._M_find_tr(__x)}; } 837 #endif 838 ///@} 839 840 ///@{ 841 /** 842 * @brief Finds the beginning of a subsequence matching given key. 843 * @param __x Key to be located. 844 * @return Iterator pointing to first element equal to or greater 845 * than key, or end(). 846 * 847 * This function returns the first element of a subsequence of elements 848 * that matches the given key. If unsuccessful it returns an iterator 849 * pointing to the first element that has a greater value than given key 850 * or end() if no such element exists. 851 */ 852 iterator 853 lower_bound(const key_type& __x) 854 { return _M_t.lower_bound(__x); } 855 856 const_iterator 857 lower_bound(const key_type& __x) const 858 { return _M_t.lower_bound(__x); } 859 860 #if __cplusplus > 201103L 861 template<typename _Kt> 862 auto 863 lower_bound(const _Kt& __x) 864 -> decltype(iterator(_M_t._M_lower_bound_tr(__x))) 865 { return iterator(_M_t._M_lower_bound_tr(__x)); } 866 867 template<typename _Kt> 868 auto 869 lower_bound(const _Kt& __x) const 870 -> decltype(iterator(_M_t._M_lower_bound_tr(__x))) 871 { return iterator(_M_t._M_lower_bound_tr(__x)); } 872 #endif 873 ///@} 874 875 ///@{ 876 /** 877 * @brief Finds the end of a subsequence matching given key. 878 * @param __x Key to be located. 879 * @return Iterator pointing to the first element 880 * greater than key, or end(). 881 */ 882 iterator 883 upper_bound(const key_type& __x) 884 { return _M_t.upper_bound(__x); } 885 886 const_iterator 887 upper_bound(const key_type& __x) const 888 { return _M_t.upper_bound(__x); } 889 890 #if __cplusplus > 201103L 891 template<typename _Kt> 892 auto 893 upper_bound(const _Kt& __x) 894 -> decltype(iterator(_M_t._M_upper_bound_tr(__x))) 895 { return iterator(_M_t._M_upper_bound_tr(__x)); } 896 897 template<typename _Kt> 898 auto 899 upper_bound(const _Kt& __x) const 900 -> decltype(iterator(_M_t._M_upper_bound_tr(__x))) 901 { return iterator(_M_t._M_upper_bound_tr(__x)); } 902 #endif 903 ///@} 904 905 ///@{ 906 /** 907 * @brief Finds a subsequence matching given key. 908 * @param __x Key to be located. 909 * @return Pair of iterators that possibly points to the subsequence 910 * matching given key. 911 * 912 * This function is equivalent to 913 * @code 914 * std::make_pair(c.lower_bound(val), 915 * c.upper_bound(val)) 916 * @endcode 917 * (but is faster than making the calls separately). 918 * 919 * This function probably only makes sense for multisets. 920 */ 921 std::pair<iterator, iterator> 922 equal_range(const key_type& __x) 923 { return _M_t.equal_range(__x); } 924 925 std::pair<const_iterator, const_iterator> 926 equal_range(const key_type& __x) const 927 { return _M_t.equal_range(__x); } 928 929 #if __cplusplus > 201103L 930 template<typename _Kt> 931 auto 932 equal_range(const _Kt& __x) 933 -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x))) 934 { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); } 935 936 template<typename _Kt> 937 auto 938 equal_range(const _Kt& __x) const 939 -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x))) 940 { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); } 941 #endif 942 ///@} 943 944 template<typename _K1, typename _C1, typename _A1> 945 friend bool 946 operator==(const multiset<_K1, _C1, _A1>&, 947 const multiset<_K1, _C1, _A1>&); 948 949 #if __cpp_lib_three_way_comparison 950 template<typename _K1, typename _C1, typename _A1> 951 friend __detail::__synth3way_t<_K1> 952 operator<=>(const multiset<_K1, _C1, _A1>&, 953 const multiset<_K1, _C1, _A1>&); 954 #else 955 template<typename _K1, typename _C1, typename _A1> 956 friend bool 957 operator< (const multiset<_K1, _C1, _A1>&, 958 const multiset<_K1, _C1, _A1>&); 959 #endif 960 }; 961 962 #if __cpp_deduction_guides >= 201606 963 964 template<typename _InputIterator, 965 typename _Compare = 966 less<typename iterator_traits<_InputIterator>::value_type>, 967 typename _Allocator = 968 allocator<typename iterator_traits<_InputIterator>::value_type>, 969 typename = _RequireInputIter<_InputIterator>, 970 typename = _RequireNotAllocator<_Compare>, 971 typename = _RequireAllocator<_Allocator>> 972 multiset(_InputIterator, _InputIterator, 973 _Compare = _Compare(), _Allocator = _Allocator()) 974 -> multiset<typename iterator_traits<_InputIterator>::value_type, 975 _Compare, _Allocator>; 976 977 template<typename _Key, 978 typename _Compare = less<_Key>, 979 typename _Allocator = allocator<_Key>, 980 typename = _RequireNotAllocator<_Compare>, 981 typename = _RequireAllocator<_Allocator>> 982 multiset(initializer_list<_Key>, 983 _Compare = _Compare(), _Allocator = _Allocator()) 984 -> multiset<_Key, _Compare, _Allocator>; 985 986 template<typename _InputIterator, typename _Allocator, 987 typename = _RequireInputIter<_InputIterator>, 988 typename = _RequireAllocator<_Allocator>> 989 multiset(_InputIterator, _InputIterator, _Allocator) 990 -> multiset<typename iterator_traits<_InputIterator>::value_type, 991 less<typename iterator_traits<_InputIterator>::value_type>, 992 _Allocator>; 993 994 template<typename _Key, typename _Allocator, 995 typename = _RequireAllocator<_Allocator>> 996 multiset(initializer_list<_Key>, _Allocator) 997 -> multiset<_Key, less<_Key>, _Allocator>; 998 999 #if __glibcxx_containers_ranges // C++ >= 23 1000 template<ranges::input_range _Rg, 1001 __not_allocator_like _Compare = less<ranges::range_value_t<_Rg>>, 1002 __allocator_like _Alloc = std::allocator<ranges::range_value_t<_Rg>>> 1003 multiset(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc = _Alloc()) 1004 -> multiset<ranges::range_value_t<_Rg>, _Compare, _Alloc>; 1005 1006 template<ranges::input_range _Rg, __allocator_like _Alloc> 1007 multiset(from_range_t, _Rg&&, _Alloc) 1008 -> multiset<ranges::range_value_t<_Rg>, less<ranges::range_value_t<_Rg>>, _Alloc>; 1009 #endif 1010 #endif // deduction guides 1011 1012 /** 1013 * @brief Multiset equality comparison. 1014 * @param __x A %multiset. 1015 * @param __y A %multiset of the same type as @a __x. 1016 * @return True iff the size and elements of the multisets are equal. 1017 * 1018 * This is an equivalence relation. It is linear in the size of the 1019 * multisets. 1020 * Multisets are considered equivalent if their sizes are equal, and if 1021 * corresponding elements compare equal. 1022 */ 1023 template<typename _Key, typename _Compare, typename _Alloc> 1024 inline bool 1025 operator==(const multiset<_Key, _Compare, _Alloc>& __x, 1026 const multiset<_Key, _Compare, _Alloc>& __y) 1027 { return __x._M_t == __y._M_t; } 1028 1029 #if __cpp_lib_three_way_comparison 1030 /** 1031 * @brief Multiset ordering relation. 1032 * @param __x A `multiset`. 1033 * @param __y A `multiset` of the same type as `x`. 1034 * @return A value indicating whether `__x` is less than, equal to, 1035 * greater than, or incomparable with `__y`. 1036 * 1037 * This is a total ordering relation. It is linear in the size of the 1038 * maps. The elements must be comparable with @c <. 1039 * 1040 * See `std::lexicographical_compare_three_way()` for how the determination 1041 * is made. This operator is used to synthesize relational operators like 1042 * `<` and `>=` etc. 1043 */ 1044 template<typename _Key, typename _Compare, typename _Alloc> 1045 inline __detail::__synth3way_t<_Key> 1046 operator<=>(const multiset<_Key, _Compare, _Alloc>& __x, 1047 const multiset<_Key, _Compare, _Alloc>& __y) 1048 { return __x._M_t <=> __y._M_t; } 1049 #else 1050 /** 1051 * @brief Multiset ordering relation. 1052 * @param __x A %multiset. 1053 * @param __y A %multiset of the same type as @a __x. 1054 * @return True iff @a __x is lexicographically less than @a __y. 1055 * 1056 * This is a total ordering relation. It is linear in the size of the 1057 * sets. The elements must be comparable with @c <. 1058 * 1059 * See std::lexicographical_compare() for how the determination is made. 1060 */ 1061 template<typename _Key, typename _Compare, typename _Alloc> 1062 inline bool 1063 operator<(const multiset<_Key, _Compare, _Alloc>& __x, 1064 const multiset<_Key, _Compare, _Alloc>& __y) 1065 { return __x._M_t < __y._M_t; } 1066 1067 /// Returns !(x == y). 1068 template<typename _Key, typename _Compare, typename _Alloc> 1069 inline bool 1070 operator!=(const multiset<_Key, _Compare, _Alloc>& __x, 1071 const multiset<_Key, _Compare, _Alloc>& __y) 1072 { return !(__x == __y); } 1073 1074 /// Returns y < x. 1075 template<typename _Key, typename _Compare, typename _Alloc> 1076 inline bool 1077 operator>(const multiset<_Key,_Compare,_Alloc>& __x, 1078 const multiset<_Key,_Compare,_Alloc>& __y) 1079 { return __y < __x; } 1080 1081 /// Returns !(y < x) 1082 template<typename _Key, typename _Compare, typename _Alloc> 1083 inline bool 1084 operator<=(const multiset<_Key, _Compare, _Alloc>& __x, 1085 const multiset<_Key, _Compare, _Alloc>& __y) 1086 { return !(__y < __x); } 1087 1088 /// Returns !(x < y) 1089 template<typename _Key, typename _Compare, typename _Alloc> 1090 inline bool 1091 operator>=(const multiset<_Key, _Compare, _Alloc>& __x, 1092 const multiset<_Key, _Compare, _Alloc>& __y) 1093 { return !(__x < __y); } 1094 #endif // three-way comparison 1095 1096 /// See std::multiset::swap(). 1097 template<typename _Key, typename _Compare, typename _Alloc> 1098 inline void 1099 swap(multiset<_Key, _Compare, _Alloc>& __x, 1100 multiset<_Key, _Compare, _Alloc>& __y) 1101 _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) 1102 { __x.swap(__y); } 1103 1104 _GLIBCXX_END_NAMESPACE_CONTAINER 1105 1106 #if __cplusplus > 201402L 1107 // Allow std::multiset access to internals of compatible sets. 1108 template<typename _Val, typename _Cmp1, typename _Alloc, typename _Cmp2> 1109 struct 1110 _Rb_tree_merge_helper<_GLIBCXX_STD_C::multiset<_Val, _Cmp1, _Alloc>, 1111 _Cmp2> 1112 { 1113 private: 1114 friend class _GLIBCXX_STD_C::multiset<_Val, _Cmp1, _Alloc>; 1115 1116 static auto& 1117 _S_get_tree(_GLIBCXX_STD_C::set<_Val, _Cmp2, _Alloc>& __set) 1118 { return __set._M_t; } 1119 1120 static auto& 1121 _S_get_tree(_GLIBCXX_STD_C::multiset<_Val, _Cmp2, _Alloc>& __set) 1122 { return __set._M_t; } 1123 }; 1124 #endif // C++17 1125 1126 _GLIBCXX_END_NAMESPACE_VERSION 1127 } // namespace std 1128 1129 #endif /* _STL_MULTISET_H */