Warning, /include/c++/v1/set is written in an unsupported language. File is not indexed.
0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009
0010 #ifndef _LIBCPP_SET
0011 #define _LIBCPP_SET
0012
0013 /*
0014
0015 set synopsis
0016
0017 namespace std
0018 {
0019
0020 template <class Key, class Compare = less<Key>,
0021 class Allocator = allocator<Key>>
0022 class set
0023 {
0024 public:
0025 // types:
0026 typedef Key key_type;
0027 typedef key_type value_type;
0028 typedef Compare key_compare;
0029 typedef key_compare value_compare;
0030 typedef Allocator allocator_type;
0031 typedef typename allocator_type::reference reference;
0032 typedef typename allocator_type::const_reference const_reference;
0033 typedef typename allocator_type::size_type size_type;
0034 typedef typename allocator_type::difference_type difference_type;
0035 typedef typename allocator_type::pointer pointer;
0036 typedef typename allocator_type::const_pointer const_pointer;
0037
0038 typedef implementation-defined iterator;
0039 typedef implementation-defined const_iterator;
0040 typedef std::reverse_iterator<iterator> reverse_iterator;
0041 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0042 typedef unspecified node_type; // C++17
0043 typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
0044
0045 // construct/copy/destroy:
0046 set()
0047 noexcept(
0048 is_nothrow_default_constructible<allocator_type>::value &&
0049 is_nothrow_default_constructible<key_compare>::value &&
0050 is_nothrow_copy_constructible<key_compare>::value);
0051 explicit set(const value_compare& comp);
0052 set(const value_compare& comp, const allocator_type& a);
0053 template <class InputIterator>
0054 set(InputIterator first, InputIterator last,
0055 const value_compare& comp = value_compare());
0056 template <class InputIterator>
0057 set(InputIterator first, InputIterator last, const value_compare& comp,
0058 const allocator_type& a);
0059 template<container-compatible-range<value_type> R>
0060 set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
0061 set(const set& s);
0062 set(set&& s)
0063 noexcept(
0064 is_nothrow_move_constructible<allocator_type>::value &&
0065 is_nothrow_move_constructible<key_compare>::value);
0066 explicit set(const allocator_type& a);
0067 set(const set& s, const allocator_type& a);
0068 set(set&& s, const allocator_type& a);
0069 set(initializer_list<value_type> il, const value_compare& comp = value_compare());
0070 set(initializer_list<value_type> il, const value_compare& comp,
0071 const allocator_type& a);
0072 template <class InputIterator>
0073 set(InputIterator first, InputIterator last, const allocator_type& a)
0074 : set(first, last, Compare(), a) {} // C++14
0075 template<container-compatible-range<value_type> R>
0076 set(from_range_t, R&& rg, const Allocator& a))
0077 : set(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
0078 set(initializer_list<value_type> il, const allocator_type& a)
0079 : set(il, Compare(), a) {} // C++14
0080 ~set();
0081
0082 set& operator=(const set& s);
0083 set& operator=(set&& s)
0084 noexcept(
0085 allocator_type::propagate_on_container_move_assignment::value &&
0086 is_nothrow_move_assignable<allocator_type>::value &&
0087 is_nothrow_move_assignable<key_compare>::value);
0088 set& operator=(initializer_list<value_type> il);
0089
0090 // iterators:
0091 iterator begin() noexcept;
0092 const_iterator begin() const noexcept;
0093 iterator end() noexcept;
0094 const_iterator end() const noexcept;
0095
0096 reverse_iterator rbegin() noexcept;
0097 const_reverse_iterator rbegin() const noexcept;
0098 reverse_iterator rend() noexcept;
0099 const_reverse_iterator rend() const noexcept;
0100
0101 const_iterator cbegin() const noexcept;
0102 const_iterator cend() const noexcept;
0103 const_reverse_iterator crbegin() const noexcept;
0104 const_reverse_iterator crend() const noexcept;
0105
0106 // capacity:
0107 bool empty() const noexcept;
0108 size_type size() const noexcept;
0109 size_type max_size() const noexcept;
0110
0111 // modifiers:
0112 template <class... Args>
0113 pair<iterator, bool> emplace(Args&&... args);
0114 template <class... Args>
0115 iterator emplace_hint(const_iterator position, Args&&... args);
0116 pair<iterator,bool> insert(const value_type& v);
0117 pair<iterator,bool> insert(value_type&& v);
0118 iterator insert(const_iterator position, const value_type& v);
0119 iterator insert(const_iterator position, value_type&& v);
0120 template <class InputIterator>
0121 void insert(InputIterator first, InputIterator last);
0122 template<container-compatible-range<value_type> R>
0123 void insert_range(R&& rg); // C++23
0124 void insert(initializer_list<value_type> il);
0125
0126 node_type extract(const_iterator position); // C++17
0127 node_type extract(const key_type& x); // C++17
0128 insert_return_type insert(node_type&& nh); // C++17
0129 iterator insert(const_iterator hint, node_type&& nh); // C++17
0130
0131 iterator erase(const_iterator position);
0132 iterator erase(iterator position); // C++14
0133 size_type erase(const key_type& k);
0134 iterator erase(const_iterator first, const_iterator last);
0135 void clear() noexcept;
0136
0137 template<class C2>
0138 void merge(set<Key, C2, Allocator>& source); // C++17
0139 template<class C2>
0140 void merge(set<Key, C2, Allocator>&& source); // C++17
0141 template<class C2>
0142 void merge(multiset<Key, C2, Allocator>& source); // C++17
0143 template<class C2>
0144 void merge(multiset<Key, C2, Allocator>&& source); // C++17
0145
0146 void swap(set& s)
0147 noexcept(
0148 __is_nothrow_swappable<key_compare>::value &&
0149 (!allocator_type::propagate_on_container_swap::value ||
0150 __is_nothrow_swappable<allocator_type>::value));
0151
0152 // observers:
0153 allocator_type get_allocator() const noexcept;
0154 key_compare key_comp() const;
0155 value_compare value_comp() const;
0156
0157 // set operations:
0158 iterator find(const key_type& k);
0159 const_iterator find(const key_type& k) const;
0160 template<typename K>
0161 iterator find(const K& x);
0162 template<typename K>
0163 const_iterator find(const K& x) const; // C++14
0164
0165 template<typename K>
0166 size_type count(const K& x) const; // C++14
0167 size_type count(const key_type& k) const;
0168
0169 bool contains(const key_type& x) const; // C++20
0170 template<class K> bool contains(const K& x) const; // C++20
0171
0172 iterator lower_bound(const key_type& k);
0173 const_iterator lower_bound(const key_type& k) const;
0174 template<typename K>
0175 iterator lower_bound(const K& x); // C++14
0176 template<typename K>
0177 const_iterator lower_bound(const K& x) const; // C++14
0178
0179 iterator upper_bound(const key_type& k);
0180 const_iterator upper_bound(const key_type& k) const;
0181 template<typename K>
0182 iterator upper_bound(const K& x); // C++14
0183 template<typename K>
0184 const_iterator upper_bound(const K& x) const; // C++14
0185 pair<iterator,iterator> equal_range(const key_type& k);
0186 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
0187 template<typename K>
0188 pair<iterator,iterator> equal_range(const K& x); // C++14
0189 template<typename K>
0190 pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14
0191 };
0192
0193 template <class InputIterator,
0194 class Compare = less<typename iterator_traits<InputIterator>::value_type>,
0195 class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
0196 set(InputIterator, InputIterator,
0197 Compare = Compare(), Allocator = Allocator())
0198 -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17
0199
0200 template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
0201 class Allocator = allocator<ranges::range_value_t<R>>>
0202 set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
0203 -> set<ranges::range_value_t<R>, Compare, Allocator>; // C++23
0204
0205 template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
0206 set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
0207 -> set<Key, Compare, Allocator>; // C++17
0208
0209 template<class InputIterator, class Allocator>
0210 set(InputIterator, InputIterator, Allocator)
0211 -> set<typename iterator_traits<InputIterator>::value_type,
0212 less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17
0213
0214 template<ranges::input_range R, class Allocator>
0215 set(from_range_t, R&&, Allocator)
0216 -> set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>; // C++23
0217
0218 template<class Key, class Allocator>
0219 set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>; // C++17
0220
0221 template <class Key, class Compare, class Allocator>
0222 bool
0223 operator==(const set<Key, Compare, Allocator>& x,
0224 const set<Key, Compare, Allocator>& y);
0225
0226 template <class Key, class Compare, class Allocator>
0227 bool
0228 operator< (const set<Key, Compare, Allocator>& x,
0229 const set<Key, Compare, Allocator>& y); // removed in C++20
0230
0231 template <class Key, class Compare, class Allocator>
0232 bool
0233 operator!=(const set<Key, Compare, Allocator>& x,
0234 const set<Key, Compare, Allocator>& y); // removed in C++20
0235
0236 template <class Key, class Compare, class Allocator>
0237 bool
0238 operator> (const set<Key, Compare, Allocator>& x,
0239 const set<Key, Compare, Allocator>& y); // removed in C++20
0240
0241 template <class Key, class Compare, class Allocator>
0242 bool
0243 operator>=(const set<Key, Compare, Allocator>& x,
0244 const set<Key, Compare, Allocator>& y); // removed in C++20
0245
0246 template <class Key, class Compare, class Allocator>
0247 bool
0248 operator<=(const set<Key, Compare, Allocator>& x,
0249 const set<Key, Compare, Allocator>& y); // removed in C++20
0250
0251 template<class Key, class Compare, class Allocator>
0252 synth-three-way-result<Key> operator<=>(const set<Key, Compare, Allocator>& x,
0253 const set<Key, Compare, Allocator>& y); // since C++20
0254
0255 // specialized algorithms:
0256 template <class Key, class Compare, class Allocator>
0257 void
0258 swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)
0259 noexcept(noexcept(x.swap(y)));
0260
0261 template <class Key, class Compare, class Allocator, class Predicate>
0262 typename set<Key, Compare, Allocator>::size_type
0263 erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20
0264
0265 template <class Key, class Compare = less<Key>,
0266 class Allocator = allocator<Key>>
0267 class multiset
0268 {
0269 public:
0270 // types:
0271 typedef Key key_type;
0272 typedef key_type value_type;
0273 typedef Compare key_compare;
0274 typedef key_compare value_compare;
0275 typedef Allocator allocator_type;
0276 typedef typename allocator_type::reference reference;
0277 typedef typename allocator_type::const_reference const_reference;
0278 typedef typename allocator_type::size_type size_type;
0279 typedef typename allocator_type::difference_type difference_type;
0280 typedef typename allocator_type::pointer pointer;
0281 typedef typename allocator_type::const_pointer const_pointer;
0282
0283 typedef implementation-defined iterator;
0284 typedef implementation-defined const_iterator;
0285 typedef std::reverse_iterator<iterator> reverse_iterator;
0286 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0287 typedef unspecified node_type; // C++17
0288
0289 // construct/copy/destroy:
0290 multiset()
0291 noexcept(
0292 is_nothrow_default_constructible<allocator_type>::value &&
0293 is_nothrow_default_constructible<key_compare>::value &&
0294 is_nothrow_copy_constructible<key_compare>::value);
0295 explicit multiset(const value_compare& comp);
0296 multiset(const value_compare& comp, const allocator_type& a);
0297 template <class InputIterator>
0298 multiset(InputIterator first, InputIterator last,
0299 const value_compare& comp = value_compare());
0300 template <class InputIterator>
0301 multiset(InputIterator first, InputIterator last,
0302 const value_compare& comp, const allocator_type& a);
0303 template<container-compatible-range<value_type> R>
0304 multiset(from_range_t, R&& rg,
0305 const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
0306 multiset(const multiset& s);
0307 multiset(multiset&& s)
0308 noexcept(
0309 is_nothrow_move_constructible<allocator_type>::value &&
0310 is_nothrow_move_constructible<key_compare>::value);
0311 explicit multiset(const allocator_type& a);
0312 multiset(const multiset& s, const allocator_type& a);
0313 multiset(multiset&& s, const allocator_type& a);
0314 multiset(initializer_list<value_type> il, const value_compare& comp = value_compare());
0315 multiset(initializer_list<value_type> il, const value_compare& comp,
0316 const allocator_type& a);
0317 template <class InputIterator>
0318 multiset(InputIterator first, InputIterator last, const allocator_type& a)
0319 : set(first, last, Compare(), a) {} // C++14
0320 template<container-compatible-range<value_type> R>
0321 multiset(from_range_t, R&& rg, const Allocator& a))
0322 : multiset(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
0323 multiset(initializer_list<value_type> il, const allocator_type& a)
0324 : set(il, Compare(), a) {} // C++14
0325 ~multiset();
0326
0327 multiset& operator=(const multiset& s);
0328 multiset& operator=(multiset&& s)
0329 noexcept(
0330 allocator_type::propagate_on_container_move_assignment::value &&
0331 is_nothrow_move_assignable<allocator_type>::value &&
0332 is_nothrow_move_assignable<key_compare>::value);
0333 multiset& operator=(initializer_list<value_type> il);
0334
0335 // iterators:
0336 iterator begin() noexcept;
0337 const_iterator begin() const noexcept;
0338 iterator end() noexcept;
0339 const_iterator end() const noexcept;
0340
0341 reverse_iterator rbegin() noexcept;
0342 const_reverse_iterator rbegin() const noexcept;
0343 reverse_iterator rend() noexcept;
0344 const_reverse_iterator rend() const noexcept;
0345
0346 const_iterator cbegin() const noexcept;
0347 const_iterator cend() const noexcept;
0348 const_reverse_iterator crbegin() const noexcept;
0349 const_reverse_iterator crend() const noexcept;
0350
0351 // capacity:
0352 bool empty() const noexcept;
0353 size_type size() const noexcept;
0354 size_type max_size() const noexcept;
0355
0356 // modifiers:
0357 template <class... Args>
0358 iterator emplace(Args&&... args);
0359 template <class... Args>
0360 iterator emplace_hint(const_iterator position, Args&&... args);
0361 iterator insert(const value_type& v);
0362 iterator insert(value_type&& v);
0363 iterator insert(const_iterator position, const value_type& v);
0364 iterator insert(const_iterator position, value_type&& v);
0365 template <class InputIterator>
0366 void insert(InputIterator first, InputIterator last);
0367 template<container-compatible-range<value_type> R>
0368 void insert_range(R&& rg); // C++23
0369 void insert(initializer_list<value_type> il);
0370
0371 node_type extract(const_iterator position); // C++17
0372 node_type extract(const key_type& x); // C++17
0373 iterator insert(node_type&& nh); // C++17
0374 iterator insert(const_iterator hint, node_type&& nh); // C++17
0375
0376 iterator erase(const_iterator position);
0377 iterator erase(iterator position); // C++14
0378 size_type erase(const key_type& k);
0379 iterator erase(const_iterator first, const_iterator last);
0380 void clear() noexcept;
0381
0382 template<class C2>
0383 void merge(multiset<Key, C2, Allocator>& source); // C++17
0384 template<class C2>
0385 void merge(multiset<Key, C2, Allocator>&& source); // C++17
0386 template<class C2>
0387 void merge(set<Key, C2, Allocator>& source); // C++17
0388 template<class C2>
0389 void merge(set<Key, C2, Allocator>&& source); // C++17
0390
0391 void swap(multiset& s)
0392 noexcept(
0393 __is_nothrow_swappable<key_compare>::value &&
0394 (!allocator_type::propagate_on_container_swap::value ||
0395 __is_nothrow_swappable<allocator_type>::value));
0396
0397 // observers:
0398 allocator_type get_allocator() const noexcept;
0399 key_compare key_comp() const;
0400 value_compare value_comp() const;
0401
0402 // set operations:
0403 iterator find(const key_type& k);
0404 const_iterator find(const key_type& k) const;
0405 template<typename K>
0406 iterator find(const K& x);
0407 template<typename K>
0408 const_iterator find(const K& x) const; // C++14
0409
0410 template<typename K>
0411 size_type count(const K& x) const; // C++14
0412 size_type count(const key_type& k) const;
0413
0414 bool contains(const key_type& x) const; // C++20
0415 template<class K> bool contains(const K& x) const; // C++20
0416
0417 iterator lower_bound(const key_type& k);
0418 const_iterator lower_bound(const key_type& k) const;
0419 template<typename K>
0420 iterator lower_bound(const K& x); // C++14
0421 template<typename K>
0422 const_iterator lower_bound(const K& x) const; // C++14
0423
0424 iterator upper_bound(const key_type& k);
0425 const_iterator upper_bound(const key_type& k) const;
0426 template<typename K>
0427 iterator upper_bound(const K& x); // C++14
0428 template<typename K>
0429 const_iterator upper_bound(const K& x) const; // C++14
0430
0431 pair<iterator,iterator> equal_range(const key_type& k);
0432 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
0433 template<typename K>
0434 pair<iterator,iterator> equal_range(const K& x); // C++14
0435 template<typename K>
0436 pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14
0437 };
0438
0439 template <class InputIterator,
0440 class Compare = less<typename iterator_traits<InputIterator>::value_type>,
0441 class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
0442 multiset(InputIterator, InputIterator,
0443 Compare = Compare(), Allocator = Allocator())
0444 -> multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17
0445
0446 template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
0447 class Allocator = allocator<ranges::range_value_t<R>>>
0448 multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
0449 -> multiset<ranges::range_value_t<R>, Compare, Allocator>;
0450
0451 template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
0452 multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
0453 -> multiset<Key, Compare, Allocator>; // C++17
0454
0455 template<class InputIterator, class Allocator>
0456 multiset(InputIterator, InputIterator, Allocator)
0457 -> multiset<typename iterator_traits<InputIterator>::value_type,
0458 less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17
0459
0460 template<ranges::input_range R, class Allocator>
0461 multiset(from_range_t, R&&, Allocator)
0462 -> multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>;
0463
0464 template<class Key, class Allocator>
0465 multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>; // C++17
0466
0467 template <class Key, class Compare, class Allocator>
0468 bool
0469 operator==(const multiset<Key, Compare, Allocator>& x,
0470 const multiset<Key, Compare, Allocator>& y);
0471
0472 template <class Key, class Compare, class Allocator>
0473 bool
0474 operator< (const multiset<Key, Compare, Allocator>& x,
0475 const multiset<Key, Compare, Allocator>& y); // removed in C++20
0476
0477 template <class Key, class Compare, class Allocator>
0478 bool
0479 operator!=(const multiset<Key, Compare, Allocator>& x,
0480 const multiset<Key, Compare, Allocator>& y); // removed in C++20
0481
0482 template <class Key, class Compare, class Allocator>
0483 bool
0484 operator> (const multiset<Key, Compare, Allocator>& x,
0485 const multiset<Key, Compare, Allocator>& y); // removed in C++20
0486
0487 template <class Key, class Compare, class Allocator>
0488 bool
0489 operator>=(const multiset<Key, Compare, Allocator>& x,
0490 const multiset<Key, Compare, Allocator>& y); // removed in C++20
0491
0492 template <class Key, class Compare, class Allocator>
0493 bool
0494 operator<=(const multiset<Key, Compare, Allocator>& x,
0495 const multiset<Key, Compare, Allocator>& y); // removed in C++20
0496
0497 template<class Key, class Compare, class Allocator>
0498 synth-three-way-result<Key> operator<=>(const multiset<Key, Compare, Allocator>& x,
0499 const multiset<Key, Compare, Allocator>& y); // since C++20
0500
0501 // specialized algorithms:
0502 template <class Key, class Compare, class Allocator>
0503 void
0504 swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
0505 noexcept(noexcept(x.swap(y)));
0506
0507 template <class Key, class Compare, class Allocator, class Predicate>
0508 typename multiset<Key, Compare, Allocator>::size_type
0509 erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
0510
0511 } // std
0512
0513 */
0514
0515 #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
0516 # include <__cxx03/set>
0517 #else
0518 # include <__algorithm/equal.h>
0519 # include <__algorithm/lexicographical_compare.h>
0520 # include <__algorithm/lexicographical_compare_three_way.h>
0521 # include <__assert>
0522 # include <__config>
0523 # include <__functional/is_transparent.h>
0524 # include <__functional/operations.h>
0525 # include <__iterator/erase_if_container.h>
0526 # include <__iterator/iterator_traits.h>
0527 # include <__iterator/ranges_iterator_traits.h>
0528 # include <__iterator/reverse_iterator.h>
0529 # include <__memory/allocator.h>
0530 # include <__memory/allocator_traits.h>
0531 # include <__memory_resource/polymorphic_allocator.h>
0532 # include <__node_handle>
0533 # include <__ranges/concepts.h>
0534 # include <__ranges/container_compatible_range.h>
0535 # include <__ranges/from_range.h>
0536 # include <__tree>
0537 # include <__type_traits/container_traits.h>
0538 # include <__type_traits/enable_if.h>
0539 # include <__type_traits/is_allocator.h>
0540 # include <__type_traits/is_nothrow_assignable.h>
0541 # include <__type_traits/is_nothrow_constructible.h>
0542 # include <__type_traits/is_same.h>
0543 # include <__type_traits/is_swappable.h>
0544 # include <__type_traits/type_identity.h>
0545 # include <__utility/forward.h>
0546 # include <__utility/move.h>
0547 # include <__utility/pair.h>
0548 # include <version>
0549
0550 // standard-mandated includes
0551
0552 // [iterator.range]
0553 # include <__iterator/access.h>
0554 # include <__iterator/data.h>
0555 # include <__iterator/empty.h>
0556 # include <__iterator/reverse_access.h>
0557 # include <__iterator/size.h>
0558
0559 // [associative.set.syn]
0560 # include <compare>
0561 # include <initializer_list>
0562
0563 # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0564 # pragma GCC system_header
0565 # endif
0566
0567 _LIBCPP_PUSH_MACROS
0568 # include <__undef_macros>
0569
0570 _LIBCPP_BEGIN_NAMESPACE_STD
0571
0572 template <class _Key, class _Compare, class _Allocator>
0573 class multiset;
0574
0575 template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> >
0576 class _LIBCPP_TEMPLATE_VIS set {
0577 public:
0578 // types:
0579 typedef _Key key_type;
0580 typedef key_type value_type;
0581 typedef __type_identity_t<_Compare> key_compare;
0582 typedef key_compare value_compare;
0583 typedef __type_identity_t<_Allocator> allocator_type;
0584 typedef value_type& reference;
0585 typedef const value_type& const_reference;
0586
0587 static_assert(is_same<typename allocator_type::value_type, value_type>::value,
0588 "Allocator::value_type must be same type as value_type");
0589
0590 private:
0591 typedef __tree<value_type, value_compare, allocator_type> __base;
0592 typedef allocator_traits<allocator_type> __alloc_traits;
0593
0594 static_assert(__check_valid_allocator<allocator_type>::value, "");
0595
0596 __base __tree_;
0597
0598 public:
0599 typedef typename __base::pointer pointer;
0600 typedef typename __base::const_pointer const_pointer;
0601 typedef typename __base::size_type size_type;
0602 typedef typename __base::difference_type difference_type;
0603 typedef typename __base::const_iterator iterator;
0604 typedef typename __base::const_iterator const_iterator;
0605 typedef std::reverse_iterator<iterator> reverse_iterator;
0606 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0607
0608 # if _LIBCPP_STD_VER >= 17
0609 typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
0610 typedef __insert_return_type<iterator, node_type> insert_return_type;
0611 # endif
0612
0613 template <class _Key2, class _Compare2, class _Alloc2>
0614 friend class _LIBCPP_TEMPLATE_VIS set;
0615 template <class _Key2, class _Compare2, class _Alloc2>
0616 friend class _LIBCPP_TEMPLATE_VIS multiset;
0617
0618 _LIBCPP_HIDE_FROM_ABI set() _NOEXCEPT_(
0619 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&
0620 is_nothrow_copy_constructible<key_compare>::value)
0621 : __tree_(value_compare()) {}
0622
0623 _LIBCPP_HIDE_FROM_ABI explicit set(const value_compare& __comp) _NOEXCEPT_(
0624 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_copy_constructible<key_compare>::value)
0625 : __tree_(__comp) {}
0626
0627 _LIBCPP_HIDE_FROM_ABI explicit set(const value_compare& __comp, const allocator_type& __a) : __tree_(__comp, __a) {}
0628 template <class _InputIterator>
0629 _LIBCPP_HIDE_FROM_ABI set(_InputIterator __f, _InputIterator __l, const value_compare& __comp = value_compare())
0630 : __tree_(__comp) {
0631 insert(__f, __l);
0632 }
0633
0634 template <class _InputIterator>
0635 _LIBCPP_HIDE_FROM_ABI
0636 set(_InputIterator __f, _InputIterator __l, const value_compare& __comp, const allocator_type& __a)
0637 : __tree_(__comp, __a) {
0638 insert(__f, __l);
0639 }
0640
0641 # if _LIBCPP_STD_VER >= 23
0642 template <_ContainerCompatibleRange<value_type> _Range>
0643 _LIBCPP_HIDE_FROM_ABI
0644 set(from_range_t,
0645 _Range&& __range,
0646 const key_compare& __comp = key_compare(),
0647 const allocator_type& __a = allocator_type())
0648 : __tree_(__comp, __a) {
0649 insert_range(std::forward<_Range>(__range));
0650 }
0651 # endif
0652
0653 # if _LIBCPP_STD_VER >= 14
0654 template <class _InputIterator>
0655 _LIBCPP_HIDE_FROM_ABI set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
0656 : set(__f, __l, key_compare(), __a) {}
0657 # endif
0658
0659 # if _LIBCPP_STD_VER >= 23
0660 template <_ContainerCompatibleRange<value_type> _Range>
0661 _LIBCPP_HIDE_FROM_ABI set(from_range_t, _Range&& __range, const allocator_type& __a)
0662 : set(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
0663 # endif
0664
0665 _LIBCPP_HIDE_FROM_ABI set(const set& __s) : __tree_(__s.__tree_) { insert(__s.begin(), __s.end()); }
0666
0667 _LIBCPP_HIDE_FROM_ABI set& operator=(const set& __s) {
0668 __tree_ = __s.__tree_;
0669 return *this;
0670 }
0671
0672 # ifndef _LIBCPP_CXX03_LANG
0673 _LIBCPP_HIDE_FROM_ABI set(set&& __s) noexcept(is_nothrow_move_constructible<__base>::value)
0674 : __tree_(std::move(__s.__tree_)) {}
0675 # endif // _LIBCPP_CXX03_LANG
0676
0677 _LIBCPP_HIDE_FROM_ABI explicit set(const allocator_type& __a) : __tree_(__a) {}
0678
0679 _LIBCPP_HIDE_FROM_ABI set(const set& __s, const allocator_type& __a) : __tree_(__s.__tree_.value_comp(), __a) {
0680 insert(__s.begin(), __s.end());
0681 }
0682
0683 # ifndef _LIBCPP_CXX03_LANG
0684 _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __a);
0685
0686 _LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
0687 : __tree_(__comp) {
0688 insert(__il.begin(), __il.end());
0689 }
0690
0691 _LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const value_compare& __comp, const allocator_type& __a)
0692 : __tree_(__comp, __a) {
0693 insert(__il.begin(), __il.end());
0694 }
0695
0696 # if _LIBCPP_STD_VER >= 14
0697 _LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const allocator_type& __a)
0698 : set(__il, key_compare(), __a) {}
0699 # endif
0700
0701 _LIBCPP_HIDE_FROM_ABI set& operator=(initializer_list<value_type> __il) {
0702 __tree_.__assign_unique(__il.begin(), __il.end());
0703 return *this;
0704 }
0705
0706 _LIBCPP_HIDE_FROM_ABI set& operator=(set&& __s) noexcept(is_nothrow_move_assignable<__base>::value) {
0707 __tree_ = std::move(__s.__tree_);
0708 return *this;
0709 }
0710 # endif // _LIBCPP_CXX03_LANG
0711
0712 _LIBCPP_HIDE_FROM_ABI ~set() { static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
0713
0714 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
0715 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
0716 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
0717 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
0718
0719 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
0720 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
0721 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
0722 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
0723
0724 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
0725 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
0726 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
0727 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
0728
0729 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
0730 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
0731 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
0732
0733 // modifiers:
0734 # ifndef _LIBCPP_CXX03_LANG
0735 template <class... _Args>
0736 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> emplace(_Args&&... __args) {
0737 return __tree_.__emplace_unique(std::forward<_Args>(__args)...);
0738 }
0739 template <class... _Args>
0740 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
0741 return __tree_.__emplace_hint_unique(__p, std::forward<_Args>(__args)...);
0742 }
0743 # endif // _LIBCPP_CXX03_LANG
0744
0745 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__insert_unique(__v); }
0746 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
0747 return __tree_.__insert_unique(__p, __v);
0748 }
0749
0750 template <class _InputIterator>
0751 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
0752 for (const_iterator __e = cend(); __f != __l; ++__f)
0753 __tree_.__insert_unique(__e, *__f);
0754 }
0755
0756 # if _LIBCPP_STD_VER >= 23
0757 template <_ContainerCompatibleRange<value_type> _Range>
0758 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
0759 const_iterator __end = cend();
0760 for (auto&& __element : __range) {
0761 __tree_.__insert_unique(__end, std::forward<decltype(__element)>(__element));
0762 }
0763 }
0764 # endif
0765
0766 # ifndef _LIBCPP_CXX03_LANG
0767 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(value_type&& __v) {
0768 return __tree_.__insert_unique(std::move(__v));
0769 }
0770
0771 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
0772 return __tree_.__insert_unique(__p, std::move(__v));
0773 }
0774
0775 _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
0776 # endif // _LIBCPP_CXX03_LANG
0777
0778 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p); }
0779 _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_unique(__k); }
0780 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) { return __tree_.erase(__f, __l); }
0781 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }
0782
0783 # if _LIBCPP_STD_VER >= 17
0784 _LIBCPP_HIDE_FROM_ABI insert_return_type insert(node_type&& __nh) {
0785 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
0786 "node_type with incompatible allocator passed to set::insert()");
0787 return __tree_.template __node_handle_insert_unique< node_type, insert_return_type>(std::move(__nh));
0788 }
0789 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {
0790 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
0791 "node_type with incompatible allocator passed to set::insert()");
0792 return __tree_.template __node_handle_insert_unique<node_type>(__hint, std::move(__nh));
0793 }
0794 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
0795 return __tree_.template __node_handle_extract<node_type>(__key);
0796 }
0797 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
0798 return __tree_.template __node_handle_extract<node_type>(__it);
0799 }
0800 template <class _Compare2>
0801 _LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>& __source) {
0802 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
0803 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
0804 __tree_.__node_handle_merge_unique(__source.__tree_);
0805 }
0806 template <class _Compare2>
0807 _LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>&& __source) {
0808 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
0809 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
0810 __tree_.__node_handle_merge_unique(__source.__tree_);
0811 }
0812 template <class _Compare2>
0813 _LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>& __source) {
0814 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
0815 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
0816 __tree_.__node_handle_merge_unique(__source.__tree_);
0817 }
0818 template <class _Compare2>
0819 _LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>&& __source) {
0820 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
0821 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
0822 __tree_.__node_handle_merge_unique(__source.__tree_);
0823 }
0824 # endif
0825
0826 _LIBCPP_HIDE_FROM_ABI void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) { __tree_.swap(__s.__tree_); }
0827
0828 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
0829 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
0830 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
0831
0832 // set operations:
0833 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
0834 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
0835 # if _LIBCPP_STD_VER >= 14
0836 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0837 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
0838 return __tree_.find(__k);
0839 }
0840 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0841 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
0842 return __tree_.find(__k);
0843 }
0844 # endif
0845
0846 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_unique(__k); }
0847 # if _LIBCPP_STD_VER >= 14
0848 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0849 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
0850 return __tree_.__count_multi(__k);
0851 }
0852 # endif
0853
0854 # if _LIBCPP_STD_VER >= 20
0855 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
0856 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0857 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
0858 return find(__k) != end();
0859 }
0860 # endif // _LIBCPP_STD_VER >= 20
0861
0862 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
0863 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
0864 # if _LIBCPP_STD_VER >= 14
0865 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0866 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
0867 return __tree_.lower_bound(__k);
0868 }
0869
0870 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0871 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
0872 return __tree_.lower_bound(__k);
0873 }
0874 # endif
0875
0876 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
0877 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
0878 # if _LIBCPP_STD_VER >= 14
0879 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0880 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
0881 return __tree_.upper_bound(__k);
0882 }
0883 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0884 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
0885 return __tree_.upper_bound(__k);
0886 }
0887 # endif
0888
0889 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
0890 return __tree_.__equal_range_unique(__k);
0891 }
0892 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
0893 return __tree_.__equal_range_unique(__k);
0894 }
0895 # if _LIBCPP_STD_VER >= 14
0896 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0897 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
0898 return __tree_.__equal_range_multi(__k);
0899 }
0900 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0901 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
0902 return __tree_.__equal_range_multi(__k);
0903 }
0904 # endif
0905 };
0906
0907 # if _LIBCPP_STD_VER >= 17
0908 template <class _InputIterator,
0909 class _Compare = less<__iter_value_type<_InputIterator>>,
0910 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
0911 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
0912 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
0913 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
0914 set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
0915 -> set<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
0916
0917 # if _LIBCPP_STD_VER >= 23
0918 template <ranges::input_range _Range,
0919 class _Compare = less<ranges::range_value_t<_Range>>,
0920 class _Allocator = allocator<ranges::range_value_t<_Range>>,
0921 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
0922 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
0923 set(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
0924 -> set<ranges::range_value_t<_Range>, _Compare, _Allocator>;
0925 # endif
0926
0927 template <class _Key,
0928 class _Compare = less<_Key>,
0929 class _Allocator = allocator<_Key>,
0930 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
0931 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
0932 set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) -> set<_Key, _Compare, _Allocator>;
0933
0934 template <class _InputIterator,
0935 class _Allocator,
0936 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
0937 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
0938 set(_InputIterator,
0939 _InputIterator,
0940 _Allocator) -> set<__iter_value_type<_InputIterator>, less<__iter_value_type<_InputIterator>>, _Allocator>;
0941
0942 # if _LIBCPP_STD_VER >= 23
0943 template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
0944 set(from_range_t,
0945 _Range&&,
0946 _Allocator) -> set<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
0947 # endif
0948
0949 template <class _Key, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
0950 set(initializer_list<_Key>, _Allocator) -> set<_Key, less<_Key>, _Allocator>;
0951 # endif
0952
0953 # ifndef _LIBCPP_CXX03_LANG
0954
0955 template <class _Key, class _Compare, class _Allocator>
0956 set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a) : __tree_(std::move(__s.__tree_), __a) {
0957 if (__a != __s.get_allocator()) {
0958 const_iterator __e = cend();
0959 while (!__s.empty())
0960 insert(__e, std::move(__s.__tree_.remove(__s.begin())->__value_));
0961 }
0962 }
0963
0964 # endif // _LIBCPP_CXX03_LANG
0965
0966 template <class _Key, class _Compare, class _Allocator>
0967 inline _LIBCPP_HIDE_FROM_ABI bool
0968 operator==(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0969 return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
0970 }
0971
0972 # if _LIBCPP_STD_VER <= 17
0973
0974 template <class _Key, class _Compare, class _Allocator>
0975 inline _LIBCPP_HIDE_FROM_ABI bool
0976 operator<(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0977 return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
0978 }
0979
0980 template <class _Key, class _Compare, class _Allocator>
0981 inline _LIBCPP_HIDE_FROM_ABI bool
0982 operator!=(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0983 return !(__x == __y);
0984 }
0985
0986 template <class _Key, class _Compare, class _Allocator>
0987 inline _LIBCPP_HIDE_FROM_ABI bool
0988 operator>(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0989 return __y < __x;
0990 }
0991
0992 template <class _Key, class _Compare, class _Allocator>
0993 inline _LIBCPP_HIDE_FROM_ABI bool
0994 operator>=(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0995 return !(__x < __y);
0996 }
0997
0998 template <class _Key, class _Compare, class _Allocator>
0999 inline _LIBCPP_HIDE_FROM_ABI bool
1000 operator<=(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
1001 return !(__y < __x);
1002 }
1003
1004 # else // _LIBCPP_STD_VER <= 17
1005
1006 template <class _Key, class _Compare, class _Allocator>
1007 _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
1008 operator<=>(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
1009 return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
1010 }
1011
1012 # endif // _LIBCPP_STD_VER <= 17
1013
1014 // specialized algorithms:
1015 template <class _Key, class _Compare, class _Allocator>
1016 inline _LIBCPP_HIDE_FROM_ABI void swap(set<_Key, _Compare, _Allocator>& __x, set<_Key, _Compare, _Allocator>& __y)
1017 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
1018 __x.swap(__y);
1019 }
1020
1021 # if _LIBCPP_STD_VER >= 20
1022 template <class _Key, class _Compare, class _Allocator, class _Predicate>
1023 inline _LIBCPP_HIDE_FROM_ABI typename set<_Key, _Compare, _Allocator>::size_type
1024 erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
1025 return std::__libcpp_erase_if_container(__c, __pred);
1026 }
1027 # endif
1028
1029 template <class _Key, class _Compare, class _Allocator>
1030 struct __container_traits<set<_Key, _Compare, _Allocator> > {
1031 // http://eel.is/c++draft/associative.reqmts.except#2
1032 // For associative containers, if an exception is thrown by any operation from within
1033 // an insert or emplace function inserting a single element, the insertion has no effect.
1034 static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = true;
1035 };
1036
1037 template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> >
1038 class _LIBCPP_TEMPLATE_VIS multiset {
1039 public:
1040 // types:
1041 typedef _Key key_type;
1042 typedef key_type value_type;
1043 typedef __type_identity_t<_Compare> key_compare;
1044 typedef key_compare value_compare;
1045 typedef __type_identity_t<_Allocator> allocator_type;
1046 typedef value_type& reference;
1047 typedef const value_type& const_reference;
1048
1049 static_assert(is_same<typename allocator_type::value_type, value_type>::value,
1050 "Allocator::value_type must be same type as value_type");
1051
1052 private:
1053 typedef __tree<value_type, value_compare, allocator_type> __base;
1054 typedef allocator_traits<allocator_type> __alloc_traits;
1055
1056 static_assert(__check_valid_allocator<allocator_type>::value, "");
1057
1058 __base __tree_;
1059
1060 public:
1061 typedef typename __base::pointer pointer;
1062 typedef typename __base::const_pointer const_pointer;
1063 typedef typename __base::size_type size_type;
1064 typedef typename __base::difference_type difference_type;
1065 typedef typename __base::const_iterator iterator;
1066 typedef typename __base::const_iterator const_iterator;
1067 typedef std::reverse_iterator<iterator> reverse_iterator;
1068 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1069
1070 # if _LIBCPP_STD_VER >= 17
1071 typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
1072 # endif
1073
1074 template <class _Key2, class _Compare2, class _Alloc2>
1075 friend class _LIBCPP_TEMPLATE_VIS set;
1076 template <class _Key2, class _Compare2, class _Alloc2>
1077 friend class _LIBCPP_TEMPLATE_VIS multiset;
1078
1079 // construct/copy/destroy:
1080 _LIBCPP_HIDE_FROM_ABI multiset() _NOEXCEPT_(
1081 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&
1082 is_nothrow_copy_constructible<key_compare>::value)
1083 : __tree_(value_compare()) {}
1084
1085 _LIBCPP_HIDE_FROM_ABI explicit multiset(const value_compare& __comp) _NOEXCEPT_(
1086 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_copy_constructible<key_compare>::value)
1087 : __tree_(__comp) {}
1088
1089 _LIBCPP_HIDE_FROM_ABI explicit multiset(const value_compare& __comp, const allocator_type& __a)
1090 : __tree_(__comp, __a) {}
1091 template <class _InputIterator>
1092 _LIBCPP_HIDE_FROM_ABI multiset(_InputIterator __f, _InputIterator __l, const value_compare& __comp = value_compare())
1093 : __tree_(__comp) {
1094 insert(__f, __l);
1095 }
1096
1097 # if _LIBCPP_STD_VER >= 14
1098 template <class _InputIterator>
1099 _LIBCPP_HIDE_FROM_ABI multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
1100 : multiset(__f, __l, key_compare(), __a) {}
1101 # endif
1102
1103 template <class _InputIterator>
1104 _LIBCPP_HIDE_FROM_ABI
1105 multiset(_InputIterator __f, _InputIterator __l, const value_compare& __comp, const allocator_type& __a)
1106 : __tree_(__comp, __a) {
1107 insert(__f, __l);
1108 }
1109
1110 # if _LIBCPP_STD_VER >= 23
1111 template <_ContainerCompatibleRange<value_type> _Range>
1112 _LIBCPP_HIDE_FROM_ABI
1113 multiset(from_range_t,
1114 _Range&& __range,
1115 const key_compare& __comp = key_compare(),
1116 const allocator_type& __a = allocator_type())
1117 : __tree_(__comp, __a) {
1118 insert_range(std::forward<_Range>(__range));
1119 }
1120
1121 template <_ContainerCompatibleRange<value_type> _Range>
1122 _LIBCPP_HIDE_FROM_ABI multiset(from_range_t, _Range&& __range, const allocator_type& __a)
1123 : multiset(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
1124 # endif
1125
1126 _LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s)
1127 : __tree_(__s.__tree_.value_comp(),
1128 __alloc_traits::select_on_container_copy_construction(__s.__tree_.__alloc())) {
1129 insert(__s.begin(), __s.end());
1130 }
1131
1132 _LIBCPP_HIDE_FROM_ABI multiset& operator=(const multiset& __s) {
1133 __tree_ = __s.__tree_;
1134 return *this;
1135 }
1136
1137 # ifndef _LIBCPP_CXX03_LANG
1138 _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s) noexcept(is_nothrow_move_constructible<__base>::value)
1139 : __tree_(std::move(__s.__tree_)) {}
1140
1141 _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a);
1142 # endif // _LIBCPP_CXX03_LANG
1143 _LIBCPP_HIDE_FROM_ABI explicit multiset(const allocator_type& __a) : __tree_(__a) {}
1144 _LIBCPP_HIDE_FROM_ABI multiset(const multiset& __s, const allocator_type& __a)
1145 : __tree_(__s.__tree_.value_comp(), __a) {
1146 insert(__s.begin(), __s.end());
1147 }
1148
1149 # ifndef _LIBCPP_CXX03_LANG
1150 _LIBCPP_HIDE_FROM_ABI multiset(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
1151 : __tree_(__comp) {
1152 insert(__il.begin(), __il.end());
1153 }
1154
1155 _LIBCPP_HIDE_FROM_ABI
1156 multiset(initializer_list<value_type> __il, const value_compare& __comp, const allocator_type& __a)
1157 : __tree_(__comp, __a) {
1158 insert(__il.begin(), __il.end());
1159 }
1160
1161 # if _LIBCPP_STD_VER >= 14
1162 _LIBCPP_HIDE_FROM_ABI multiset(initializer_list<value_type> __il, const allocator_type& __a)
1163 : multiset(__il, key_compare(), __a) {}
1164 # endif
1165
1166 _LIBCPP_HIDE_FROM_ABI multiset& operator=(initializer_list<value_type> __il) {
1167 __tree_.__assign_multi(__il.begin(), __il.end());
1168 return *this;
1169 }
1170
1171 _LIBCPP_HIDE_FROM_ABI multiset& operator=(multiset&& __s) _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) {
1172 __tree_ = std::move(__s.__tree_);
1173 return *this;
1174 }
1175 # endif // _LIBCPP_CXX03_LANG
1176
1177 _LIBCPP_HIDE_FROM_ABI ~multiset() { static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
1178
1179 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1180 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1181 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1182 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
1183
1184 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1185 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
1186 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1187 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
1188
1189 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1190 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1191 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1192 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
1193
1194 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
1195 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1196 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
1197
1198 // modifiers:
1199 # ifndef _LIBCPP_CXX03_LANG
1200 template <class... _Args>
1201 _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {
1202 return __tree_.__emplace_multi(std::forward<_Args>(__args)...);
1203 }
1204 template <class... _Args>
1205 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
1206 return __tree_.__emplace_hint_multi(__p, std::forward<_Args>(__args)...);
1207 }
1208 # endif // _LIBCPP_CXX03_LANG
1209
1210 _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __v) { return __tree_.__insert_multi(__v); }
1211 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
1212 return __tree_.__insert_multi(__p, __v);
1213 }
1214
1215 template <class _InputIterator>
1216 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
1217 for (const_iterator __e = cend(); __f != __l; ++__f)
1218 __tree_.__insert_multi(__e, *__f);
1219 }
1220
1221 # if _LIBCPP_STD_VER >= 23
1222 template <_ContainerCompatibleRange<value_type> _Range>
1223 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
1224 const_iterator __end = cend();
1225 for (auto&& __element : __range) {
1226 __tree_.__insert_multi(__end, std::forward<decltype(__element)>(__element));
1227 }
1228 }
1229 # endif
1230
1231 # ifndef _LIBCPP_CXX03_LANG
1232 _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __v) { return __tree_.__insert_multi(std::move(__v)); }
1233
1234 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
1235 return __tree_.__insert_multi(__p, std::move(__v));
1236 }
1237
1238 _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
1239 # endif // _LIBCPP_CXX03_LANG
1240
1241 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p); }
1242 _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_multi(__k); }
1243 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) { return __tree_.erase(__f, __l); }
1244 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }
1245
1246 # if _LIBCPP_STD_VER >= 17
1247 _LIBCPP_HIDE_FROM_ABI iterator insert(node_type&& __nh) {
1248 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
1249 "node_type with incompatible allocator passed to multiset::insert()");
1250 return __tree_.template __node_handle_insert_multi<node_type>(std::move(__nh));
1251 }
1252 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {
1253 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
1254 "node_type with incompatible allocator passed to multiset::insert()");
1255 return __tree_.template __node_handle_insert_multi<node_type>(__hint, std::move(__nh));
1256 }
1257 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
1258 return __tree_.template __node_handle_extract<node_type>(__key);
1259 }
1260 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1261 return __tree_.template __node_handle_extract<node_type>(__it);
1262 }
1263 template <class _Compare2>
1264 _LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>& __source) {
1265 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1266 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
1267 __tree_.__node_handle_merge_multi(__source.__tree_);
1268 }
1269 template <class _Compare2>
1270 _LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>&& __source) {
1271 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1272 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
1273 __tree_.__node_handle_merge_multi(__source.__tree_);
1274 }
1275 template <class _Compare2>
1276 _LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>& __source) {
1277 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1278 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
1279 __tree_.__node_handle_merge_multi(__source.__tree_);
1280 }
1281 template <class _Compare2>
1282 _LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>&& __source) {
1283 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1284 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
1285 __tree_.__node_handle_merge_multi(__source.__tree_);
1286 }
1287 # endif
1288
1289 _LIBCPP_HIDE_FROM_ABI void swap(multiset& __s) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) {
1290 __tree_.swap(__s.__tree_);
1291 }
1292
1293 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
1294 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
1295 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
1296
1297 // set operations:
1298 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1299 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
1300 # if _LIBCPP_STD_VER >= 14
1301 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1302 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1303 return __tree_.find(__k);
1304 }
1305 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1306 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1307 return __tree_.find(__k);
1308 }
1309 # endif
1310
1311 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_multi(__k); }
1312 # if _LIBCPP_STD_VER >= 14
1313 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1314 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1315 return __tree_.__count_multi(__k);
1316 }
1317 # endif
1318
1319 # if _LIBCPP_STD_VER >= 20
1320 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1321 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1322 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1323 return find(__k) != end();
1324 }
1325 # endif // _LIBCPP_STD_VER >= 20
1326
1327 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
1328 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
1329 # if _LIBCPP_STD_VER >= 14
1330 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1331 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1332 return __tree_.lower_bound(__k);
1333 }
1334
1335 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1336 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1337 return __tree_.lower_bound(__k);
1338 }
1339 # endif
1340
1341 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
1342 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
1343 # if _LIBCPP_STD_VER >= 14
1344 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1345 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1346 return __tree_.upper_bound(__k);
1347 }
1348 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1349 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1350 return __tree_.upper_bound(__k);
1351 }
1352 # endif
1353
1354 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1355 return __tree_.__equal_range_multi(__k);
1356 }
1357 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1358 return __tree_.__equal_range_multi(__k);
1359 }
1360 # if _LIBCPP_STD_VER >= 14
1361 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1362 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1363 return __tree_.__equal_range_multi(__k);
1364 }
1365 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1366 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1367 return __tree_.__equal_range_multi(__k);
1368 }
1369 # endif
1370 };
1371
1372 # if _LIBCPP_STD_VER >= 17
1373 template <class _InputIterator,
1374 class _Compare = less<__iter_value_type<_InputIterator>>,
1375 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
1376 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1377 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1378 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1379 multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
1380 -> multiset<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
1381
1382 # if _LIBCPP_STD_VER >= 23
1383 template <ranges::input_range _Range,
1384 class _Compare = less<ranges::range_value_t<_Range>>,
1385 class _Allocator = allocator<ranges::range_value_t<_Range>>,
1386 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1387 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1388 multiset(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
1389 -> multiset<ranges::range_value_t<_Range>, _Compare, _Allocator>;
1390 # endif
1391
1392 template <class _Key,
1393 class _Compare = less<_Key>,
1394 class _Allocator = allocator<_Key>,
1395 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1396 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1397 multiset(initializer_list<_Key>,
1398 _Compare = _Compare(),
1399 _Allocator = _Allocator()) -> multiset<_Key, _Compare, _Allocator>;
1400
1401 template <class _InputIterator,
1402 class _Allocator,
1403 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1404 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1405 multiset(_InputIterator, _InputIterator, _Allocator)
1406 -> multiset<__iter_value_type<_InputIterator>, less<__iter_value_type<_InputIterator>>, _Allocator>;
1407
1408 # if _LIBCPP_STD_VER >= 23
1409 template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1410 multiset(from_range_t,
1411 _Range&&,
1412 _Allocator) -> multiset<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
1413 # endif
1414
1415 template <class _Key, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1416 multiset(initializer_list<_Key>, _Allocator) -> multiset<_Key, less<_Key>, _Allocator>;
1417 # endif
1418
1419 # ifndef _LIBCPP_CXX03_LANG
1420
1421 template <class _Key, class _Compare, class _Allocator>
1422 multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a)
1423 : __tree_(std::move(__s.__tree_), __a) {
1424 if (__a != __s.get_allocator()) {
1425 const_iterator __e = cend();
1426 while (!__s.empty())
1427 insert(__e, std::move(__s.__tree_.remove(__s.begin())->__value_));
1428 }
1429 }
1430
1431 # endif // _LIBCPP_CXX03_LANG
1432
1433 template <class _Key, class _Compare, class _Allocator>
1434 inline _LIBCPP_HIDE_FROM_ABI bool
1435 operator==(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1436 return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
1437 }
1438
1439 # if _LIBCPP_STD_VER <= 17
1440
1441 template <class _Key, class _Compare, class _Allocator>
1442 inline _LIBCPP_HIDE_FROM_ABI bool
1443 operator<(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1444 return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1445 }
1446
1447 template <class _Key, class _Compare, class _Allocator>
1448 inline _LIBCPP_HIDE_FROM_ABI bool
1449 operator!=(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1450 return !(__x == __y);
1451 }
1452
1453 template <class _Key, class _Compare, class _Allocator>
1454 inline _LIBCPP_HIDE_FROM_ABI bool
1455 operator>(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1456 return __y < __x;
1457 }
1458
1459 template <class _Key, class _Compare, class _Allocator>
1460 inline _LIBCPP_HIDE_FROM_ABI bool
1461 operator>=(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1462 return !(__x < __y);
1463 }
1464
1465 template <class _Key, class _Compare, class _Allocator>
1466 inline _LIBCPP_HIDE_FROM_ABI bool
1467 operator<=(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1468 return !(__y < __x);
1469 }
1470
1471 # else // _LIBCPP_STD_VER <= 17
1472
1473 template <class _Key, class _Compare, class _Allocator>
1474 _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
1475 operator<=>(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1476 return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), __synth_three_way);
1477 }
1478
1479 # endif // _LIBCPP_STD_VER <= 17
1480
1481 template <class _Key, class _Compare, class _Allocator>
1482 inline _LIBCPP_HIDE_FROM_ABI void
1483 swap(multiset<_Key, _Compare, _Allocator>& __x, multiset<_Key, _Compare, _Allocator>& __y)
1484 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
1485 __x.swap(__y);
1486 }
1487
1488 # if _LIBCPP_STD_VER >= 20
1489 template <class _Key, class _Compare, class _Allocator, class _Predicate>
1490 inline _LIBCPP_HIDE_FROM_ABI typename multiset<_Key, _Compare, _Allocator>::size_type
1491 erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
1492 return std::__libcpp_erase_if_container(__c, __pred);
1493 }
1494 # endif
1495
1496 template <class _Key, class _Compare, class _Allocator>
1497 struct __container_traits<multiset<_Key, _Compare, _Allocator> > {
1498 // http://eel.is/c++draft/associative.reqmts.except#2
1499 // For associative containers, if an exception is thrown by any operation from within
1500 // an insert or emplace function inserting a single element, the insertion has no effect.
1501 static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = true;
1502 };
1503
1504 _LIBCPP_END_NAMESPACE_STD
1505
1506 # if _LIBCPP_STD_VER >= 17
1507 _LIBCPP_BEGIN_NAMESPACE_STD
1508 namespace pmr {
1509 template <class _KeyT, class _CompareT = std::less<_KeyT>>
1510 using set _LIBCPP_AVAILABILITY_PMR = std::set<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
1511
1512 template <class _KeyT, class _CompareT = std::less<_KeyT>>
1513 using multiset _LIBCPP_AVAILABILITY_PMR = std::multiset<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
1514 } // namespace pmr
1515 _LIBCPP_END_NAMESPACE_STD
1516 # endif
1517
1518 _LIBCPP_POP_MACROS
1519
1520 # if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1521 # include <concepts>
1522 # include <cstdlib>
1523 # include <functional>
1524 # include <iterator>
1525 # include <stdexcept>
1526 # include <type_traits>
1527 # endif
1528 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
1529
1530 #endif // _LIBCPP_SET