llvm-project
1501 строка · 63.3 Кб
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_SET
11#define _LIBCPP_SET
12
13/*
14
15set synopsis
16
17namespace std
18{
19
20template <class Key, class Compare = less<Key>,
21class Allocator = allocator<Key>>
22class set
23{
24public:
25// types:
26typedef Key key_type;
27typedef key_type value_type;
28typedef Compare key_compare;
29typedef key_compare value_compare;
30typedef Allocator allocator_type;
31typedef typename allocator_type::reference reference;
32typedef typename allocator_type::const_reference const_reference;
33typedef typename allocator_type::size_type size_type;
34typedef typename allocator_type::difference_type difference_type;
35typedef typename allocator_type::pointer pointer;
36typedef typename allocator_type::const_pointer const_pointer;
37
38typedef implementation-defined iterator;
39typedef implementation-defined const_iterator;
40typedef std::reverse_iterator<iterator> reverse_iterator;
41typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
42typedef unspecified node_type; // C++17
43typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
44
45// construct/copy/destroy:
46set()
47noexcept(
48is_nothrow_default_constructible<allocator_type>::value &&
49is_nothrow_default_constructible<key_compare>::value &&
50is_nothrow_copy_constructible<key_compare>::value);
51explicit set(const value_compare& comp);
52set(const value_compare& comp, const allocator_type& a);
53template <class InputIterator>
54set(InputIterator first, InputIterator last,
55const value_compare& comp = value_compare());
56template <class InputIterator>
57set(InputIterator first, InputIterator last, const value_compare& comp,
58const allocator_type& a);
59template<container-compatible-range<value_type> R>
60set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
61set(const set& s);
62set(set&& s)
63noexcept(
64is_nothrow_move_constructible<allocator_type>::value &&
65is_nothrow_move_constructible<key_compare>::value);
66explicit set(const allocator_type& a);
67set(const set& s, const allocator_type& a);
68set(set&& s, const allocator_type& a);
69set(initializer_list<value_type> il, const value_compare& comp = value_compare());
70set(initializer_list<value_type> il, const value_compare& comp,
71const allocator_type& a);
72template <class InputIterator>
73set(InputIterator first, InputIterator last, const allocator_type& a)
74: set(first, last, Compare(), a) {} // C++14
75template<container-compatible-range<value_type> R>
76set(from_range_t, R&& rg, const Allocator& a))
77: set(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
78set(initializer_list<value_type> il, const allocator_type& a)
79: set(il, Compare(), a) {} // C++14
80~set();
81
82set& operator=(const set& s);
83set& operator=(set&& s)
84noexcept(
85allocator_type::propagate_on_container_move_assignment::value &&
86is_nothrow_move_assignable<allocator_type>::value &&
87is_nothrow_move_assignable<key_compare>::value);
88set& operator=(initializer_list<value_type> il);
89
90// iterators:
91iterator begin() noexcept;
92const_iterator begin() const noexcept;
93iterator end() noexcept;
94const_iterator end() const noexcept;
95
96reverse_iterator rbegin() noexcept;
97const_reverse_iterator rbegin() const noexcept;
98reverse_iterator rend() noexcept;
99const_reverse_iterator rend() const noexcept;
100
101const_iterator cbegin() const noexcept;
102const_iterator cend() const noexcept;
103const_reverse_iterator crbegin() const noexcept;
104const_reverse_iterator crend() const noexcept;
105
106// capacity:
107bool empty() const noexcept;
108size_type size() const noexcept;
109size_type max_size() const noexcept;
110
111// modifiers:
112template <class... Args>
113pair<iterator, bool> emplace(Args&&... args);
114template <class... Args>
115iterator emplace_hint(const_iterator position, Args&&... args);
116pair<iterator,bool> insert(const value_type& v);
117pair<iterator,bool> insert(value_type&& v);
118iterator insert(const_iterator position, const value_type& v);
119iterator insert(const_iterator position, value_type&& v);
120template <class InputIterator>
121void insert(InputIterator first, InputIterator last);
122template<container-compatible-range<value_type> R>
123void insert_range(R&& rg); // C++23
124void insert(initializer_list<value_type> il);
125
126node_type extract(const_iterator position); // C++17
127node_type extract(const key_type& x); // C++17
128insert_return_type insert(node_type&& nh); // C++17
129iterator insert(const_iterator hint, node_type&& nh); // C++17
130
131iterator erase(const_iterator position);
132iterator erase(iterator position); // C++14
133size_type erase(const key_type& k);
134iterator erase(const_iterator first, const_iterator last);
135void clear() noexcept;
136
137template<class C2>
138void merge(set<Key, C2, Allocator>& source); // C++17
139template<class C2>
140void merge(set<Key, C2, Allocator>&& source); // C++17
141template<class C2>
142void merge(multiset<Key, C2, Allocator>& source); // C++17
143template<class C2>
144void merge(multiset<Key, C2, Allocator>&& source); // C++17
145
146void swap(set& s)
147noexcept(
148__is_nothrow_swappable<key_compare>::value &&
149(!allocator_type::propagate_on_container_swap::value ||
150__is_nothrow_swappable<allocator_type>::value));
151
152// observers:
153allocator_type get_allocator() const noexcept;
154key_compare key_comp() const;
155value_compare value_comp() const;
156
157// set operations:
158iterator find(const key_type& k);
159const_iterator find(const key_type& k) const;
160template<typename K>
161iterator find(const K& x);
162template<typename K>
163const_iterator find(const K& x) const; // C++14
164
165template<typename K>
166size_type count(const K& x) const; // C++14
167size_type count(const key_type& k) const;
168
169bool contains(const key_type& x) const; // C++20
170template<class K> bool contains(const K& x) const; // C++20
171
172iterator lower_bound(const key_type& k);
173const_iterator lower_bound(const key_type& k) const;
174template<typename K>
175iterator lower_bound(const K& x); // C++14
176template<typename K>
177const_iterator lower_bound(const K& x) const; // C++14
178
179iterator upper_bound(const key_type& k);
180const_iterator upper_bound(const key_type& k) const;
181template<typename K>
182iterator upper_bound(const K& x); // C++14
183template<typename K>
184const_iterator upper_bound(const K& x) const; // C++14
185pair<iterator,iterator> equal_range(const key_type& k);
186pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
187template<typename K>
188pair<iterator,iterator> equal_range(const K& x); // C++14
189template<typename K>
190pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14
191};
192
193template <class InputIterator,
194class Compare = less<typename iterator_traits<InputIterator>::value_type>,
195class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
196set(InputIterator, InputIterator,
197Compare = Compare(), Allocator = Allocator())
198-> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17
199
200template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
201class Allocator = allocator<ranges::range_value_t<R>>>
202set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
203-> set<ranges::range_value_t<R>, Compare, Allocator>; // C++23
204
205template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
206set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
207-> set<Key, Compare, Allocator>; // C++17
208
209template<class InputIterator, class Allocator>
210set(InputIterator, InputIterator, Allocator)
211-> set<typename iterator_traits<InputIterator>::value_type,
212less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17
213
214template<ranges::input_range R, class Allocator>
215set(from_range_t, R&&, Allocator)
216-> set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>; // C++23
217
218template<class Key, class Allocator>
219set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>; // C++17
220
221template <class Key, class Compare, class Allocator>
222bool
223operator==(const set<Key, Compare, Allocator>& x,
224const set<Key, Compare, Allocator>& y);
225
226template <class Key, class Compare, class Allocator>
227bool
228operator< (const set<Key, Compare, Allocator>& x,
229const set<Key, Compare, Allocator>& y); // removed in C++20
230
231template <class Key, class Compare, class Allocator>
232bool
233operator!=(const set<Key, Compare, Allocator>& x,
234const set<Key, Compare, Allocator>& y); // removed in C++20
235
236template <class Key, class Compare, class Allocator>
237bool
238operator> (const set<Key, Compare, Allocator>& x,
239const set<Key, Compare, Allocator>& y); // removed in C++20
240
241template <class Key, class Compare, class Allocator>
242bool
243operator>=(const set<Key, Compare, Allocator>& x,
244const set<Key, Compare, Allocator>& y); // removed in C++20
245
246template <class Key, class Compare, class Allocator>
247bool
248operator<=(const set<Key, Compare, Allocator>& x,
249const set<Key, Compare, Allocator>& y); // removed in C++20
250
251template<class Key, class Compare, class Allocator>
252synth-three-way-result<Key> operator<=>(const set<Key, Compare, Allocator>& x,
253const set<Key, Compare, Allocator>& y); // since C++20
254
255// specialized algorithms:
256template <class Key, class Compare, class Allocator>
257void
258swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)
259noexcept(noexcept(x.swap(y)));
260
261template <class Key, class Compare, class Allocator, class Predicate>
262typename set<Key, Compare, Allocator>::size_type
263erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20
264
265template <class Key, class Compare = less<Key>,
266class Allocator = allocator<Key>>
267class multiset
268{
269public:
270// types:
271typedef Key key_type;
272typedef key_type value_type;
273typedef Compare key_compare;
274typedef key_compare value_compare;
275typedef Allocator allocator_type;
276typedef typename allocator_type::reference reference;
277typedef typename allocator_type::const_reference const_reference;
278typedef typename allocator_type::size_type size_type;
279typedef typename allocator_type::difference_type difference_type;
280typedef typename allocator_type::pointer pointer;
281typedef typename allocator_type::const_pointer const_pointer;
282
283typedef implementation-defined iterator;
284typedef implementation-defined const_iterator;
285typedef std::reverse_iterator<iterator> reverse_iterator;
286typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
287typedef unspecified node_type; // C++17
288
289// construct/copy/destroy:
290multiset()
291noexcept(
292is_nothrow_default_constructible<allocator_type>::value &&
293is_nothrow_default_constructible<key_compare>::value &&
294is_nothrow_copy_constructible<key_compare>::value);
295explicit multiset(const value_compare& comp);
296multiset(const value_compare& comp, const allocator_type& a);
297template <class InputIterator>
298multiset(InputIterator first, InputIterator last,
299const value_compare& comp = value_compare());
300template <class InputIterator>
301multiset(InputIterator first, InputIterator last,
302const value_compare& comp, const allocator_type& a);
303template<container-compatible-range<value_type> R>
304multiset(from_range_t, R&& rg,
305const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
306multiset(const multiset& s);
307multiset(multiset&& s)
308noexcept(
309is_nothrow_move_constructible<allocator_type>::value &&
310is_nothrow_move_constructible<key_compare>::value);
311explicit multiset(const allocator_type& a);
312multiset(const multiset& s, const allocator_type& a);
313multiset(multiset&& s, const allocator_type& a);
314multiset(initializer_list<value_type> il, const value_compare& comp = value_compare());
315multiset(initializer_list<value_type> il, const value_compare& comp,
316const allocator_type& a);
317template <class InputIterator>
318multiset(InputIterator first, InputIterator last, const allocator_type& a)
319: set(first, last, Compare(), a) {} // C++14
320template<container-compatible-range<value_type> R>
321multiset(from_range_t, R&& rg, const Allocator& a))
322: multiset(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
323multiset(initializer_list<value_type> il, const allocator_type& a)
324: set(il, Compare(), a) {} // C++14
325~multiset();
326
327multiset& operator=(const multiset& s);
328multiset& operator=(multiset&& s)
329noexcept(
330allocator_type::propagate_on_container_move_assignment::value &&
331is_nothrow_move_assignable<allocator_type>::value &&
332is_nothrow_move_assignable<key_compare>::value);
333multiset& operator=(initializer_list<value_type> il);
334
335// iterators:
336iterator begin() noexcept;
337const_iterator begin() const noexcept;
338iterator end() noexcept;
339const_iterator end() const noexcept;
340
341reverse_iterator rbegin() noexcept;
342const_reverse_iterator rbegin() const noexcept;
343reverse_iterator rend() noexcept;
344const_reverse_iterator rend() const noexcept;
345
346const_iterator cbegin() const noexcept;
347const_iterator cend() const noexcept;
348const_reverse_iterator crbegin() const noexcept;
349const_reverse_iterator crend() const noexcept;
350
351// capacity:
352bool empty() const noexcept;
353size_type size() const noexcept;
354size_type max_size() const noexcept;
355
356// modifiers:
357template <class... Args>
358iterator emplace(Args&&... args);
359template <class... Args>
360iterator emplace_hint(const_iterator position, Args&&... args);
361iterator insert(const value_type& v);
362iterator insert(value_type&& v);
363iterator insert(const_iterator position, const value_type& v);
364iterator insert(const_iterator position, value_type&& v);
365template <class InputIterator>
366void insert(InputIterator first, InputIterator last);
367template<container-compatible-range<value_type> R>
368void insert_range(R&& rg); // C++23
369void insert(initializer_list<value_type> il);
370
371node_type extract(const_iterator position); // C++17
372node_type extract(const key_type& x); // C++17
373iterator insert(node_type&& nh); // C++17
374iterator insert(const_iterator hint, node_type&& nh); // C++17
375
376iterator erase(const_iterator position);
377iterator erase(iterator position); // C++14
378size_type erase(const key_type& k);
379iterator erase(const_iterator first, const_iterator last);
380void clear() noexcept;
381
382template<class C2>
383void merge(multiset<Key, C2, Allocator>& source); // C++17
384template<class C2>
385void merge(multiset<Key, C2, Allocator>&& source); // C++17
386template<class C2>
387void merge(set<Key, C2, Allocator>& source); // C++17
388template<class C2>
389void merge(set<Key, C2, Allocator>&& source); // C++17
390
391void swap(multiset& s)
392noexcept(
393__is_nothrow_swappable<key_compare>::value &&
394(!allocator_type::propagate_on_container_swap::value ||
395__is_nothrow_swappable<allocator_type>::value));
396
397// observers:
398allocator_type get_allocator() const noexcept;
399key_compare key_comp() const;
400value_compare value_comp() const;
401
402// set operations:
403iterator find(const key_type& k);
404const_iterator find(const key_type& k) const;
405template<typename K>
406iterator find(const K& x);
407template<typename K>
408const_iterator find(const K& x) const; // C++14
409
410template<typename K>
411size_type count(const K& x) const; // C++14
412size_type count(const key_type& k) const;
413
414bool contains(const key_type& x) const; // C++20
415template<class K> bool contains(const K& x) const; // C++20
416
417iterator lower_bound(const key_type& k);
418const_iterator lower_bound(const key_type& k) const;
419template<typename K>
420iterator lower_bound(const K& x); // C++14
421template<typename K>
422const_iterator lower_bound(const K& x) const; // C++14
423
424iterator upper_bound(const key_type& k);
425const_iterator upper_bound(const key_type& k) const;
426template<typename K>
427iterator upper_bound(const K& x); // C++14
428template<typename K>
429const_iterator upper_bound(const K& x) const; // C++14
430
431pair<iterator,iterator> equal_range(const key_type& k);
432pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
433template<typename K>
434pair<iterator,iterator> equal_range(const K& x); // C++14
435template<typename K>
436pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14
437};
438
439template <class InputIterator,
440class Compare = less<typename iterator_traits<InputIterator>::value_type>,
441class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
442multiset(InputIterator, InputIterator,
443Compare = Compare(), Allocator = Allocator())
444-> multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17
445
446template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
447class Allocator = allocator<ranges::range_value_t<R>>>
448multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
449-> multiset<ranges::range_value_t<R>, Compare, Allocator>;
450
451template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
452multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
453-> multiset<Key, Compare, Allocator>; // C++17
454
455template<class InputIterator, class Allocator>
456multiset(InputIterator, InputIterator, Allocator)
457-> multiset<typename iterator_traits<InputIterator>::value_type,
458less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17
459
460template<ranges::input_range R, class Allocator>
461multiset(from_range_t, R&&, Allocator)
462-> multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>;
463
464template<class Key, class Allocator>
465multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>; // C++17
466
467template <class Key, class Compare, class Allocator>
468bool
469operator==(const multiset<Key, Compare, Allocator>& x,
470const multiset<Key, Compare, Allocator>& y);
471
472template <class Key, class Compare, class Allocator>
473bool
474operator< (const multiset<Key, Compare, Allocator>& x,
475const multiset<Key, Compare, Allocator>& y); // removed in C++20
476
477template <class Key, class Compare, class Allocator>
478bool
479operator!=(const multiset<Key, Compare, Allocator>& x,
480const multiset<Key, Compare, Allocator>& y); // removed in C++20
481
482template <class Key, class Compare, class Allocator>
483bool
484operator> (const multiset<Key, Compare, Allocator>& x,
485const multiset<Key, Compare, Allocator>& y); // removed in C++20
486
487template <class Key, class Compare, class Allocator>
488bool
489operator>=(const multiset<Key, Compare, Allocator>& x,
490const multiset<Key, Compare, Allocator>& y); // removed in C++20
491
492template <class Key, class Compare, class Allocator>
493bool
494operator<=(const multiset<Key, Compare, Allocator>& x,
495const multiset<Key, Compare, Allocator>& y); // removed in C++20
496
497template<class Key, class Compare, class Allocator>
498synth-three-way-result<Key> operator<=>(const multiset<Key, Compare, Allocator>& x,
499const multiset<Key, Compare, Allocator>& y); // since C++20
500
501// specialized algorithms:
502template <class Key, class Compare, class Allocator>
503void
504swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
505noexcept(noexcept(x.swap(y)));
506
507template <class Key, class Compare, class Allocator, class Predicate>
508typename multiset<Key, Compare, Allocator>::size_type
509erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
510
511} // std
512
513*/
514
515#include <__algorithm/equal.h>
516#include <__algorithm/lexicographical_compare.h>
517#include <__algorithm/lexicographical_compare_three_way.h>
518#include <__assert>
519#include <__config>
520#include <__functional/is_transparent.h>
521#include <__functional/operations.h>
522#include <__iterator/erase_if_container.h>
523#include <__iterator/iterator_traits.h>
524#include <__iterator/ranges_iterator_traits.h>
525#include <__iterator/reverse_iterator.h>
526#include <__memory/allocator.h>
527#include <__memory_resource/polymorphic_allocator.h>
528#include <__node_handle>
529#include <__ranges/concepts.h>
530#include <__ranges/container_compatible_range.h>
531#include <__ranges/from_range.h>
532#include <__tree>
533#include <__type_traits/is_allocator.h>
534#include <__utility/forward.h>
535#include <version>
536
537// standard-mandated includes
538
539// [iterator.range]
540#include <__iterator/access.h>
541#include <__iterator/data.h>
542#include <__iterator/empty.h>
543#include <__iterator/reverse_access.h>
544#include <__iterator/size.h>
545
546// [associative.set.syn]
547#include <compare>
548#include <initializer_list>
549
550#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
551# pragma GCC system_header
552#endif
553
554_LIBCPP_PUSH_MACROS
555#include <__undef_macros>
556
557_LIBCPP_BEGIN_NAMESPACE_STD
558
559template <class _Key, class _Compare, class _Allocator>
560class multiset;
561
562template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> >
563class _LIBCPP_TEMPLATE_VIS set {
564public:
565// types:
566typedef _Key key_type;
567typedef key_type value_type;
568typedef __type_identity_t<_Compare> key_compare;
569typedef key_compare value_compare;
570typedef __type_identity_t<_Allocator> allocator_type;
571typedef value_type& reference;
572typedef const value_type& const_reference;
573
574static_assert(is_same<typename allocator_type::value_type, value_type>::value,
575"Allocator::value_type must be same type as value_type");
576
577private:
578typedef __tree<value_type, value_compare, allocator_type> __base;
579typedef allocator_traits<allocator_type> __alloc_traits;
580
581static_assert(__check_valid_allocator<allocator_type>::value, "");
582
583__base __tree_;
584
585public:
586typedef typename __base::pointer pointer;
587typedef typename __base::const_pointer const_pointer;
588typedef typename __base::size_type size_type;
589typedef typename __base::difference_type difference_type;
590typedef typename __base::const_iterator iterator;
591typedef typename __base::const_iterator const_iterator;
592typedef std::reverse_iterator<iterator> reverse_iterator;
593typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
594
595#if _LIBCPP_STD_VER >= 17
596typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
597typedef __insert_return_type<iterator, node_type> insert_return_type;
598#endif
599
600template <class _Key2, class _Compare2, class _Alloc2>
601friend class _LIBCPP_TEMPLATE_VIS set;
602template <class _Key2, class _Compare2, class _Alloc2>
603friend class _LIBCPP_TEMPLATE_VIS multiset;
604
605_LIBCPP_HIDE_FROM_ABI set() _NOEXCEPT_(
606is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&
607is_nothrow_copy_constructible<key_compare>::value)
608: __tree_(value_compare()) {}
609
610_LIBCPP_HIDE_FROM_ABI explicit set(const value_compare& __comp) _NOEXCEPT_(
611is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_copy_constructible<key_compare>::value)
612: __tree_(__comp) {}
613
614_LIBCPP_HIDE_FROM_ABI explicit set(const value_compare& __comp, const allocator_type& __a) : __tree_(__comp, __a) {}
615template <class _InputIterator>
616_LIBCPP_HIDE_FROM_ABI set(_InputIterator __f, _InputIterator __l, const value_compare& __comp = value_compare())
617: __tree_(__comp) {
618insert(__f, __l);
619}
620
621template <class _InputIterator>
622_LIBCPP_HIDE_FROM_ABI
623set(_InputIterator __f, _InputIterator __l, const value_compare& __comp, const allocator_type& __a)
624: __tree_(__comp, __a) {
625insert(__f, __l);
626}
627
628#if _LIBCPP_STD_VER >= 23
629template <_ContainerCompatibleRange<value_type> _Range>
630_LIBCPP_HIDE_FROM_ABI
631set(from_range_t,
632_Range&& __range,
633const key_compare& __comp = key_compare(),
634const allocator_type& __a = allocator_type())
635: __tree_(__comp, __a) {
636insert_range(std::forward<_Range>(__range));
637}
638#endif
639
640#if _LIBCPP_STD_VER >= 14
641template <class _InputIterator>
642_LIBCPP_HIDE_FROM_ABI set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
643: set(__f, __l, key_compare(), __a) {}
644#endif
645
646#if _LIBCPP_STD_VER >= 23
647template <_ContainerCompatibleRange<value_type> _Range>
648_LIBCPP_HIDE_FROM_ABI set(from_range_t, _Range&& __range, const allocator_type& __a)
649: set(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
650#endif
651
652_LIBCPP_HIDE_FROM_ABI set(const set& __s) : __tree_(__s.__tree_) { insert(__s.begin(), __s.end()); }
653
654_LIBCPP_HIDE_FROM_ABI set& operator=(const set& __s) {
655__tree_ = __s.__tree_;
656return *this;
657}
658
659#ifndef _LIBCPP_CXX03_LANG
660_LIBCPP_HIDE_FROM_ABI set(set&& __s) noexcept(is_nothrow_move_constructible<__base>::value)
661: __tree_(std::move(__s.__tree_)) {}
662#endif // _LIBCPP_CXX03_LANG
663
664_LIBCPP_HIDE_FROM_ABI explicit set(const allocator_type& __a) : __tree_(__a) {}
665
666_LIBCPP_HIDE_FROM_ABI set(const set& __s, const allocator_type& __a) : __tree_(__s.__tree_.value_comp(), __a) {
667insert(__s.begin(), __s.end());
668}
669
670#ifndef _LIBCPP_CXX03_LANG
671_LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __a);
672
673_LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
674: __tree_(__comp) {
675insert(__il.begin(), __il.end());
676}
677
678_LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const value_compare& __comp, const allocator_type& __a)
679: __tree_(__comp, __a) {
680insert(__il.begin(), __il.end());
681}
682
683# if _LIBCPP_STD_VER >= 14
684_LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const allocator_type& __a)
685: set(__il, key_compare(), __a) {}
686# endif
687
688_LIBCPP_HIDE_FROM_ABI set& operator=(initializer_list<value_type> __il) {
689__tree_.__assign_unique(__il.begin(), __il.end());
690return *this;
691}
692
693_LIBCPP_HIDE_FROM_ABI set& operator=(set&& __s) noexcept(is_nothrow_move_assignable<__base>::value) {
694__tree_ = std::move(__s.__tree_);
695return *this;
696}
697#endif // _LIBCPP_CXX03_LANG
698
699_LIBCPP_HIDE_FROM_ABI ~set() { static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
700
701_LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
702_LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
703_LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
704_LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
705
706_LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
707_LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
708_LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
709_LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
710
711_LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
712_LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
713_LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
714_LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
715
716_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
717_LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
718_LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
719
720// modifiers:
721#ifndef _LIBCPP_CXX03_LANG
722template <class... _Args>
723_LIBCPP_HIDE_FROM_ABI pair<iterator, bool> emplace(_Args&&... __args) {
724return __tree_.__emplace_unique(std::forward<_Args>(__args)...);
725}
726template <class... _Args>
727_LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
728return __tree_.__emplace_hint_unique(__p, std::forward<_Args>(__args)...);
729}
730#endif // _LIBCPP_CXX03_LANG
731
732_LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__insert_unique(__v); }
733_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
734return __tree_.__insert_unique(__p, __v);
735}
736
737template <class _InputIterator>
738_LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
739for (const_iterator __e = cend(); __f != __l; ++__f)
740__tree_.__insert_unique(__e, *__f);
741}
742
743#if _LIBCPP_STD_VER >= 23
744template <_ContainerCompatibleRange<value_type> _Range>
745_LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
746const_iterator __end = cend();
747for (auto&& __element : __range) {
748__tree_.__insert_unique(__end, std::forward<decltype(__element)>(__element));
749}
750}
751#endif
752
753#ifndef _LIBCPP_CXX03_LANG
754_LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(value_type&& __v) {
755return __tree_.__insert_unique(std::move(__v));
756}
757
758_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
759return __tree_.__insert_unique(__p, std::move(__v));
760}
761
762_LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
763#endif // _LIBCPP_CXX03_LANG
764
765_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p); }
766_LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_unique(__k); }
767_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) { return __tree_.erase(__f, __l); }
768_LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }
769
770#if _LIBCPP_STD_VER >= 17
771_LIBCPP_HIDE_FROM_ABI insert_return_type insert(node_type&& __nh) {
772_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
773"node_type with incompatible allocator passed to set::insert()");
774return __tree_.template __node_handle_insert_unique< node_type, insert_return_type>(std::move(__nh));
775}
776_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {
777_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
778"node_type with incompatible allocator passed to set::insert()");
779return __tree_.template __node_handle_insert_unique<node_type>(__hint, std::move(__nh));
780}
781_LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
782return __tree_.template __node_handle_extract<node_type>(__key);
783}
784_LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
785return __tree_.template __node_handle_extract<node_type>(__it);
786}
787template <class _Compare2>
788_LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>& __source) {
789_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
790__source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
791__tree_.__node_handle_merge_unique(__source.__tree_);
792}
793template <class _Compare2>
794_LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>&& __source) {
795_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
796__source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
797__tree_.__node_handle_merge_unique(__source.__tree_);
798}
799template <class _Compare2>
800_LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>& __source) {
801_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
802__source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
803__tree_.__node_handle_merge_unique(__source.__tree_);
804}
805template <class _Compare2>
806_LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>&& __source) {
807_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
808__source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
809__tree_.__node_handle_merge_unique(__source.__tree_);
810}
811#endif
812
813_LIBCPP_HIDE_FROM_ABI void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) { __tree_.swap(__s.__tree_); }
814
815_LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
816_LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
817_LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
818
819// set operations:
820_LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
821_LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
822#if _LIBCPP_STD_VER >= 14
823template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
824_LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
825return __tree_.find(__k);
826}
827template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
828_LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
829return __tree_.find(__k);
830}
831#endif
832
833_LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_unique(__k); }
834#if _LIBCPP_STD_VER >= 14
835template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
836_LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
837return __tree_.__count_multi(__k);
838}
839#endif
840
841#if _LIBCPP_STD_VER >= 20
842_LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
843template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
844_LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
845return find(__k) != end();
846}
847#endif // _LIBCPP_STD_VER >= 20
848
849_LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
850_LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
851#if _LIBCPP_STD_VER >= 14
852template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
853_LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
854return __tree_.lower_bound(__k);
855}
856
857template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
858_LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
859return __tree_.lower_bound(__k);
860}
861#endif
862
863_LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
864_LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
865#if _LIBCPP_STD_VER >= 14
866template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
867_LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
868return __tree_.upper_bound(__k);
869}
870template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
871_LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
872return __tree_.upper_bound(__k);
873}
874#endif
875
876_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
877return __tree_.__equal_range_unique(__k);
878}
879_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
880return __tree_.__equal_range_unique(__k);
881}
882#if _LIBCPP_STD_VER >= 14
883template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
884_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
885return __tree_.__equal_range_multi(__k);
886}
887template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
888_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
889return __tree_.__equal_range_multi(__k);
890}
891#endif
892};
893
894#if _LIBCPP_STD_VER >= 17
895template <class _InputIterator,
896class _Compare = less<__iter_value_type<_InputIterator>>,
897class _Allocator = allocator<__iter_value_type<_InputIterator>>,
898class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
899class = enable_if_t<__is_allocator<_Allocator>::value, void>,
900class = enable_if_t<!__is_allocator<_Compare>::value, void>>
901set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
902-> set<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
903
904# if _LIBCPP_STD_VER >= 23
905template <ranges::input_range _Range,
906class _Compare = less<ranges::range_value_t<_Range>>,
907class _Allocator = allocator<ranges::range_value_t<_Range>>,
908class = enable_if_t<__is_allocator<_Allocator>::value, void>,
909class = enable_if_t<!__is_allocator<_Compare>::value, void>>
910set(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
911-> set<ranges::range_value_t<_Range>, _Compare, _Allocator>;
912# endif
913
914template <class _Key,
915class _Compare = less<_Key>,
916class _Allocator = allocator<_Key>,
917class = enable_if_t<!__is_allocator<_Compare>::value, void>,
918class = enable_if_t<__is_allocator<_Allocator>::value, void>>
919set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) -> set<_Key, _Compare, _Allocator>;
920
921template <class _InputIterator,
922class _Allocator,
923class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
924class = enable_if_t<__is_allocator<_Allocator>::value, void>>
925set(_InputIterator,
926_InputIterator,
927_Allocator) -> set<__iter_value_type<_InputIterator>, less<__iter_value_type<_InputIterator>>, _Allocator>;
928
929# if _LIBCPP_STD_VER >= 23
930template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
931set(from_range_t,
932_Range&&,
933_Allocator) -> set<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
934# endif
935
936template <class _Key, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
937set(initializer_list<_Key>, _Allocator) -> set<_Key, less<_Key>, _Allocator>;
938#endif
939
940#ifndef _LIBCPP_CXX03_LANG
941
942template <class _Key, class _Compare, class _Allocator>
943set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a) : __tree_(std::move(__s.__tree_), __a) {
944if (__a != __s.get_allocator()) {
945const_iterator __e = cend();
946while (!__s.empty())
947insert(__e, std::move(__s.__tree_.remove(__s.begin())->__value_));
948}
949}
950
951#endif // _LIBCPP_CXX03_LANG
952
953template <class _Key, class _Compare, class _Allocator>
954inline _LIBCPP_HIDE_FROM_ABI bool
955operator==(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
956return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
957}
958
959#if _LIBCPP_STD_VER <= 17
960
961template <class _Key, class _Compare, class _Allocator>
962inline _LIBCPP_HIDE_FROM_ABI bool
963operator<(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
964return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
965}
966
967template <class _Key, class _Compare, class _Allocator>
968inline _LIBCPP_HIDE_FROM_ABI bool
969operator!=(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
970return !(__x == __y);
971}
972
973template <class _Key, class _Compare, class _Allocator>
974inline _LIBCPP_HIDE_FROM_ABI bool
975operator>(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
976return __y < __x;
977}
978
979template <class _Key, class _Compare, class _Allocator>
980inline _LIBCPP_HIDE_FROM_ABI bool
981operator>=(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
982return !(__x < __y);
983}
984
985template <class _Key, class _Compare, class _Allocator>
986inline _LIBCPP_HIDE_FROM_ABI bool
987operator<=(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
988return !(__y < __x);
989}
990
991#else // _LIBCPP_STD_VER <= 17
992
993template <class _Key, class _Allocator>
994_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
995operator<=>(const set<_Key, _Allocator>& __x, const set<_Key, _Allocator>& __y) {
996return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
997}
998
999#endif // _LIBCPP_STD_VER <= 17
1000
1001// specialized algorithms:
1002template <class _Key, class _Compare, class _Allocator>
1003inline _LIBCPP_HIDE_FROM_ABI void swap(set<_Key, _Compare, _Allocator>& __x, set<_Key, _Compare, _Allocator>& __y)
1004_NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
1005__x.swap(__y);
1006}
1007
1008#if _LIBCPP_STD_VER >= 20
1009template <class _Key, class _Compare, class _Allocator, class _Predicate>
1010inline _LIBCPP_HIDE_FROM_ABI typename set<_Key, _Compare, _Allocator>::size_type
1011erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
1012return std::__libcpp_erase_if_container(__c, __pred);
1013}
1014#endif
1015
1016template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> >
1017class _LIBCPP_TEMPLATE_VIS multiset {
1018public:
1019// types:
1020typedef _Key key_type;
1021typedef key_type value_type;
1022typedef __type_identity_t<_Compare> key_compare;
1023typedef key_compare value_compare;
1024typedef __type_identity_t<_Allocator> allocator_type;
1025typedef value_type& reference;
1026typedef const value_type& const_reference;
1027
1028static_assert(is_same<typename allocator_type::value_type, value_type>::value,
1029"Allocator::value_type must be same type as value_type");
1030
1031private:
1032typedef __tree<value_type, value_compare, allocator_type> __base;
1033typedef allocator_traits<allocator_type> __alloc_traits;
1034
1035static_assert(__check_valid_allocator<allocator_type>::value, "");
1036
1037__base __tree_;
1038
1039public:
1040typedef typename __base::pointer pointer;
1041typedef typename __base::const_pointer const_pointer;
1042typedef typename __base::size_type size_type;
1043typedef typename __base::difference_type difference_type;
1044typedef typename __base::const_iterator iterator;
1045typedef typename __base::const_iterator const_iterator;
1046typedef std::reverse_iterator<iterator> reverse_iterator;
1047typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1048
1049#if _LIBCPP_STD_VER >= 17
1050typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
1051#endif
1052
1053template <class _Key2, class _Compare2, class _Alloc2>
1054friend class _LIBCPP_TEMPLATE_VIS set;
1055template <class _Key2, class _Compare2, class _Alloc2>
1056friend class _LIBCPP_TEMPLATE_VIS multiset;
1057
1058// construct/copy/destroy:
1059_LIBCPP_HIDE_FROM_ABI multiset() _NOEXCEPT_(
1060is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&
1061is_nothrow_copy_constructible<key_compare>::value)
1062: __tree_(value_compare()) {}
1063
1064_LIBCPP_HIDE_FROM_ABI explicit multiset(const value_compare& __comp) _NOEXCEPT_(
1065is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_copy_constructible<key_compare>::value)
1066: __tree_(__comp) {}
1067
1068_LIBCPP_HIDE_FROM_ABI explicit multiset(const value_compare& __comp, const allocator_type& __a)
1069: __tree_(__comp, __a) {}
1070template <class _InputIterator>
1071_LIBCPP_HIDE_FROM_ABI multiset(_InputIterator __f, _InputIterator __l, const value_compare& __comp = value_compare())
1072: __tree_(__comp) {
1073insert(__f, __l);
1074}
1075
1076#if _LIBCPP_STD_VER >= 14
1077template <class _InputIterator>
1078_LIBCPP_HIDE_FROM_ABI multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
1079: multiset(__f, __l, key_compare(), __a) {}
1080#endif
1081
1082template <class _InputIterator>
1083_LIBCPP_HIDE_FROM_ABI
1084multiset(_InputIterator __f, _InputIterator __l, const value_compare& __comp, const allocator_type& __a)
1085: __tree_(__comp, __a) {
1086insert(__f, __l);
1087}
1088
1089#if _LIBCPP_STD_VER >= 23
1090template <_ContainerCompatibleRange<value_type> _Range>
1091_LIBCPP_HIDE_FROM_ABI
1092multiset(from_range_t,
1093_Range&& __range,
1094const key_compare& __comp = key_compare(),
1095const allocator_type& __a = allocator_type())
1096: __tree_(__comp, __a) {
1097insert_range(std::forward<_Range>(__range));
1098}
1099
1100template <_ContainerCompatibleRange<value_type> _Range>
1101_LIBCPP_HIDE_FROM_ABI multiset(from_range_t, _Range&& __range, const allocator_type& __a)
1102: multiset(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
1103#endif
1104
1105_LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s)
1106: __tree_(__s.__tree_.value_comp(),
1107__alloc_traits::select_on_container_copy_construction(__s.__tree_.__alloc())) {
1108insert(__s.begin(), __s.end());
1109}
1110
1111_LIBCPP_HIDE_FROM_ABI multiset& operator=(const multiset& __s) {
1112__tree_ = __s.__tree_;
1113return *this;
1114}
1115
1116#ifndef _LIBCPP_CXX03_LANG
1117_LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s) noexcept(is_nothrow_move_constructible<__base>::value)
1118: __tree_(std::move(__s.__tree_)) {}
1119
1120_LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a);
1121#endif // _LIBCPP_CXX03_LANG
1122_LIBCPP_HIDE_FROM_ABI explicit multiset(const allocator_type& __a) : __tree_(__a) {}
1123_LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s, const allocator_type& __a)
1124: __tree_(__s.__tree_.value_comp(), __a) {
1125insert(__s.begin(), __s.end());
1126}
1127
1128#ifndef _LIBCPP_CXX03_LANG
1129_LIBCPP_HIDE_FROM_ABI multiset(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
1130: __tree_(__comp) {
1131insert(__il.begin(), __il.end());
1132}
1133
1134_LIBCPP_HIDE_FROM_ABI
1135multiset(initializer_list<value_type> __il, const value_compare& __comp, const allocator_type& __a)
1136: __tree_(__comp, __a) {
1137insert(__il.begin(), __il.end());
1138}
1139
1140# if _LIBCPP_STD_VER >= 14
1141_LIBCPP_HIDE_FROM_ABI multiset(initializer_list<value_type> __il, const allocator_type& __a)
1142: multiset(__il, key_compare(), __a) {}
1143# endif
1144
1145_LIBCPP_HIDE_FROM_ABI multiset& operator=(initializer_list<value_type> __il) {
1146__tree_.__assign_multi(__il.begin(), __il.end());
1147return *this;
1148}
1149
1150_LIBCPP_HIDE_FROM_ABI multiset& operator=(multiset&& __s) _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) {
1151__tree_ = std::move(__s.__tree_);
1152return *this;
1153}
1154#endif // _LIBCPP_CXX03_LANG
1155
1156_LIBCPP_HIDE_FROM_ABI ~multiset() { static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
1157
1158_LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1159_LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1160_LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1161_LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
1162
1163_LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1164_LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
1165_LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1166_LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
1167
1168_LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1169_LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1170_LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1171_LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
1172
1173_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
1174_LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1175_LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
1176
1177// modifiers:
1178#ifndef _LIBCPP_CXX03_LANG
1179template <class... _Args>
1180_LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {
1181return __tree_.__emplace_multi(std::forward<_Args>(__args)...);
1182}
1183template <class... _Args>
1184_LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
1185return __tree_.__emplace_hint_multi(__p, std::forward<_Args>(__args)...);
1186}
1187#endif // _LIBCPP_CXX03_LANG
1188
1189_LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __v) { return __tree_.__insert_multi(__v); }
1190_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
1191return __tree_.__insert_multi(__p, __v);
1192}
1193
1194template <class _InputIterator>
1195_LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
1196for (const_iterator __e = cend(); __f != __l; ++__f)
1197__tree_.__insert_multi(__e, *__f);
1198}
1199
1200#if _LIBCPP_STD_VER >= 23
1201template <_ContainerCompatibleRange<value_type> _Range>
1202_LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
1203const_iterator __end = cend();
1204for (auto&& __element : __range) {
1205__tree_.__insert_multi(__end, std::forward<decltype(__element)>(__element));
1206}
1207}
1208#endif
1209
1210#ifndef _LIBCPP_CXX03_LANG
1211_LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __v) { return __tree_.__insert_multi(std::move(__v)); }
1212
1213_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
1214return __tree_.__insert_multi(__p, std::move(__v));
1215}
1216
1217_LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
1218#endif // _LIBCPP_CXX03_LANG
1219
1220_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p); }
1221_LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_multi(__k); }
1222_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) { return __tree_.erase(__f, __l); }
1223_LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }
1224
1225#if _LIBCPP_STD_VER >= 17
1226_LIBCPP_HIDE_FROM_ABI iterator insert(node_type&& __nh) {
1227_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
1228"node_type with incompatible allocator passed to multiset::insert()");
1229return __tree_.template __node_handle_insert_multi<node_type>(std::move(__nh));
1230}
1231_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {
1232_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
1233"node_type with incompatible allocator passed to multiset::insert()");
1234return __tree_.template __node_handle_insert_multi<node_type>(__hint, std::move(__nh));
1235}
1236_LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1237return __tree_.template __node_handle_extract<node_type>(__key);
1238}
1239_LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1240return __tree_.template __node_handle_extract<node_type>(__it);
1241}
1242template <class _Compare2>
1243_LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>& __source) {
1244_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1245__source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
1246__tree_.__node_handle_merge_multi(__source.__tree_);
1247}
1248template <class _Compare2>
1249_LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>&& __source) {
1250_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1251__source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
1252__tree_.__node_handle_merge_multi(__source.__tree_);
1253}
1254template <class _Compare2>
1255_LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>& __source) {
1256_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1257__source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
1258__tree_.__node_handle_merge_multi(__source.__tree_);
1259}
1260template <class _Compare2>
1261_LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>&& __source) {
1262_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1263__source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
1264__tree_.__node_handle_merge_multi(__source.__tree_);
1265}
1266#endif
1267
1268_LIBCPP_HIDE_FROM_ABI void swap(multiset& __s) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) {
1269__tree_.swap(__s.__tree_);
1270}
1271
1272_LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
1273_LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
1274_LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
1275
1276// set operations:
1277_LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1278_LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
1279#if _LIBCPP_STD_VER >= 14
1280template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1281_LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1282return __tree_.find(__k);
1283}
1284template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1285_LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1286return __tree_.find(__k);
1287}
1288#endif
1289
1290_LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_multi(__k); }
1291#if _LIBCPP_STD_VER >= 14
1292template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1293_LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1294return __tree_.__count_multi(__k);
1295}
1296#endif
1297
1298#if _LIBCPP_STD_VER >= 20
1299_LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1300template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1301_LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1302return find(__k) != end();
1303}
1304#endif // _LIBCPP_STD_VER >= 20
1305
1306_LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
1307_LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
1308#if _LIBCPP_STD_VER >= 14
1309template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1310_LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1311return __tree_.lower_bound(__k);
1312}
1313
1314template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1315_LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1316return __tree_.lower_bound(__k);
1317}
1318#endif
1319
1320_LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
1321_LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
1322#if _LIBCPP_STD_VER >= 14
1323template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1324_LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1325return __tree_.upper_bound(__k);
1326}
1327template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1328_LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1329return __tree_.upper_bound(__k);
1330}
1331#endif
1332
1333_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1334return __tree_.__equal_range_multi(__k);
1335}
1336_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1337return __tree_.__equal_range_multi(__k);
1338}
1339#if _LIBCPP_STD_VER >= 14
1340template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1341_LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1342return __tree_.__equal_range_multi(__k);
1343}
1344template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1345_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1346return __tree_.__equal_range_multi(__k);
1347}
1348#endif
1349};
1350
1351#if _LIBCPP_STD_VER >= 17
1352template <class _InputIterator,
1353class _Compare = less<__iter_value_type<_InputIterator>>,
1354class _Allocator = allocator<__iter_value_type<_InputIterator>>,
1355class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1356class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1357class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1358multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
1359-> multiset<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
1360
1361# if _LIBCPP_STD_VER >= 23
1362template <ranges::input_range _Range,
1363class _Compare = less<ranges::range_value_t<_Range>>,
1364class _Allocator = allocator<ranges::range_value_t<_Range>>,
1365class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1366class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1367multiset(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
1368-> multiset<ranges::range_value_t<_Range>, _Compare, _Allocator>;
1369# endif
1370
1371template <class _Key,
1372class _Compare = less<_Key>,
1373class _Allocator = allocator<_Key>,
1374class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1375class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1376multiset(initializer_list<_Key>,
1377_Compare = _Compare(),
1378_Allocator = _Allocator()) -> multiset<_Key, _Compare, _Allocator>;
1379
1380template <class _InputIterator,
1381class _Allocator,
1382class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1383class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1384multiset(_InputIterator, _InputIterator, _Allocator)
1385-> multiset<__iter_value_type<_InputIterator>, less<__iter_value_type<_InputIterator>>, _Allocator>;
1386
1387# if _LIBCPP_STD_VER >= 23
1388template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1389multiset(from_range_t,
1390_Range&&,
1391_Allocator) -> multiset<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
1392# endif
1393
1394template <class _Key, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1395multiset(initializer_list<_Key>, _Allocator) -> multiset<_Key, less<_Key>, _Allocator>;
1396#endif
1397
1398#ifndef _LIBCPP_CXX03_LANG
1399
1400template <class _Key, class _Compare, class _Allocator>
1401multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a)
1402: __tree_(std::move(__s.__tree_), __a) {
1403if (__a != __s.get_allocator()) {
1404const_iterator __e = cend();
1405while (!__s.empty())
1406insert(__e, std::move(__s.__tree_.remove(__s.begin())->__value_));
1407}
1408}
1409
1410#endif // _LIBCPP_CXX03_LANG
1411
1412template <class _Key, class _Compare, class _Allocator>
1413inline _LIBCPP_HIDE_FROM_ABI bool
1414operator==(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1415return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
1416}
1417
1418#if _LIBCPP_STD_VER <= 17
1419
1420template <class _Key, class _Compare, class _Allocator>
1421inline _LIBCPP_HIDE_FROM_ABI bool
1422operator<(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1423return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1424}
1425
1426template <class _Key, class _Compare, class _Allocator>
1427inline _LIBCPP_HIDE_FROM_ABI bool
1428operator!=(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1429return !(__x == __y);
1430}
1431
1432template <class _Key, class _Compare, class _Allocator>
1433inline _LIBCPP_HIDE_FROM_ABI bool
1434operator>(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1435return __y < __x;
1436}
1437
1438template <class _Key, class _Compare, class _Allocator>
1439inline _LIBCPP_HIDE_FROM_ABI bool
1440operator>=(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1441return !(__x < __y);
1442}
1443
1444template <class _Key, class _Compare, class _Allocator>
1445inline _LIBCPP_HIDE_FROM_ABI bool
1446operator<=(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1447return !(__y < __x);
1448}
1449
1450#else // _LIBCPP_STD_VER <= 17
1451
1452template <class _Key, class _Allocator>
1453_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
1454operator<=>(const multiset<_Key, _Allocator>& __x, const multiset<_Key, _Allocator>& __y) {
1455return std::lexicographical_compare_three_way(
1456__x.begin(), __x.end(), __y.begin(), __y.end(), __synth_three_way);
1457}
1458
1459#endif // _LIBCPP_STD_VER <= 17
1460
1461template <class _Key, class _Compare, class _Allocator>
1462inline _LIBCPP_HIDE_FROM_ABI void
1463swap(multiset<_Key, _Compare, _Allocator>& __x, multiset<_Key, _Compare, _Allocator>& __y)
1464_NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
1465__x.swap(__y);
1466}
1467
1468#if _LIBCPP_STD_VER >= 20
1469template <class _Key, class _Compare, class _Allocator, class _Predicate>
1470inline _LIBCPP_HIDE_FROM_ABI typename multiset<_Key, _Compare, _Allocator>::size_type
1471erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
1472return std::__libcpp_erase_if_container(__c, __pred);
1473}
1474#endif
1475
1476_LIBCPP_END_NAMESPACE_STD
1477
1478#if _LIBCPP_STD_VER >= 17
1479_LIBCPP_BEGIN_NAMESPACE_STD
1480namespace pmr {
1481template <class _KeyT, class _CompareT = std::less<_KeyT>>
1482using set _LIBCPP_AVAILABILITY_PMR = std::set<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
1483
1484template <class _KeyT, class _CompareT = std::less<_KeyT>>
1485using multiset _LIBCPP_AVAILABILITY_PMR = std::multiset<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
1486} // namespace pmr
1487_LIBCPP_END_NAMESPACE_STD
1488#endif
1489
1490_LIBCPP_POP_MACROS
1491
1492#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1493# include <concepts>
1494# include <cstdlib>
1495# include <functional>
1496# include <iterator>
1497# include <stdexcept>
1498# include <type_traits>
1499#endif
1500
1501#endif // _LIBCPP_SET
1502