Warning, /include/c++/v1/__cxx03/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___CXX03_SET
0011 #define _LIBCPP___CXX03_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 #include <__cxx03/__algorithm/equal.h>
0516 #include <__cxx03/__algorithm/lexicographical_compare.h>
0517 #include <__cxx03/__algorithm/lexicographical_compare_three_way.h>
0518 #include <__cxx03/__assert>
0519 #include <__cxx03/__config>
0520 #include <__cxx03/__functional/is_transparent.h>
0521 #include <__cxx03/__functional/operations.h>
0522 #include <__cxx03/__iterator/erase_if_container.h>
0523 #include <__cxx03/__iterator/iterator_traits.h>
0524 #include <__cxx03/__iterator/ranges_iterator_traits.h>
0525 #include <__cxx03/__iterator/reverse_iterator.h>
0526 #include <__cxx03/__memory/allocator.h>
0527 #include <__cxx03/__memory_resource/polymorphic_allocator.h>
0528 #include <__cxx03/__node_handle>
0529 #include <__cxx03/__ranges/concepts.h>
0530 #include <__cxx03/__ranges/container_compatible_range.h>
0531 #include <__cxx03/__ranges/from_range.h>
0532 #include <__cxx03/__tree>
0533 #include <__cxx03/__type_traits/is_allocator.h>
0534 #include <__cxx03/__utility/forward.h>
0535 #include <__cxx03/version>
0536
0537 // standard-mandated includes
0538
0539 // [iterator.range]
0540 #include <__cxx03/__iterator/access.h>
0541 #include <__cxx03/__iterator/data.h>
0542 #include <__cxx03/__iterator/empty.h>
0543 #include <__cxx03/__iterator/reverse_access.h>
0544 #include <__cxx03/__iterator/size.h>
0545
0546 // [associative.set.syn]
0547 #include <__cxx03/compare>
0548 #include <__cxx03/initializer_list>
0549
0550 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0551 # pragma GCC system_header
0552 #endif
0553
0554 _LIBCPP_PUSH_MACROS
0555 #include <__cxx03/__undef_macros>
0556
0557 _LIBCPP_BEGIN_NAMESPACE_STD
0558
0559 template <class _Key, class _Compare, class _Allocator>
0560 class multiset;
0561
0562 template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> >
0563 class _LIBCPP_TEMPLATE_VIS set {
0564 public:
0565 // types:
0566 typedef _Key key_type;
0567 typedef key_type value_type;
0568 typedef __type_identity_t<_Compare> key_compare;
0569 typedef key_compare value_compare;
0570 typedef __type_identity_t<_Allocator> allocator_type;
0571 typedef value_type& reference;
0572 typedef const value_type& const_reference;
0573
0574 static_assert(is_same<typename allocator_type::value_type, value_type>::value,
0575 "Allocator::value_type must be same type as value_type");
0576
0577 private:
0578 typedef __tree<value_type, value_compare, allocator_type> __base;
0579 typedef allocator_traits<allocator_type> __alloc_traits;
0580
0581 static_assert(__check_valid_allocator<allocator_type>::value, "");
0582
0583 __base __tree_;
0584
0585 public:
0586 typedef typename __base::pointer pointer;
0587 typedef typename __base::const_pointer const_pointer;
0588 typedef typename __base::size_type size_type;
0589 typedef typename __base::difference_type difference_type;
0590 typedef typename __base::const_iterator iterator;
0591 typedef typename __base::const_iterator const_iterator;
0592 typedef std::reverse_iterator<iterator> reverse_iterator;
0593 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0594
0595 #if _LIBCPP_STD_VER >= 17
0596 typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
0597 typedef __insert_return_type<iterator, node_type> insert_return_type;
0598 #endif
0599
0600 template <class _Key2, class _Compare2, class _Alloc2>
0601 friend class _LIBCPP_TEMPLATE_VIS set;
0602 template <class _Key2, class _Compare2, class _Alloc2>
0603 friend class _LIBCPP_TEMPLATE_VIS multiset;
0604
0605 _LIBCPP_HIDE_FROM_ABI set() _NOEXCEPT_(
0606 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&
0607 is_nothrow_copy_constructible<key_compare>::value)
0608 : __tree_(value_compare()) {}
0609
0610 _LIBCPP_HIDE_FROM_ABI explicit set(const value_compare& __comp) _NOEXCEPT_(
0611 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_copy_constructible<key_compare>::value)
0612 : __tree_(__comp) {}
0613
0614 _LIBCPP_HIDE_FROM_ABI explicit set(const value_compare& __comp, const allocator_type& __a) : __tree_(__comp, __a) {}
0615 template <class _InputIterator>
0616 _LIBCPP_HIDE_FROM_ABI set(_InputIterator __f, _InputIterator __l, const value_compare& __comp = value_compare())
0617 : __tree_(__comp) {
0618 insert(__f, __l);
0619 }
0620
0621 template <class _InputIterator>
0622 _LIBCPP_HIDE_FROM_ABI
0623 set(_InputIterator __f, _InputIterator __l, const value_compare& __comp, const allocator_type& __a)
0624 : __tree_(__comp, __a) {
0625 insert(__f, __l);
0626 }
0627
0628 #if _LIBCPP_STD_VER >= 23
0629 template <_ContainerCompatibleRange<value_type> _Range>
0630 _LIBCPP_HIDE_FROM_ABI
0631 set(from_range_t,
0632 _Range&& __range,
0633 const key_compare& __comp = key_compare(),
0634 const allocator_type& __a = allocator_type())
0635 : __tree_(__comp, __a) {
0636 insert_range(std::forward<_Range>(__range));
0637 }
0638 #endif
0639
0640 #if _LIBCPP_STD_VER >= 14
0641 template <class _InputIterator>
0642 _LIBCPP_HIDE_FROM_ABI set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
0643 : set(__f, __l, key_compare(), __a) {}
0644 #endif
0645
0646 #if _LIBCPP_STD_VER >= 23
0647 template <_ContainerCompatibleRange<value_type> _Range>
0648 _LIBCPP_HIDE_FROM_ABI set(from_range_t, _Range&& __range, const allocator_type& __a)
0649 : set(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
0650 #endif
0651
0652 _LIBCPP_HIDE_FROM_ABI set(const set& __s) : __tree_(__s.__tree_) { insert(__s.begin(), __s.end()); }
0653
0654 _LIBCPP_HIDE_FROM_ABI set& operator=(const set& __s) {
0655 __tree_ = __s.__tree_;
0656 return *this;
0657 }
0658
0659 #ifndef _LIBCPP_CXX03_LANG
0660 _LIBCPP_HIDE_FROM_ABI set(set&& __s) noexcept(is_nothrow_move_constructible<__base>::value)
0661 : __tree_(std::move(__s.__tree_)) {}
0662 #endif // _LIBCPP_CXX03_LANG
0663
0664 _LIBCPP_HIDE_FROM_ABI explicit set(const allocator_type& __a) : __tree_(__a) {}
0665
0666 _LIBCPP_HIDE_FROM_ABI set(const set& __s, const allocator_type& __a) : __tree_(__s.__tree_.value_comp(), __a) {
0667 insert(__s.begin(), __s.end());
0668 }
0669
0670 #ifndef _LIBCPP_CXX03_LANG
0671 _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __a);
0672
0673 _LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
0674 : __tree_(__comp) {
0675 insert(__il.begin(), __il.end());
0676 }
0677
0678 _LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const value_compare& __comp, const allocator_type& __a)
0679 : __tree_(__comp, __a) {
0680 insert(__il.begin(), __il.end());
0681 }
0682
0683 # if _LIBCPP_STD_VER >= 14
0684 _LIBCPP_HIDE_FROM_ABI set(initializer_list<value_type> __il, const allocator_type& __a)
0685 : set(__il, key_compare(), __a) {}
0686 # endif
0687
0688 _LIBCPP_HIDE_FROM_ABI set& operator=(initializer_list<value_type> __il) {
0689 __tree_.__assign_unique(__il.begin(), __il.end());
0690 return *this;
0691 }
0692
0693 _LIBCPP_HIDE_FROM_ABI set& operator=(set&& __s) noexcept(is_nothrow_move_assignable<__base>::value) {
0694 __tree_ = std::move(__s.__tree_);
0695 return *this;
0696 }
0697 #endif // _LIBCPP_CXX03_LANG
0698
0699 _LIBCPP_HIDE_FROM_ABI ~set() { static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
0700
0701 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
0702 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
0703 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
0704 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
0705
0706 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
0707 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
0708 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
0709 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
0710
0711 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
0712 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
0713 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
0714 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
0715
0716 _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
0717 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
0718 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
0719
0720 // modifiers:
0721 #ifndef _LIBCPP_CXX03_LANG
0722 template <class... _Args>
0723 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> emplace(_Args&&... __args) {
0724 return __tree_.__emplace_unique(std::forward<_Args>(__args)...);
0725 }
0726 template <class... _Args>
0727 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
0728 return __tree_.__emplace_hint_unique(__p, std::forward<_Args>(__args)...);
0729 }
0730 #endif // _LIBCPP_CXX03_LANG
0731
0732 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__insert_unique(__v); }
0733 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
0734 return __tree_.__insert_unique(__p, __v);
0735 }
0736
0737 template <class _InputIterator>
0738 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
0739 for (const_iterator __e = cend(); __f != __l; ++__f)
0740 __tree_.__insert_unique(__e, *__f);
0741 }
0742
0743 #if _LIBCPP_STD_VER >= 23
0744 template <_ContainerCompatibleRange<value_type> _Range>
0745 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
0746 const_iterator __end = cend();
0747 for (auto&& __element : __range) {
0748 __tree_.__insert_unique(__end, std::forward<decltype(__element)>(__element));
0749 }
0750 }
0751 #endif
0752
0753 #ifndef _LIBCPP_CXX03_LANG
0754 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(value_type&& __v) {
0755 return __tree_.__insert_unique(std::move(__v));
0756 }
0757
0758 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
0759 return __tree_.__insert_unique(__p, std::move(__v));
0760 }
0761
0762 _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
0763 #endif // _LIBCPP_CXX03_LANG
0764
0765 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p); }
0766 _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_unique(__k); }
0767 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) { return __tree_.erase(__f, __l); }
0768 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }
0769
0770 #if _LIBCPP_STD_VER >= 17
0771 _LIBCPP_HIDE_FROM_ABI insert_return_type insert(node_type&& __nh) {
0772 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
0773 "node_type with incompatible allocator passed to set::insert()");
0774 return __tree_.template __node_handle_insert_unique< node_type, insert_return_type>(std::move(__nh));
0775 }
0776 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {
0777 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
0778 "node_type with incompatible allocator passed to set::insert()");
0779 return __tree_.template __node_handle_insert_unique<node_type>(__hint, std::move(__nh));
0780 }
0781 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
0782 return __tree_.template __node_handle_extract<node_type>(__key);
0783 }
0784 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
0785 return __tree_.template __node_handle_extract<node_type>(__it);
0786 }
0787 template <class _Compare2>
0788 _LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>& __source) {
0789 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
0790 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
0791 __tree_.__node_handle_merge_unique(__source.__tree_);
0792 }
0793 template <class _Compare2>
0794 _LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>&& __source) {
0795 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
0796 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
0797 __tree_.__node_handle_merge_unique(__source.__tree_);
0798 }
0799 template <class _Compare2>
0800 _LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>& __source) {
0801 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
0802 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
0803 __tree_.__node_handle_merge_unique(__source.__tree_);
0804 }
0805 template <class _Compare2>
0806 _LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>&& __source) {
0807 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
0808 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
0809 __tree_.__node_handle_merge_unique(__source.__tree_);
0810 }
0811 #endif
0812
0813 _LIBCPP_HIDE_FROM_ABI void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) { __tree_.swap(__s.__tree_); }
0814
0815 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return __tree_.__alloc(); }
0816 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp(); }
0817 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __tree_.value_comp(); }
0818
0819 // set operations:
0820 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
0821 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
0822 #if _LIBCPP_STD_VER >= 14
0823 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0824 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
0825 return __tree_.find(__k);
0826 }
0827 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0828 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
0829 return __tree_.find(__k);
0830 }
0831 #endif
0832
0833 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_unique(__k); }
0834 #if _LIBCPP_STD_VER >= 14
0835 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0836 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
0837 return __tree_.__count_multi(__k);
0838 }
0839 #endif
0840
0841 #if _LIBCPP_STD_VER >= 20
0842 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
0843 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0844 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
0845 return find(__k) != end();
0846 }
0847 #endif // _LIBCPP_STD_VER >= 20
0848
0849 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
0850 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
0851 #if _LIBCPP_STD_VER >= 14
0852 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0853 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
0854 return __tree_.lower_bound(__k);
0855 }
0856
0857 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0858 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
0859 return __tree_.lower_bound(__k);
0860 }
0861 #endif
0862
0863 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
0864 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
0865 #if _LIBCPP_STD_VER >= 14
0866 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0867 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
0868 return __tree_.upper_bound(__k);
0869 }
0870 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0871 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
0872 return __tree_.upper_bound(__k);
0873 }
0874 #endif
0875
0876 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
0877 return __tree_.__equal_range_unique(__k);
0878 }
0879 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
0880 return __tree_.__equal_range_unique(__k);
0881 }
0882 #if _LIBCPP_STD_VER >= 14
0883 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0884 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
0885 return __tree_.__equal_range_multi(__k);
0886 }
0887 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
0888 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
0889 return __tree_.__equal_range_multi(__k);
0890 }
0891 #endif
0892 };
0893
0894 #if _LIBCPP_STD_VER >= 17
0895 template <class _InputIterator,
0896 class _Compare = less<__iter_value_type<_InputIterator>>,
0897 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
0898 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
0899 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
0900 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
0901 set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
0902 -> set<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
0903
0904 # if _LIBCPP_STD_VER >= 23
0905 template <ranges::input_range _Range,
0906 class _Compare = less<ranges::range_value_t<_Range>>,
0907 class _Allocator = allocator<ranges::range_value_t<_Range>>,
0908 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
0909 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
0910 set(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
0911 -> set<ranges::range_value_t<_Range>, _Compare, _Allocator>;
0912 # endif
0913
0914 template <class _Key,
0915 class _Compare = less<_Key>,
0916 class _Allocator = allocator<_Key>,
0917 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
0918 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
0919 set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) -> set<_Key, _Compare, _Allocator>;
0920
0921 template <class _InputIterator,
0922 class _Allocator,
0923 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
0924 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
0925 set(_InputIterator,
0926 _InputIterator,
0927 _Allocator) -> set<__iter_value_type<_InputIterator>, less<__iter_value_type<_InputIterator>>, _Allocator>;
0928
0929 # if _LIBCPP_STD_VER >= 23
0930 template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
0931 set(from_range_t,
0932 _Range&&,
0933 _Allocator) -> set<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
0934 # endif
0935
0936 template <class _Key, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
0937 set(initializer_list<_Key>, _Allocator) -> set<_Key, less<_Key>, _Allocator>;
0938 #endif
0939
0940 #ifndef _LIBCPP_CXX03_LANG
0941
0942 template <class _Key, class _Compare, class _Allocator>
0943 set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a) : __tree_(std::move(__s.__tree_), __a) {
0944 if (__a != __s.get_allocator()) {
0945 const_iterator __e = cend();
0946 while (!__s.empty())
0947 insert(__e, std::move(__s.__tree_.remove(__s.begin())->__value_));
0948 }
0949 }
0950
0951 #endif // _LIBCPP_CXX03_LANG
0952
0953 template <class _Key, class _Compare, class _Allocator>
0954 inline _LIBCPP_HIDE_FROM_ABI bool
0955 operator==(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0956 return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
0957 }
0958
0959 #if _LIBCPP_STD_VER <= 17
0960
0961 template <class _Key, class _Compare, class _Allocator>
0962 inline _LIBCPP_HIDE_FROM_ABI bool
0963 operator<(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0964 return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
0965 }
0966
0967 template <class _Key, class _Compare, class _Allocator>
0968 inline _LIBCPP_HIDE_FROM_ABI bool
0969 operator!=(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0970 return !(__x == __y);
0971 }
0972
0973 template <class _Key, class _Compare, class _Allocator>
0974 inline _LIBCPP_HIDE_FROM_ABI bool
0975 operator>(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0976 return __y < __x;
0977 }
0978
0979 template <class _Key, class _Compare, class _Allocator>
0980 inline _LIBCPP_HIDE_FROM_ABI bool
0981 operator>=(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0982 return !(__x < __y);
0983 }
0984
0985 template <class _Key, class _Compare, class _Allocator>
0986 inline _LIBCPP_HIDE_FROM_ABI bool
0987 operator<=(const set<_Key, _Compare, _Allocator>& __x, const set<_Key, _Compare, _Allocator>& __y) {
0988 return !(__y < __x);
0989 }
0990
0991 #else // _LIBCPP_STD_VER <= 17
0992
0993 template <class _Key, class _Allocator>
0994 _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
0995 operator<=>(const set<_Key, _Allocator>& __x, const set<_Key, _Allocator>& __y) {
0996 return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
0997 }
0998
0999 #endif // _LIBCPP_STD_VER <= 17
1000
1001 // specialized algorithms:
1002 template <class _Key, class _Compare, class _Allocator>
1003 inline _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
1009 template <class _Key, class _Compare, class _Allocator, class _Predicate>
1010 inline _LIBCPP_HIDE_FROM_ABI typename set<_Key, _Compare, _Allocator>::size_type
1011 erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
1012 return std::__libcpp_erase_if_container(__c, __pred);
1013 }
1014 #endif
1015
1016 template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> >
1017 class _LIBCPP_TEMPLATE_VIS multiset {
1018 public:
1019 // types:
1020 typedef _Key key_type;
1021 typedef key_type value_type;
1022 typedef __type_identity_t<_Compare> key_compare;
1023 typedef key_compare value_compare;
1024 typedef __type_identity_t<_Allocator> allocator_type;
1025 typedef value_type& reference;
1026 typedef const value_type& const_reference;
1027
1028 static_assert(is_same<typename allocator_type::value_type, value_type>::value,
1029 "Allocator::value_type must be same type as value_type");
1030
1031 private:
1032 typedef __tree<value_type, value_compare, allocator_type> __base;
1033 typedef allocator_traits<allocator_type> __alloc_traits;
1034
1035 static_assert(__check_valid_allocator<allocator_type>::value, "");
1036
1037 __base __tree_;
1038
1039 public:
1040 typedef typename __base::pointer pointer;
1041 typedef typename __base::const_pointer const_pointer;
1042 typedef typename __base::size_type size_type;
1043 typedef typename __base::difference_type difference_type;
1044 typedef typename __base::const_iterator iterator;
1045 typedef typename __base::const_iterator const_iterator;
1046 typedef std::reverse_iterator<iterator> reverse_iterator;
1047 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1048
1049 #if _LIBCPP_STD_VER >= 17
1050 typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
1051 #endif
1052
1053 template <class _Key2, class _Compare2, class _Alloc2>
1054 friend class _LIBCPP_TEMPLATE_VIS set;
1055 template <class _Key2, class _Compare2, class _Alloc2>
1056 friend class _LIBCPP_TEMPLATE_VIS multiset;
1057
1058 // construct/copy/destroy:
1059 _LIBCPP_HIDE_FROM_ABI multiset() _NOEXCEPT_(
1060 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&
1061 is_nothrow_copy_constructible<key_compare>::value)
1062 : __tree_(value_compare()) {}
1063
1064 _LIBCPP_HIDE_FROM_ABI explicit multiset(const value_compare& __comp) _NOEXCEPT_(
1065 is_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) {}
1070 template <class _InputIterator>
1071 _LIBCPP_HIDE_FROM_ABI multiset(_InputIterator __f, _InputIterator __l, const value_compare& __comp = value_compare())
1072 : __tree_(__comp) {
1073 insert(__f, __l);
1074 }
1075
1076 #if _LIBCPP_STD_VER >= 14
1077 template <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
1082 template <class _InputIterator>
1083 _LIBCPP_HIDE_FROM_ABI
1084 multiset(_InputIterator __f, _InputIterator __l, const value_compare& __comp, const allocator_type& __a)
1085 : __tree_(__comp, __a) {
1086 insert(__f, __l);
1087 }
1088
1089 #if _LIBCPP_STD_VER >= 23
1090 template <_ContainerCompatibleRange<value_type> _Range>
1091 _LIBCPP_HIDE_FROM_ABI
1092 multiset(from_range_t,
1093 _Range&& __range,
1094 const key_compare& __comp = key_compare(),
1095 const allocator_type& __a = allocator_type())
1096 : __tree_(__comp, __a) {
1097 insert_range(std::forward<_Range>(__range));
1098 }
1099
1100 template <_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())) {
1108 insert(__s.begin(), __s.end());
1109 }
1110
1111 _LIBCPP_HIDE_FROM_ABI multiset& operator=(const multiset& __s) {
1112 __tree_ = __s.__tree_;
1113 return *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) {
1125 insert(__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) {
1131 insert(__il.begin(), __il.end());
1132 }
1133
1134 _LIBCPP_HIDE_FROM_ABI
1135 multiset(initializer_list<value_type> __il, const value_compare& __comp, const allocator_type& __a)
1136 : __tree_(__comp, __a) {
1137 insert(__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());
1147 return *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_);
1152 return *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
1179 template <class... _Args>
1180 _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {
1181 return __tree_.__emplace_multi(std::forward<_Args>(__args)...);
1182 }
1183 template <class... _Args>
1184 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
1185 return __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) {
1191 return __tree_.__insert_multi(__p, __v);
1192 }
1193
1194 template <class _InputIterator>
1195 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
1196 for (const_iterator __e = cend(); __f != __l; ++__f)
1197 __tree_.__insert_multi(__e, *__f);
1198 }
1199
1200 #if _LIBCPP_STD_VER >= 23
1201 template <_ContainerCompatibleRange<value_type> _Range>
1202 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
1203 const_iterator __end = cend();
1204 for (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) {
1214 return __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()");
1229 return __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()");
1234 return __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) {
1237 return __tree_.template __node_handle_extract<node_type>(__key);
1238 }
1239 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1240 return __tree_.template __node_handle_extract<node_type>(__it);
1241 }
1242 template <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 }
1248 template <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 }
1254 template <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 }
1260 template <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
1280 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1281 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1282 return __tree_.find(__k);
1283 }
1284 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1285 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1286 return __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
1292 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1293 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1294 return __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(); }
1300 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1301 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1302 return 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
1309 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1310 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1311 return __tree_.lower_bound(__k);
1312 }
1313
1314 template <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 {
1316 return __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
1323 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1324 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1325 return __tree_.upper_bound(__k);
1326 }
1327 template <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 {
1329 return __tree_.upper_bound(__k);
1330 }
1331 #endif
1332
1333 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1334 return __tree_.__equal_range_multi(__k);
1335 }
1336 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1337 return __tree_.__equal_range_multi(__k);
1338 }
1339 #if _LIBCPP_STD_VER >= 14
1340 template <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) {
1342 return __tree_.__equal_range_multi(__k);
1343 }
1344 template <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 {
1346 return __tree_.__equal_range_multi(__k);
1347 }
1348 #endif
1349 };
1350
1351 #if _LIBCPP_STD_VER >= 17
1352 template <class _InputIterator,
1353 class _Compare = less<__iter_value_type<_InputIterator>>,
1354 class _Allocator = allocator<__iter_value_type<_InputIterator>>,
1355 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1356 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1357 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1358 multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
1359 -> multiset<__iter_value_type<_InputIterator>, _Compare, _Allocator>;
1360
1361 # if _LIBCPP_STD_VER >= 23
1362 template <ranges::input_range _Range,
1363 class _Compare = less<ranges::range_value_t<_Range>>,
1364 class _Allocator = allocator<ranges::range_value_t<_Range>>,
1365 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1366 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1367 multiset(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
1368 -> multiset<ranges::range_value_t<_Range>, _Compare, _Allocator>;
1369 # endif
1370
1371 template <class _Key,
1372 class _Compare = less<_Key>,
1373 class _Allocator = allocator<_Key>,
1374 class = enable_if_t<__is_allocator<_Allocator>::value, void>,
1375 class = enable_if_t<!__is_allocator<_Compare>::value, void>>
1376 multiset(initializer_list<_Key>,
1377 _Compare = _Compare(),
1378 _Allocator = _Allocator()) -> multiset<_Key, _Compare, _Allocator>;
1379
1380 template <class _InputIterator,
1381 class _Allocator,
1382 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1383 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1384 multiset(_InputIterator, _InputIterator, _Allocator)
1385 -> multiset<__iter_value_type<_InputIterator>, less<__iter_value_type<_InputIterator>>, _Allocator>;
1386
1387 # if _LIBCPP_STD_VER >= 23
1388 template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1389 multiset(from_range_t,
1390 _Range&&,
1391 _Allocator) -> multiset<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>;
1392 # endif
1393
1394 template <class _Key, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1395 multiset(initializer_list<_Key>, _Allocator) -> multiset<_Key, less<_Key>, _Allocator>;
1396 #endif
1397
1398 #ifndef _LIBCPP_CXX03_LANG
1399
1400 template <class _Key, class _Compare, class _Allocator>
1401 multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a)
1402 : __tree_(std::move(__s.__tree_), __a) {
1403 if (__a != __s.get_allocator()) {
1404 const_iterator __e = cend();
1405 while (!__s.empty())
1406 insert(__e, std::move(__s.__tree_.remove(__s.begin())->__value_));
1407 }
1408 }
1409
1410 #endif // _LIBCPP_CXX03_LANG
1411
1412 template <class _Key, class _Compare, class _Allocator>
1413 inline _LIBCPP_HIDE_FROM_ABI bool
1414 operator==(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1415 return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
1416 }
1417
1418 #if _LIBCPP_STD_VER <= 17
1419
1420 template <class _Key, class _Compare, class _Allocator>
1421 inline _LIBCPP_HIDE_FROM_ABI bool
1422 operator<(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1423 return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1424 }
1425
1426 template <class _Key, class _Compare, class _Allocator>
1427 inline _LIBCPP_HIDE_FROM_ABI bool
1428 operator!=(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1429 return !(__x == __y);
1430 }
1431
1432 template <class _Key, class _Compare, class _Allocator>
1433 inline _LIBCPP_HIDE_FROM_ABI bool
1434 operator>(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1435 return __y < __x;
1436 }
1437
1438 template <class _Key, class _Compare, class _Allocator>
1439 inline _LIBCPP_HIDE_FROM_ABI bool
1440 operator>=(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1441 return !(__x < __y);
1442 }
1443
1444 template <class _Key, class _Compare, class _Allocator>
1445 inline _LIBCPP_HIDE_FROM_ABI bool
1446 operator<=(const multiset<_Key, _Compare, _Allocator>& __x, const multiset<_Key, _Compare, _Allocator>& __y) {
1447 return !(__y < __x);
1448 }
1449
1450 #else // _LIBCPP_STD_VER <= 17
1451
1452 template <class _Key, class _Allocator>
1453 _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
1454 operator<=>(const multiset<_Key, _Allocator>& __x, const multiset<_Key, _Allocator>& __y) {
1455 return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), __synth_three_way);
1456 }
1457
1458 #endif // _LIBCPP_STD_VER <= 17
1459
1460 template <class _Key, class _Compare, class _Allocator>
1461 inline _LIBCPP_HIDE_FROM_ABI void
1462 swap(multiset<_Key, _Compare, _Allocator>& __x, multiset<_Key, _Compare, _Allocator>& __y)
1463 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
1464 __x.swap(__y);
1465 }
1466
1467 #if _LIBCPP_STD_VER >= 20
1468 template <class _Key, class _Compare, class _Allocator, class _Predicate>
1469 inline _LIBCPP_HIDE_FROM_ABI typename multiset<_Key, _Compare, _Allocator>::size_type
1470 erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
1471 return std::__libcpp_erase_if_container(__c, __pred);
1472 }
1473 #endif
1474
1475 _LIBCPP_END_NAMESPACE_STD
1476
1477 #if _LIBCPP_STD_VER >= 17
1478 _LIBCPP_BEGIN_NAMESPACE_STD
1479 namespace pmr {
1480 template <class _KeyT, class _CompareT = std::less<_KeyT>>
1481 using set _LIBCPP_AVAILABILITY_PMR = std::set<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
1482
1483 template <class _KeyT, class _CompareT = std::less<_KeyT>>
1484 using multiset _LIBCPP_AVAILABILITY_PMR = std::multiset<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>;
1485 } // namespace pmr
1486 _LIBCPP_END_NAMESPACE_STD
1487 #endif
1488
1489 _LIBCPP_POP_MACROS
1490
1491 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1492 # include <__cxx03/concepts>
1493 # include <__cxx03/cstdlib>
1494 # include <__cxx03/functional>
1495 # include <__cxx03/iterator>
1496 # include <__cxx03/stdexcept>
1497 # include <__cxx03/type_traits>
1498 #endif
1499
1500 #endif // _LIBCPP___CXX03_SET