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