2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
20 template <class Key, class T, class Compare = less<Key>,
21 class Allocator = allocator<pair<const Key, T>>>
27 typedef T mapped_type;
28 typedef pair<const key_type, mapped_type> value_type;
29 typedef Compare key_compare;
30 typedef Allocator allocator_type;
31 typedef typename allocator_type::reference reference;
32 typedef typename allocator_type::const_reference const_reference;
33 typedef typename allocator_type::pointer pointer;
34 typedef typename allocator_type::const_pointer const_pointer;
35 typedef typename allocator_type::size_type size_type;
36 typedef typename allocator_type::difference_type difference_type;
38 typedef implementation-defined iterator;
39 typedef implementation-defined const_iterator;
40 typedef std::reverse_iterator<iterator> reverse_iterator;
41 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
42 typedef unspecified node_type; // C++17
43 typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
51 value_compare(key_compare c);
53 typedef bool result_type; // deprecated in C++17, removed in C++20
54 typedef value_type first_argument_type; // deprecated in C++17, removed in C++20
55 typedef value_type second_argument_type; // deprecated in C++17, removed in C++20
56 bool operator()(const value_type& x, const value_type& y) const;
59 // construct/copy/destroy:
62 is_nothrow_default_constructible<allocator_type>::value &&
63 is_nothrow_default_constructible<key_compare>::value &&
64 is_nothrow_copy_constructible<key_compare>::value);
65 explicit map(const key_compare& comp);
66 map(const key_compare& comp, const allocator_type& a);
67 template <class InputIterator>
68 map(InputIterator first, InputIterator last,
69 const key_compare& comp = key_compare());
70 template <class InputIterator>
71 map(InputIterator first, InputIterator last,
72 const key_compare& comp, const allocator_type& a);
73 template<container-compatible-range<value_type> R>
74 map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
78 is_nothrow_move_constructible<allocator_type>::value &&
79 is_nothrow_move_constructible<key_compare>::value);
80 explicit map(const allocator_type& a);
81 map(const map& m, const allocator_type& a);
82 map(map&& m, const allocator_type& a);
83 map(initializer_list<value_type> il, const key_compare& comp = key_compare());
84 map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
85 template <class InputIterator>
86 map(InputIterator first, InputIterator last, const allocator_type& a)
87 : map(first, last, Compare(), a) {} // C++14
88 template<container-compatible-range<value_type> R>
89 map(from_range_t, R&& rg, const Allocator& a))
90 : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
91 map(initializer_list<value_type> il, const allocator_type& a)
92 : map(il, Compare(), a) {} // C++14
95 map& operator=(const map& m);
96 map& operator=(map&& m)
98 allocator_type::propagate_on_container_move_assignment::value &&
99 is_nothrow_move_assignable<allocator_type>::value &&
100 is_nothrow_move_assignable<key_compare>::value);
101 map& operator=(initializer_list<value_type> il);
104 iterator begin() noexcept;
105 const_iterator begin() const noexcept;
106 iterator end() noexcept;
107 const_iterator end() const noexcept;
109 reverse_iterator rbegin() noexcept;
110 const_reverse_iterator rbegin() const noexcept;
111 reverse_iterator rend() noexcept;
112 const_reverse_iterator rend() const noexcept;
114 const_iterator cbegin() const noexcept;
115 const_iterator cend() const noexcept;
116 const_reverse_iterator crbegin() const noexcept;
117 const_reverse_iterator crend() const noexcept;
120 bool empty() const noexcept;
121 size_type size() const noexcept;
122 size_type max_size() const noexcept;
125 mapped_type& operator[](const key_type& k);
126 mapped_type& operator[](key_type&& k);
128 mapped_type& at(const key_type& k);
129 const mapped_type& at(const key_type& k) const;
132 template <class... Args>
133 pair<iterator, bool> emplace(Args&&... args);
134 template <class... Args>
135 iterator emplace_hint(const_iterator position, Args&&... args);
136 pair<iterator, bool> insert(const value_type& v);
137 pair<iterator, bool> insert( value_type&& v); // C++17
139 pair<iterator, bool> insert(P&& p);
140 iterator insert(const_iterator position, const value_type& v);
141 iterator insert(const_iterator position, value_type&& v); // C++17
143 iterator insert(const_iterator position, P&& p);
144 template <class InputIterator>
145 void insert(InputIterator first, InputIterator last);
146 template<container-compatible-range<value_type> R>
147 void insert_range(R&& rg); // C++23
148 void insert(initializer_list<value_type> il);
150 node_type extract(const_iterator position); // C++17
151 node_type extract(const key_type& x); // C++17
152 insert_return_type insert(node_type&& nh); // C++17
153 iterator insert(const_iterator hint, node_type&& nh); // C++17
155 template <class... Args>
156 pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
157 template <class... Args>
158 pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17
159 template <class... Args>
160 iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
161 template <class... Args>
162 iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17
164 pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
166 pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
168 iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
170 iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
172 iterator erase(const_iterator position);
173 iterator erase(iterator position); // C++14
174 size_type erase(const key_type& k);
175 iterator erase(const_iterator first, const_iterator last);
176 void clear() noexcept;
179 void merge(map<Key, T, C2, Allocator>& source); // C++17
181 void merge(map<Key, T, C2, Allocator>&& source); // C++17
183 void merge(multimap<Key, T, C2, Allocator>& source); // C++17
185 void merge(multimap<Key, T, C2, Allocator>&& source); // C++17
188 noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
189 is_nothrow_swappable<key_compare>::value); // C++17
192 allocator_type get_allocator() const noexcept;
193 key_compare key_comp() const;
194 value_compare value_comp() const;
197 iterator find(const key_type& k);
198 const_iterator find(const key_type& k) const;
200 iterator find(const K& x); // C++14
202 const_iterator find(const K& x) const; // C++14
205 size_type count(const K& x) const; // C++14
206 size_type count(const key_type& k) const;
208 bool contains(const key_type& x) const; // C++20
209 template<class K> bool contains(const K& x) const; // C++20
211 iterator lower_bound(const key_type& k);
212 const_iterator lower_bound(const key_type& k) const;
214 iterator lower_bound(const K& x); // C++14
216 const_iterator lower_bound(const K& x) const; // C++14
218 iterator upper_bound(const key_type& k);
219 const_iterator upper_bound(const key_type& k) const;
221 iterator upper_bound(const K& x); // C++14
223 const_iterator upper_bound(const K& x) const; // C++14
225 pair<iterator,iterator> equal_range(const key_type& k);
226 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
228 pair<iterator,iterator> equal_range(const K& x); // C++14
230 pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14
233 template <class InputIterator,
234 class Compare = less<iter_key_t<InputIterator>>,
235 class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
236 map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
237 -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17
239 template<ranges::input_range R, class Compare = less<range-key-type<R>,
240 class Allocator = allocator<range-to-alloc-type<R>>>
241 map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
242 -> map<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23
244 template<class Key, class T, class Compare = less<Key>,
245 class Allocator = allocator<pair<const Key, T>>>
246 map(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
247 -> map<Key, T, Compare, Allocator>; // C++17
249 template <class InputIterator, class Allocator>
250 map(InputIterator, InputIterator, Allocator)
251 -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, less<iter_key_t<InputIterator>>,
254 template<ranges::input_range R, class Allocator>
255 map(from_range_t, R&&, Allocator)
256 -> map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23
258 template<class Key, class T, class Allocator>
259 map(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>; // C++17
261 template <class Key, class T, class Compare, class Allocator>
263 operator==(const map<Key, T, Compare, Allocator>& x,
264 const map<Key, T, Compare, Allocator>& y);
266 template <class Key, class T, class Compare, class Allocator>
268 operator< (const map<Key, T, Compare, Allocator>& x,
269 const map<Key, T, Compare, Allocator>& y); // removed in C++20
271 template <class Key, class T, class Compare, class Allocator>
273 operator!=(const map<Key, T, Compare, Allocator>& x,
274 const map<Key, T, Compare, Allocator>& y); // removed in C++20
276 template <class Key, class T, class Compare, class Allocator>
278 operator> (const map<Key, T, Compare, Allocator>& x,
279 const map<Key, T, Compare, Allocator>& y); // removed in C++20
281 template <class Key, class T, class Compare, class Allocator>
283 operator>=(const map<Key, T, Compare, Allocator>& x,
284 const map<Key, T, Compare, Allocator>& y); // removed in C++20
286 template <class Key, class T, class Compare, class Allocator>
288 operator<=(const map<Key, T, Compare, Allocator>& x,
289 const map<Key, T, Compare, Allocator>& y); // removed in C++20
291 template<class Key, class T, class Compare, class Allocator>
292 synth-three-way-result<pair<const Key, T>>
293 operator<=>(const map<Key, T, Compare, Allocator>& x,
294 const map<Key, T, Compare, Allocator>& y); // since C++20
296 // specialized algorithms:
297 template <class Key, class T, class Compare, class Allocator>
299 swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
300 noexcept(noexcept(x.swap(y)));
302 template <class Key, class T, class Compare, class Allocator, class Predicate>
303 typename map<Key, T, Compare, Allocator>::size_type
304 erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
307 template <class Key, class T, class Compare = less<Key>,
308 class Allocator = allocator<pair<const Key, T>>>
313 typedef Key key_type;
314 typedef T mapped_type;
315 typedef pair<const key_type,mapped_type> value_type;
316 typedef Compare key_compare;
317 typedef Allocator allocator_type;
318 typedef typename allocator_type::reference reference;
319 typedef typename allocator_type::const_reference const_reference;
320 typedef typename allocator_type::size_type size_type;
321 typedef typename allocator_type::difference_type difference_type;
322 typedef typename allocator_type::pointer pointer;
323 typedef typename allocator_type::const_pointer const_pointer;
325 typedef implementation-defined iterator;
326 typedef implementation-defined const_iterator;
327 typedef std::reverse_iterator<iterator> reverse_iterator;
328 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
329 typedef unspecified node_type; // C++17
333 friend class multimap;
336 value_compare(key_compare c);
338 typedef bool result_type; // deprecated in C++17, removed in C++20
339 typedef value_type first_argument_type; // deprecated in C++17, removed in C++20
340 typedef value_type second_argument_type; // deprecated in C++17, removed in C++20
341 bool operator()(const value_type& x, const value_type& y) const;
344 // construct/copy/destroy:
347 is_nothrow_default_constructible<allocator_type>::value &&
348 is_nothrow_default_constructible<key_compare>::value &&
349 is_nothrow_copy_constructible<key_compare>::value);
350 explicit multimap(const key_compare& comp);
351 multimap(const key_compare& comp, const allocator_type& a);
352 template <class InputIterator>
353 multimap(InputIterator first, InputIterator last, const key_compare& comp);
354 template <class InputIterator>
355 multimap(InputIterator first, InputIterator last, const key_compare& comp,
356 const allocator_type& a);
357 template<container-compatible-range<value_type> R>
358 multimap(from_range_t, R&& rg,
359 const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
360 multimap(const multimap& m);
361 multimap(multimap&& m)
363 is_nothrow_move_constructible<allocator_type>::value &&
364 is_nothrow_move_constructible<key_compare>::value);
365 explicit multimap(const allocator_type& a);
366 multimap(const multimap& m, const allocator_type& a);
367 multimap(multimap&& m, const allocator_type& a);
368 multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());
369 multimap(initializer_list<value_type> il, const key_compare& comp,
370 const allocator_type& a);
371 template <class InputIterator>
372 multimap(InputIterator first, InputIterator last, const allocator_type& a)
373 : multimap(first, last, Compare(), a) {} // C++14
374 template<container-compatible-range<value_type> R>
375 multimap(from_range_t, R&& rg, const Allocator& a))
376 : multimap(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
377 multimap(initializer_list<value_type> il, const allocator_type& a)
378 : multimap(il, Compare(), a) {} // C++14
381 multimap& operator=(const multimap& m);
382 multimap& operator=(multimap&& m)
384 allocator_type::propagate_on_container_move_assignment::value &&
385 is_nothrow_move_assignable<allocator_type>::value &&
386 is_nothrow_move_assignable<key_compare>::value);
387 multimap& operator=(initializer_list<value_type> il);
390 iterator begin() noexcept;
391 const_iterator begin() const noexcept;
392 iterator end() noexcept;
393 const_iterator end() const noexcept;
395 reverse_iterator rbegin() noexcept;
396 const_reverse_iterator rbegin() const noexcept;
397 reverse_iterator rend() noexcept;
398 const_reverse_iterator rend() const noexcept;
400 const_iterator cbegin() const noexcept;
401 const_iterator cend() const noexcept;
402 const_reverse_iterator crbegin() const noexcept;
403 const_reverse_iterator crend() const noexcept;
406 bool empty() const noexcept;
407 size_type size() const noexcept;
408 size_type max_size() const noexcept;
411 template <class... Args>
412 iterator emplace(Args&&... args);
413 template <class... Args>
414 iterator emplace_hint(const_iterator position, Args&&... args);
415 iterator insert(const value_type& v);
416 iterator insert( value_type&& v); // C++17
418 iterator insert(P&& p);
419 iterator insert(const_iterator position, const value_type& v);
420 iterator insert(const_iterator position, value_type&& v); // C++17
422 iterator insert(const_iterator position, P&& p);
423 template <class InputIterator>
424 void insert(InputIterator first, InputIterator last);
425 template<container-compatible-range<value_type> R>
426 void insert_range(R&& rg); // C++23
427 void insert(initializer_list<value_type> il);
429 node_type extract(const_iterator position); // C++17
430 node_type extract(const key_type& x); // C++17
431 iterator insert(node_type&& nh); // C++17
432 iterator insert(const_iterator hint, node_type&& nh); // C++17
434 iterator erase(const_iterator position);
435 iterator erase(iterator position); // C++14
436 size_type erase(const key_type& k);
437 iterator erase(const_iterator first, const_iterator last);
438 void clear() noexcept;
441 void merge(multimap<Key, T, C2, Allocator>& source); // C++17
443 void merge(multimap<Key, T, C2, Allocator>&& source); // C++17
445 void merge(map<Key, T, C2, Allocator>& source); // C++17
447 void merge(map<Key, T, C2, Allocator>&& source); // C++17
449 void swap(multimap& m)
450 noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
451 is_nothrow_swappable<key_compare>::value); // C++17
454 allocator_type get_allocator() const noexcept;
455 key_compare key_comp() const;
456 value_compare value_comp() const;
459 iterator find(const key_type& k);
460 const_iterator find(const key_type& k) const;
462 iterator find(const K& x); // C++14
464 const_iterator find(const K& x) const; // C++14
467 size_type count(const K& x) const; // C++14
468 size_type count(const key_type& k) const;
470 bool contains(const key_type& x) const; // C++20
471 template<class K> bool contains(const K& x) const; // C++20
473 iterator lower_bound(const key_type& k);
474 const_iterator lower_bound(const key_type& k) const;
476 iterator lower_bound(const K& x); // C++14
478 const_iterator lower_bound(const K& x) const; // C++14
480 iterator upper_bound(const key_type& k);
481 const_iterator upper_bound(const key_type& k) const;
483 iterator upper_bound(const K& x); // C++14
485 const_iterator upper_bound(const K& x) const; // C++14
487 pair<iterator,iterator> equal_range(const key_type& k);
488 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
490 pair<iterator,iterator> equal_range(const K& x); // C++14
492 pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14
495 template <class InputIterator,
496 class Compare = less<iter_key_t<InputIterator>>,
497 class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
498 multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
499 -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17
501 template<ranges::input_range R, class Compare = less<range-key-type<R>>,
502 class Allocator = allocator<range-to-alloc-type<R>>>
503 multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
504 -> multimap<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23
506 template<class Key, class T, class Compare = less<Key>,
507 class Allocator = allocator<pair<const Key, T>>>
508 multimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
509 -> multimap<Key, T, Compare, Allocator>; // C++17
511 template <class InputIterator, class Allocator>
512 multimap(InputIterator, InputIterator, Allocator)
513 -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
514 less<iter_key_t<InputIterator>>, Allocator>; // C++17
516 template<ranges::input_range R, class Allocator>
517 multimap(from_range_t, R&&, Allocator)
518 -> multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23
520 template<class Key, class T, class Allocator>
521 multimap(initializer_list<pair<const Key, T>>, Allocator)
522 -> multimap<Key, T, less<Key>, Allocator>; // C++17
524 template <class Key, class T, class Compare, class Allocator>
526 operator==(const multimap<Key, T, Compare, Allocator>& x,
527 const multimap<Key, T, Compare, Allocator>& y);
529 template <class Key, class T, class Compare, class Allocator>
531 operator< (const multimap<Key, T, Compare, Allocator>& x,
532 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20
534 template <class Key, class T, class Compare, class Allocator>
536 operator!=(const multimap<Key, T, Compare, Allocator>& x,
537 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20
539 template <class Key, class T, class Compare, class Allocator>
541 operator> (const multimap<Key, T, Compare, Allocator>& x,
542 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20
544 template <class Key, class T, class Compare, class Allocator>
546 operator>=(const multimap<Key, T, Compare, Allocator>& x,
547 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20
549 template <class Key, class T, class Compare, class Allocator>
551 operator<=(const multimap<Key, T, Compare, Allocator>& x,
552 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20
554 template<class Key, class T, class Compare, class Allocator>
555 synth-three-way-result<pair<const Key, T>>
556 operator<=>(const multimap<Key, T, Compare, Allocator>& x,
557 const multimap<Key, T, Compare, Allocator>& y); // since c++20
559 // specialized algorithms:
560 template <class Key, class T, class Compare, class Allocator>
562 swap(multimap<Key, T, Compare, Allocator>& x,
563 multimap<Key, T, Compare, Allocator>& y)
564 noexcept(noexcept(x.swap(y)));
566 template <class Key, class T, class Compare, class Allocator, class Predicate>
567 typename multimap<Key, T, Compare, Allocator>::size_type
568 erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
574 #include <__algorithm/equal.h>
575 #include <__algorithm/lexicographical_compare.h>
576 #include <__algorithm/lexicographical_compare_three_way.h>
577 #include <__assert> // all public C++ headers provide the assertion handler
578 #include <__availability>
580 #include <__functional/binary_function.h>
581 #include <__functional/is_transparent.h>
582 #include <__functional/operations.h>
583 #include <__iterator/erase_if_container.h>
584 #include <__iterator/iterator_traits.h>
585 #include <__iterator/ranges_iterator_traits.h>
586 #include <__iterator/reverse_iterator.h>
587 #include <__memory/addressof.h>
588 #include <__memory/allocator.h>
589 #include <__memory_resource/polymorphic_allocator.h>
590 #include <__node_handle>
591 #include <__ranges/concepts.h>
592 #include <__ranges/container_compatible_range.h>
593 #include <__ranges/from_range.h>
595 #include <__type_traits/is_allocator.h>
596 #include <__utility/forward.h>
597 #include <__utility/piecewise_construct.h>
598 #include <__utility/swap.h>
603 // standard-mandated includes
606 #include <__iterator/access.h>
607 #include <__iterator/data.h>
608 #include <__iterator/empty.h>
609 #include <__iterator/reverse_access.h>
610 #include <__iterator/size.h>
612 // [associative.map.syn]
614 #include <initializer_list>
616 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
617 # pragma GCC system_header
620 _LIBCPP_BEGIN_NAMESPACE_STD
622 template <class _Key, class _CP, class _Compare,
623 bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
624 class __map_value_compare
628 _LIBCPP_INLINE_VISIBILITY
629 __map_value_compare()
630 _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
632 _LIBCPP_INLINE_VISIBILITY
633 __map_value_compare(_Compare __c)
634 _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
636 _LIBCPP_INLINE_VISIBILITY
637 const _Compare& key_comp() const _NOEXCEPT {return *this;}
638 _LIBCPP_INLINE_VISIBILITY
639 bool operator()(const _CP& __x, const _CP& __y) const
640 {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y.__get_value().first);}
641 _LIBCPP_INLINE_VISIBILITY
642 bool operator()(const _CP& __x, const _Key& __y) const
643 {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);}
644 _LIBCPP_INLINE_VISIBILITY
645 bool operator()(const _Key& __x, const _CP& __y) const
646 {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);}
647 _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y)
648 _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
651 swap(static_cast<_Compare&>(*this), static_cast<_Compare&>(__y));
654 #if _LIBCPP_STD_VER >= 14
655 template <typename _K2>
656 _LIBCPP_INLINE_VISIBILITY
657 bool operator()(const _K2& __x, const _CP& __y) const
658 {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);}
660 template <typename _K2>
661 _LIBCPP_INLINE_VISIBILITY
662 bool operator()(const _CP& __x, const _K2& __y) const
663 {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);}
667 template <class _Key, class _CP, class _Compare>
668 class __map_value_compare<_Key, _CP, _Compare, false>
673 _LIBCPP_INLINE_VISIBILITY
674 __map_value_compare()
675 _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
677 _LIBCPP_INLINE_VISIBILITY
678 __map_value_compare(_Compare __c)
679 _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
681 _LIBCPP_INLINE_VISIBILITY
682 const _Compare& key_comp() const _NOEXCEPT {return __comp_;}
684 _LIBCPP_INLINE_VISIBILITY
685 bool operator()(const _CP& __x, const _CP& __y) const
686 {return __comp_(__x.__get_value().first, __y.__get_value().first);}
687 _LIBCPP_INLINE_VISIBILITY
688 bool operator()(const _CP& __x, const _Key& __y) const
689 {return __comp_(__x.__get_value().first, __y);}
690 _LIBCPP_INLINE_VISIBILITY
691 bool operator()(const _Key& __x, const _CP& __y) const
692 {return __comp_(__x, __y.__get_value().first);}
693 void swap(__map_value_compare& __y)
694 _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
697 swap(__comp_, __y.__comp_);
700 #if _LIBCPP_STD_VER >= 14
701 template <typename _K2>
702 _LIBCPP_INLINE_VISIBILITY
703 bool operator()(const _K2& __x, const _CP& __y) const
704 {return __comp_(__x, __y.__get_value().first);}
706 template <typename _K2>
707 _LIBCPP_INLINE_VISIBILITY
708 bool operator()(const _CP& __x, const _K2& __y) const
709 {return __comp_(__x.__get_value().first, __y);}
713 template <class _Key, class _CP, class _Compare, bool __b>
714 inline _LIBCPP_INLINE_VISIBILITY
716 swap(__map_value_compare<_Key, _CP, _Compare, __b>& __x,
717 __map_value_compare<_Key, _CP, _Compare, __b>& __y)
718 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
723 template <class _Allocator>
724 class __map_node_destructor
726 typedef _Allocator allocator_type;
727 typedef allocator_traits<allocator_type> __alloc_traits;
730 typedef typename __alloc_traits::pointer pointer;
733 allocator_type& __na_;
735 __map_node_destructor& operator=(const __map_node_destructor&);
738 bool __first_constructed;
739 bool __second_constructed;
741 _LIBCPP_INLINE_VISIBILITY
742 explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT
744 __first_constructed(false),
745 __second_constructed(false)
748 #ifndef _LIBCPP_CXX03_LANG
749 _LIBCPP_INLINE_VISIBILITY
750 __map_node_destructor(__tree_node_destructor<allocator_type>&& __x) _NOEXCEPT
752 __first_constructed(__x.__value_constructed),
753 __second_constructed(__x.__value_constructed)
755 __x.__value_constructed = false;
757 #endif // _LIBCPP_CXX03_LANG
759 _LIBCPP_INLINE_VISIBILITY
760 void operator()(pointer __p) _NOEXCEPT
762 if (__second_constructed)
763 __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().second));
764 if (__first_constructed)
765 __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().first));
767 __alloc_traits::deallocate(__na_, __p, 1);
771 template <class _Key, class _Tp, class _Compare, class _Allocator>
773 template <class _Key, class _Tp, class _Compare, class _Allocator>
775 template <class _TreeIterator> class __map_const_iterator;
777 #ifndef _LIBCPP_CXX03_LANG
779 template <class _Key, class _Tp>
780 struct _LIBCPP_STANDALONE_DEBUG __value_type
782 typedef _Key key_type;
783 typedef _Tp mapped_type;
784 typedef pair<const key_type, mapped_type> value_type;
785 typedef pair<key_type&, mapped_type&> __nc_ref_pair_type;
786 typedef pair<key_type&&, mapped_type&&> __nc_rref_pair_type;
792 _LIBCPP_INLINE_VISIBILITY
793 value_type& __get_value()
795 #if _LIBCPP_STD_VER >= 17
796 return *_VSTD::launder(_VSTD::addressof(__cc_));
802 _LIBCPP_INLINE_VISIBILITY
803 const value_type& __get_value() const
805 #if _LIBCPP_STD_VER >= 17
806 return *_VSTD::launder(_VSTD::addressof(__cc_));
812 _LIBCPP_INLINE_VISIBILITY
813 __nc_ref_pair_type __ref()
815 value_type& __v = __get_value();
816 return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second);
819 _LIBCPP_INLINE_VISIBILITY
820 __nc_rref_pair_type __move()
822 value_type& __v = __get_value();
823 return __nc_rref_pair_type(
824 _VSTD::move(const_cast<key_type&>(__v.first)),
825 _VSTD::move(__v.second));
828 _LIBCPP_INLINE_VISIBILITY
829 __value_type& operator=(const __value_type& __v)
831 __ref() = __v.__get_value();
835 _LIBCPP_INLINE_VISIBILITY
836 __value_type& operator=(__value_type&& __v)
838 __ref() = __v.__move();
842 template <class _ValueTp,
843 class = __enable_if_t<__is_same_uncvref<_ValueTp, value_type>::value>
845 _LIBCPP_INLINE_VISIBILITY
846 __value_type& operator=(_ValueTp&& __v)
848 __ref() = _VSTD::forward<_ValueTp>(__v);
853 __value_type() = delete;
854 ~__value_type() = delete;
855 __value_type(const __value_type&) = delete;
856 __value_type(__value_type&&) = delete;
861 template <class _Key, class _Tp>
864 typedef _Key key_type;
865 typedef _Tp mapped_type;
866 typedef pair<const key_type, mapped_type> value_type;
872 _LIBCPP_INLINE_VISIBILITY
873 value_type& __get_value() { return __cc_; }
874 _LIBCPP_INLINE_VISIBILITY
875 const value_type& __get_value() const { return __cc_; }
879 __value_type(__value_type const&);
880 __value_type& operator=(__value_type const&);
884 #endif // _LIBCPP_CXX03_LANG
887 struct __extract_key_value_types;
889 template <class _Key, class _Tp>
890 struct __extract_key_value_types<__value_type<_Key, _Tp> >
892 typedef _Key const __key_type;
893 typedef _Tp __mapped_type;
896 template <class _TreeIterator>
897 class _LIBCPP_TEMPLATE_VIS __map_iterator
899 typedef typename _TreeIterator::_NodeTypes _NodeTypes;
900 typedef typename _TreeIterator::__pointer_traits __pointer_traits;
905 typedef bidirectional_iterator_tag iterator_category;
906 typedef typename _NodeTypes::__map_value_type value_type;
907 typedef typename _TreeIterator::difference_type difference_type;
908 typedef value_type& reference;
909 typedef typename _NodeTypes::__map_value_type_pointer pointer;
911 _LIBCPP_INLINE_VISIBILITY
912 __map_iterator() _NOEXCEPT {}
914 _LIBCPP_INLINE_VISIBILITY
915 __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
917 _LIBCPP_INLINE_VISIBILITY
918 reference operator*() const {return __i_->__get_value();}
919 _LIBCPP_INLINE_VISIBILITY
920 pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}
922 _LIBCPP_INLINE_VISIBILITY
923 __map_iterator& operator++() {++__i_; return *this;}
924 _LIBCPP_INLINE_VISIBILITY
925 __map_iterator operator++(int)
927 __map_iterator __t(*this);
932 _LIBCPP_INLINE_VISIBILITY
933 __map_iterator& operator--() {--__i_; return *this;}
934 _LIBCPP_INLINE_VISIBILITY
935 __map_iterator operator--(int)
937 __map_iterator __t(*this);
942 friend _LIBCPP_INLINE_VISIBILITY
943 bool operator==(const __map_iterator& __x, const __map_iterator& __y)
944 {return __x.__i_ == __y.__i_;}
946 _LIBCPP_INLINE_VISIBILITY
947 bool operator!=(const __map_iterator& __x, const __map_iterator& __y)
948 {return __x.__i_ != __y.__i_;}
950 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
951 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
952 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
955 template <class _TreeIterator>
956 class _LIBCPP_TEMPLATE_VIS __map_const_iterator
958 typedef typename _TreeIterator::_NodeTypes _NodeTypes;
959 typedef typename _TreeIterator::__pointer_traits __pointer_traits;
964 typedef bidirectional_iterator_tag iterator_category;
965 typedef typename _NodeTypes::__map_value_type value_type;
966 typedef typename _TreeIterator::difference_type difference_type;
967 typedef const value_type& reference;
968 typedef typename _NodeTypes::__const_map_value_type_pointer pointer;
970 _LIBCPP_INLINE_VISIBILITY
971 __map_const_iterator() _NOEXCEPT {}
973 _LIBCPP_INLINE_VISIBILITY
974 __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
975 _LIBCPP_INLINE_VISIBILITY
976 __map_const_iterator(__map_iterator<
977 typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT
980 _LIBCPP_INLINE_VISIBILITY
981 reference operator*() const {return __i_->__get_value();}
982 _LIBCPP_INLINE_VISIBILITY
983 pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}
985 _LIBCPP_INLINE_VISIBILITY
986 __map_const_iterator& operator++() {++__i_; return *this;}
987 _LIBCPP_INLINE_VISIBILITY
988 __map_const_iterator operator++(int)
990 __map_const_iterator __t(*this);
995 _LIBCPP_INLINE_VISIBILITY
996 __map_const_iterator& operator--() {--__i_; return *this;}
997 _LIBCPP_INLINE_VISIBILITY
998 __map_const_iterator operator--(int)
1000 __map_const_iterator __t(*this);
1005 friend _LIBCPP_INLINE_VISIBILITY
1006 bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y)
1007 {return __x.__i_ == __y.__i_;}
1008 friend _LIBCPP_INLINE_VISIBILITY
1009 bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y)
1010 {return __x.__i_ != __y.__i_;}
1012 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
1013 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
1014 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
1017 template <class _Key, class _Tp, class _Compare = less<_Key>,
1018 class _Allocator = allocator<pair<const _Key, _Tp> > >
1019 class _LIBCPP_TEMPLATE_VIS map
1023 typedef _Key key_type;
1024 typedef _Tp mapped_type;
1025 typedef pair<const key_type, mapped_type> value_type;
1026 typedef __type_identity_t<_Compare> key_compare;
1027 typedef __type_identity_t<_Allocator> allocator_type;
1028 typedef value_type& reference;
1029 typedef const value_type& const_reference;
1031 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
1032 "Allocator::value_type must be same type as value_type");
1034 class _LIBCPP_TEMPLATE_VIS value_compare
1035 : public __binary_function<value_type, value_type, bool>
1041 _LIBCPP_INLINE_VISIBILITY value_compare(key_compare __c) : comp(__c) {}
1043 _LIBCPP_INLINE_VISIBILITY
1044 bool operator()(const value_type& __x, const value_type& __y) const
1045 {return comp(__x.first, __y.first);}
1050 typedef _VSTD::__value_type<key_type, mapped_type> __value_type;
1051 typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
1052 typedef __rebind_alloc<allocator_traits<allocator_type>, __value_type> __allocator_type;
1053 typedef __tree<__value_type, __vc, __allocator_type> __base;
1054 typedef typename __base::__node_traits __node_traits;
1055 typedef allocator_traits<allocator_type> __alloc_traits;
1057 static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
1058 "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
1059 "original allocator");
1064 typedef typename __alloc_traits::pointer pointer;
1065 typedef typename __alloc_traits::const_pointer const_pointer;
1066 typedef typename __alloc_traits::size_type size_type;
1067 typedef typename __alloc_traits::difference_type difference_type;
1068 typedef __map_iterator<typename __base::iterator> iterator;
1069 typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
1070 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
1071 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
1073 #if _LIBCPP_STD_VER >= 17
1074 typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
1075 typedef __insert_return_type<iterator, node_type> insert_return_type;
1078 template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
1079 friend class _LIBCPP_TEMPLATE_VIS map;
1080 template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
1081 friend class _LIBCPP_TEMPLATE_VIS multimap;
1083 _LIBCPP_INLINE_VISIBILITY
1086 is_nothrow_default_constructible<allocator_type>::value &&
1087 is_nothrow_default_constructible<key_compare>::value &&
1088 is_nothrow_copy_constructible<key_compare>::value)
1089 : __tree_(__vc(key_compare())) {}
1091 _LIBCPP_INLINE_VISIBILITY
1092 explicit map(const key_compare& __comp)
1094 is_nothrow_default_constructible<allocator_type>::value &&
1095 is_nothrow_copy_constructible<key_compare>::value)
1096 : __tree_(__vc(__comp)) {}
1098 _LIBCPP_INLINE_VISIBILITY
1099 explicit map(const key_compare& __comp, const allocator_type& __a)
1100 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}
1102 template <class _InputIterator>
1103 _LIBCPP_INLINE_VISIBILITY
1104 map(_InputIterator __f, _InputIterator __l,
1105 const key_compare& __comp = key_compare())
1106 : __tree_(__vc(__comp))
1111 template <class _InputIterator>
1112 _LIBCPP_INLINE_VISIBILITY
1113 map(_InputIterator __f, _InputIterator __l,
1114 const key_compare& __comp, const allocator_type& __a)
1115 : __tree_(__vc(__comp), typename __base::allocator_type(__a))
1120 #if _LIBCPP_STD_VER >= 23
1121 template <_ContainerCompatibleRange<value_type> _Range>
1122 _LIBCPP_HIDE_FROM_ABI
1123 map(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(),
1124 const allocator_type& __a = allocator_type())
1125 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
1126 insert_range(std::forward<_Range>(__range));
1130 #if _LIBCPP_STD_VER >= 14
1131 template <class _InputIterator>
1132 _LIBCPP_INLINE_VISIBILITY
1133 map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
1134 : map(__f, __l, key_compare(), __a) {}
1137 #if _LIBCPP_STD_VER >= 23
1138 template <_ContainerCompatibleRange<value_type> _Range>
1139 _LIBCPP_HIDE_FROM_ABI
1140 map(from_range_t, _Range&& __range, const allocator_type& __a)
1141 : map(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
1144 _LIBCPP_INLINE_VISIBILITY
1146 : __tree_(__m.__tree_)
1148 insert(__m.begin(), __m.end());
1151 _LIBCPP_INLINE_VISIBILITY
1152 map& operator=(const map& __m)
1154 #ifndef _LIBCPP_CXX03_LANG
1155 __tree_ = __m.__tree_;
1157 if (this != _VSTD::addressof(__m)) {
1159 __tree_.value_comp() = __m.__tree_.value_comp();
1160 __tree_.__copy_assign_alloc(__m.__tree_);
1161 insert(__m.begin(), __m.end());
1167 #ifndef _LIBCPP_CXX03_LANG
1169 _LIBCPP_INLINE_VISIBILITY
1171 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
1172 : __tree_(_VSTD::move(__m.__tree_))
1176 _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a);
1178 _LIBCPP_INLINE_VISIBILITY
1179 map& operator=(map&& __m)
1180 _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
1182 __tree_ = _VSTD::move(__m.__tree_);
1186 _LIBCPP_INLINE_VISIBILITY
1187 map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
1188 : __tree_(__vc(__comp))
1190 insert(__il.begin(), __il.end());
1193 _LIBCPP_INLINE_VISIBILITY
1194 map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
1195 : __tree_(__vc(__comp), typename __base::allocator_type(__a))
1197 insert(__il.begin(), __il.end());
1200 #if _LIBCPP_STD_VER >= 14
1201 _LIBCPP_INLINE_VISIBILITY
1202 map(initializer_list<value_type> __il, const allocator_type& __a)
1203 : map(__il, key_compare(), __a) {}
1206 _LIBCPP_INLINE_VISIBILITY
1207 map& operator=(initializer_list<value_type> __il)
1209 __tree_.__assign_unique(__il.begin(), __il.end());
1213 #endif // _LIBCPP_CXX03_LANG
1215 _LIBCPP_INLINE_VISIBILITY
1216 explicit map(const allocator_type& __a)
1217 : __tree_(typename __base::allocator_type(__a))
1221 _LIBCPP_INLINE_VISIBILITY
1222 map(const map& __m, const allocator_type& __a)
1223 : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a))
1225 insert(__m.begin(), __m.end());
1228 _LIBCPP_INLINE_VISIBILITY
1230 static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
1233 _LIBCPP_INLINE_VISIBILITY
1234 iterator begin() _NOEXCEPT {return __tree_.begin();}
1235 _LIBCPP_INLINE_VISIBILITY
1236 const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
1237 _LIBCPP_INLINE_VISIBILITY
1238 iterator end() _NOEXCEPT {return __tree_.end();}
1239 _LIBCPP_INLINE_VISIBILITY
1240 const_iterator end() const _NOEXCEPT {return __tree_.end();}
1242 _LIBCPP_INLINE_VISIBILITY
1243 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
1244 _LIBCPP_INLINE_VISIBILITY
1245 const_reverse_iterator rbegin() const _NOEXCEPT
1246 {return const_reverse_iterator(end());}
1247 _LIBCPP_INLINE_VISIBILITY
1248 reverse_iterator rend() _NOEXCEPT
1249 {return reverse_iterator(begin());}
1250 _LIBCPP_INLINE_VISIBILITY
1251 const_reverse_iterator rend() const _NOEXCEPT
1252 {return const_reverse_iterator(begin());}
1254 _LIBCPP_INLINE_VISIBILITY
1255 const_iterator cbegin() const _NOEXCEPT {return begin();}
1256 _LIBCPP_INLINE_VISIBILITY
1257 const_iterator cend() const _NOEXCEPT {return end();}
1258 _LIBCPP_INLINE_VISIBILITY
1259 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
1260 _LIBCPP_INLINE_VISIBILITY
1261 const_reverse_iterator crend() const _NOEXCEPT {return rend();}
1263 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1264 bool empty() const _NOEXCEPT {return __tree_.size() == 0;}
1265 _LIBCPP_INLINE_VISIBILITY
1266 size_type size() const _NOEXCEPT {return __tree_.size();}
1267 _LIBCPP_INLINE_VISIBILITY
1268 size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
1270 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
1271 #ifndef _LIBCPP_CXX03_LANG
1272 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
1275 _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
1276 _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
1278 _LIBCPP_INLINE_VISIBILITY
1279 allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());}
1280 _LIBCPP_INLINE_VISIBILITY
1281 key_compare key_comp() const {return __tree_.value_comp().key_comp();}
1282 _LIBCPP_INLINE_VISIBILITY
1283 value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());}
1285 #ifndef _LIBCPP_CXX03_LANG
1286 template <class ..._Args>
1287 _LIBCPP_INLINE_VISIBILITY
1288 pair<iterator, bool> emplace(_Args&& ...__args) {
1289 return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...);
1292 template <class ..._Args>
1293 _LIBCPP_INLINE_VISIBILITY
1294 iterator emplace_hint(const_iterator __p, _Args&& ...__args) {
1295 return __tree_.__emplace_hint_unique(__p.__i_, _VSTD::forward<_Args>(__args)...);
1298 template <class _Pp,
1299 class = __enable_if_t<is_constructible<value_type, _Pp>::value> >
1300 _LIBCPP_INLINE_VISIBILITY
1301 pair<iterator, bool> insert(_Pp&& __p)
1302 {return __tree_.__insert_unique(_VSTD::forward<_Pp>(__p));}
1304 template <class _Pp,
1305 class = __enable_if_t<is_constructible<value_type, _Pp>::value> >
1306 _LIBCPP_INLINE_VISIBILITY
1307 iterator insert(const_iterator __pos, _Pp&& __p)
1308 {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));}
1310 #endif // _LIBCPP_CXX03_LANG
1312 _LIBCPP_INLINE_VISIBILITY
1313 pair<iterator, bool>
1314 insert(const value_type& __v) {return __tree_.__insert_unique(__v);}
1316 _LIBCPP_INLINE_VISIBILITY
1318 insert(const_iterator __p, const value_type& __v)
1319 {return __tree_.__insert_unique(__p.__i_, __v);}
1321 #ifndef _LIBCPP_CXX03_LANG
1322 _LIBCPP_INLINE_VISIBILITY
1323 pair<iterator, bool>
1324 insert(value_type&& __v) {return __tree_.__insert_unique(_VSTD::move(__v));}
1326 _LIBCPP_INLINE_VISIBILITY
1327 iterator insert(const_iterator __p, value_type&& __v)
1328 {return __tree_.__insert_unique(__p.__i_, _VSTD::move(__v));}
1330 _LIBCPP_INLINE_VISIBILITY
1331 void insert(initializer_list<value_type> __il)
1332 {insert(__il.begin(), __il.end());}
1335 template <class _InputIterator>
1336 _LIBCPP_INLINE_VISIBILITY
1337 void insert(_InputIterator __f, _InputIterator __l)
1339 for (const_iterator __e = cend(); __f != __l; ++__f)
1340 insert(__e.__i_, *__f);
1343 #if _LIBCPP_STD_VER >= 23
1344 template <_ContainerCompatibleRange<value_type> _Range>
1345 _LIBCPP_HIDE_FROM_ABI
1346 void insert_range(_Range&& __range) {
1347 const_iterator __end = cend();
1348 for (auto&& __element : __range) {
1349 insert(__end.__i_, std::forward<decltype(__element)>(__element));
1354 #if _LIBCPP_STD_VER >= 17
1356 template <class... _Args>
1357 _LIBCPP_INLINE_VISIBILITY
1358 pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args)
1360 return __tree_.__emplace_unique_key_args(__k,
1361 _VSTD::piecewise_construct,
1362 _VSTD::forward_as_tuple(__k),
1363 _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
1366 template <class... _Args>
1367 _LIBCPP_INLINE_VISIBILITY
1368 pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args)
1370 return __tree_.__emplace_unique_key_args(__k,
1371 _VSTD::piecewise_construct,
1372 _VSTD::forward_as_tuple(_VSTD::move(__k)),
1373 _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
1376 template <class... _Args>
1377 _LIBCPP_INLINE_VISIBILITY
1378 iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args)
1380 return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k,
1381 _VSTD::piecewise_construct,
1382 _VSTD::forward_as_tuple(__k),
1383 _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)).first;
1386 template <class... _Args>
1387 _LIBCPP_INLINE_VISIBILITY
1388 iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args)
1390 return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k,
1391 _VSTD::piecewise_construct,
1392 _VSTD::forward_as_tuple(_VSTD::move(__k)),
1393 _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)).first;
1396 template <class _Vp>
1397 _LIBCPP_INLINE_VISIBILITY
1398 pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v)
1400 iterator __p = lower_bound(__k);
1401 if ( __p != end() && !key_comp()(__k, __p->first))
1403 __p->second = _VSTD::forward<_Vp>(__v);
1404 return _VSTD::make_pair(__p, false);
1406 return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true);
1409 template <class _Vp>
1410 _LIBCPP_INLINE_VISIBILITY
1411 pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v)
1413 iterator __p = lower_bound(__k);
1414 if ( __p != end() && !key_comp()(__k, __p->first))
1416 __p->second = _VSTD::forward<_Vp>(__v);
1417 return _VSTD::make_pair(__p, false);
1419 return _VSTD::make_pair(emplace_hint(__p, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)), true);
1422 template <class _Vp>
1423 _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h,
1424 const key_type& __k,
1426 auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args(
1427 __h.__i_, __k, __k, _VSTD::forward<_Vp>(__v));
1430 __r->__get_value().second = _VSTD::forward<_Vp>(__v);
1435 template <class _Vp>
1436 _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h,
1439 auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args(
1440 __h.__i_, __k, _VSTD::move(__k), _VSTD::forward<_Vp>(__v));
1443 __r->__get_value().second = _VSTD::forward<_Vp>(__v);
1448 #endif // _LIBCPP_STD_VER >= 17
1450 _LIBCPP_INLINE_VISIBILITY
1451 iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
1452 _LIBCPP_INLINE_VISIBILITY
1453 iterator erase(iterator __p) {return __tree_.erase(__p.__i_);}
1454 _LIBCPP_INLINE_VISIBILITY
1455 size_type erase(const key_type& __k)
1456 {return __tree_.__erase_unique(__k);}
1457 _LIBCPP_INLINE_VISIBILITY
1458 iterator erase(const_iterator __f, const_iterator __l)
1459 {return __tree_.erase(__f.__i_, __l.__i_);}
1460 _LIBCPP_INLINE_VISIBILITY
1461 void clear() _NOEXCEPT {__tree_.clear();}
1463 #if _LIBCPP_STD_VER >= 17
1464 _LIBCPP_INLINE_VISIBILITY
1465 insert_return_type insert(node_type&& __nh)
1467 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
1468 "node_type with incompatible allocator passed to map::insert()");
1469 return __tree_.template __node_handle_insert_unique<
1470 node_type, insert_return_type>(_VSTD::move(__nh));
1472 _LIBCPP_INLINE_VISIBILITY
1473 iterator insert(const_iterator __hint, node_type&& __nh)
1475 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
1476 "node_type with incompatible allocator passed to map::insert()");
1477 return __tree_.template __node_handle_insert_unique<node_type>(
1478 __hint.__i_, _VSTD::move(__nh));
1480 _LIBCPP_INLINE_VISIBILITY
1481 node_type extract(key_type const& __key)
1483 return __tree_.template __node_handle_extract<node_type>(__key);
1485 _LIBCPP_INLINE_VISIBILITY
1486 node_type extract(const_iterator __it)
1488 return __tree_.template __node_handle_extract<node_type>(__it.__i_);
1490 template <class _Compare2>
1491 _LIBCPP_INLINE_VISIBILITY
1492 void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
1494 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1495 "merging container with incompatible allocator");
1496 __tree_.__node_handle_merge_unique(__source.__tree_);
1498 template <class _Compare2>
1499 _LIBCPP_INLINE_VISIBILITY
1500 void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
1502 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1503 "merging container with incompatible allocator");
1504 __tree_.__node_handle_merge_unique(__source.__tree_);
1506 template <class _Compare2>
1507 _LIBCPP_INLINE_VISIBILITY
1508 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
1510 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1511 "merging container with incompatible allocator");
1512 __tree_.__node_handle_merge_unique(__source.__tree_);
1514 template <class _Compare2>
1515 _LIBCPP_INLINE_VISIBILITY
1516 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
1518 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
1519 "merging container with incompatible allocator");
1520 __tree_.__node_handle_merge_unique(__source.__tree_);
1524 _LIBCPP_INLINE_VISIBILITY
1526 _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
1527 {__tree_.swap(__m.__tree_);}
1529 _LIBCPP_INLINE_VISIBILITY
1530 iterator find(const key_type& __k) {return __tree_.find(__k);}
1531 _LIBCPP_INLINE_VISIBILITY
1532 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
1533 #if _LIBCPP_STD_VER >= 14
1534 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
1535 _LIBCPP_INLINE_VISIBILITY
1537 find(const _K2& __k) {return __tree_.find(__k);}
1538 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
1539 _LIBCPP_INLINE_VISIBILITY
1541 find(const _K2& __k) const {return __tree_.find(__k);}
1544 _LIBCPP_INLINE_VISIBILITY
1545 size_type count(const key_type& __k) const
1546 {return __tree_.__count_unique(__k);}
1547 #if _LIBCPP_STD_VER >= 14
1548 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
1549 _LIBCPP_INLINE_VISIBILITY
1551 count(const _K2& __k) const {return __tree_.__count_multi(__k);}
1554 #if _LIBCPP_STD_VER >= 20
1555 _LIBCPP_INLINE_VISIBILITY
1556 bool contains(const key_type& __k) const {return find(__k) != end();}
1557 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
1558 _LIBCPP_INLINE_VISIBILITY
1560 contains(const _K2& __k) const { return find(__k) != end(); }
1561 #endif // _LIBCPP_STD_VER >= 20
1563 _LIBCPP_INLINE_VISIBILITY
1564 iterator lower_bound(const key_type& __k)
1565 {return __tree_.lower_bound(__k);}
1566 _LIBCPP_INLINE_VISIBILITY
1567 const_iterator lower_bound(const key_type& __k) const
1568 {return __tree_.lower_bound(__k);}
1569 #if _LIBCPP_STD_VER >= 14
1570 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
1571 _LIBCPP_INLINE_VISIBILITY
1573 lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);}
1575 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
1576 _LIBCPP_INLINE_VISIBILITY
1578 lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
1581 _LIBCPP_INLINE_VISIBILITY
1582 iterator upper_bound(const key_type& __k)
1583 {return __tree_.upper_bound(__k);}
1584 _LIBCPP_INLINE_VISIBILITY
1585 const_iterator upper_bound(const key_type& __k) const
1586 {return __tree_.upper_bound(__k);}
1587 #if _LIBCPP_STD_VER >= 14
1588 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
1589 _LIBCPP_INLINE_VISIBILITY
1591 upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);}
1592 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
1593 _LIBCPP_INLINE_VISIBILITY
1595 upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
1598 _LIBCPP_INLINE_VISIBILITY
1599 pair<iterator,iterator> equal_range(const key_type& __k)
1600 {return __tree_.__equal_range_unique(__k);}
1601 _LIBCPP_INLINE_VISIBILITY
1602 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
1603 {return __tree_.__equal_range_unique(__k);}
1604 #if _LIBCPP_STD_VER >= 14
1605 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
1606 _LIBCPP_INLINE_VISIBILITY
1607 pair<iterator,iterator>
1608 equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
1609 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
1610 _LIBCPP_INLINE_VISIBILITY
1611 pair<const_iterator,const_iterator>
1612 equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
1616 typedef typename __base::__node __node;
1617 typedef typename __base::__node_allocator __node_allocator;
1618 typedef typename __base::__node_pointer __node_pointer;
1619 typedef typename __base::__node_base_pointer __node_base_pointer;
1620 typedef typename __base::__parent_pointer __parent_pointer;
1622 typedef __map_node_destructor<__node_allocator> _Dp;
1623 typedef unique_ptr<__node, _Dp> __node_holder;
1625 #ifdef _LIBCPP_CXX03_LANG
1626 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_with_key(const key_type& __k);
1630 #if _LIBCPP_STD_VER >= 17
1631 template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>,
1632 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
1633 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1634 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1635 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1636 map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
1637 -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
1639 #if _LIBCPP_STD_VER >= 23
1640 template <ranges::input_range _Range, class _Compare = less<__range_key_type<_Range>>,
1641 class _Allocator = allocator<__range_to_alloc_type<_Range>>,
1642 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1643 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1644 map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
1645 -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
1648 template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>,
1649 class _Allocator = allocator<pair<const _Key, _Tp>>,
1650 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1651 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1652 map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator())
1653 -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
1655 template<class _InputIterator, class _Allocator,
1656 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1657 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1658 map(_InputIterator, _InputIterator, _Allocator)
1659 -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
1660 less<__iter_key_type<_InputIterator>>, _Allocator>;
1662 #if _LIBCPP_STD_VER >= 23
1663 template <ranges::input_range _Range, class _Allocator,
1664 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1665 map(from_range_t, _Range&&, _Allocator)
1666 -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
1669 template<class _Key, class _Tp, class _Allocator,
1670 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1671 map(initializer_list<pair<_Key, _Tp>>, _Allocator)
1672 -> map<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
1675 #ifndef _LIBCPP_CXX03_LANG
1676 template <class _Key, class _Tp, class _Compare, class _Allocator>
1677 map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
1678 : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a))
1680 if (__a != __m.get_allocator())
1682 const_iterator __e = cend();
1683 while (!__m.empty())
1684 __tree_.__insert_unique(__e.__i_,
1685 __m.__tree_.remove(__m.begin().__i_)->__value_.__move());
1689 template <class _Key, class _Tp, class _Compare, class _Allocator>
1691 map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
1693 return __tree_.__emplace_unique_key_args(__k,
1694 _VSTD::piecewise_construct,
1695 _VSTD::forward_as_tuple(__k),
1696 _VSTD::forward_as_tuple()).first->__get_value().second;
1699 template <class _Key, class _Tp, class _Compare, class _Allocator>
1701 map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k)
1703 return __tree_.__emplace_unique_key_args(__k,
1704 _VSTD::piecewise_construct,
1705 _VSTD::forward_as_tuple(_VSTD::move(__k)),
1706 _VSTD::forward_as_tuple()).first->__get_value().second;
1709 #else // _LIBCPP_CXX03_LANG
1711 template <class _Key, class _Tp, class _Compare, class _Allocator>
1712 typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1713 map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k)
1715 __node_allocator& __na = __tree_.__node_alloc();
1716 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1717 __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().first), __k);
1718 __h.get_deleter().__first_constructed = true;
1719 __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().second));
1720 __h.get_deleter().__second_constructed = true;
1724 template <class _Key, class _Tp, class _Compare, class _Allocator>
1726 map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
1728 __parent_pointer __parent;
1729 __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
1730 __node_pointer __r = static_cast<__node_pointer>(__child);
1731 if (__child == nullptr)
1733 __node_holder __h = __construct_node_with_key(__k);
1734 __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1735 __r = __h.release();
1737 return __r->__value_.__get_value().second;
1740 #endif // _LIBCPP_CXX03_LANG
1742 template <class _Key, class _Tp, class _Compare, class _Allocator>
1744 map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k)
1746 __parent_pointer __parent;
1747 __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
1748 if (__child == nullptr)
1749 __throw_out_of_range("map::at: key not found");
1750 return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
1753 template <class _Key, class _Tp, class _Compare, class _Allocator>
1755 map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const
1757 __parent_pointer __parent;
1758 __node_base_pointer __child = __tree_.__find_equal(__parent, __k);
1759 if (__child == nullptr)
1760 __throw_out_of_range("map::at: key not found");
1761 return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
1765 template <class _Key, class _Tp, class _Compare, class _Allocator>
1766 inline _LIBCPP_INLINE_VISIBILITY
1768 operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1769 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1771 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
1774 #if _LIBCPP_STD_VER <= 17
1776 template <class _Key, class _Tp, class _Compare, class _Allocator>
1777 inline _LIBCPP_INLINE_VISIBILITY
1779 operator< (const map<_Key, _Tp, _Compare, _Allocator>& __x,
1780 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1782 return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1785 template <class _Key, class _Tp, class _Compare, class _Allocator>
1786 inline _LIBCPP_INLINE_VISIBILITY
1788 operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1789 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1791 return !(__x == __y);
1794 template <class _Key, class _Tp, class _Compare, class _Allocator>
1795 inline _LIBCPP_INLINE_VISIBILITY
1797 operator> (const map<_Key, _Tp, _Compare, _Allocator>& __x,
1798 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1803 template <class _Key, class _Tp, class _Compare, class _Allocator>
1804 inline _LIBCPP_INLINE_VISIBILITY
1806 operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1807 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1809 return !(__x < __y);
1812 template <class _Key, class _Tp, class _Compare, class _Allocator>
1813 inline _LIBCPP_INLINE_VISIBILITY
1815 operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1816 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1818 return !(__y < __x);
1821 #else // #if _LIBCPP_STD_VER <= 17
1823 template <class _Key, class _Tp, class _Compare, class _Allocator>
1824 _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
1825 operator<=>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
1826 return std::lexicographical_compare_three_way(
1831 std::__synth_three_way<pair<const _Key, _Tp>, pair<const _Key, _Tp>>);
1834 #endif // #if _LIBCPP_STD_VER <= 17
1836 template <class _Key, class _Tp, class _Compare, class _Allocator>
1837 inline _LIBCPP_INLINE_VISIBILITY
1839 swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
1840 map<_Key, _Tp, _Compare, _Allocator>& __y)
1841 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1846 #if _LIBCPP_STD_VER >= 20
1847 template <class _Key, class _Tp, class _Compare, class _Allocator,
1849 inline _LIBCPP_INLINE_VISIBILITY
1850 typename map<_Key, _Tp, _Compare, _Allocator>::size_type
1851 erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
1852 return _VSTD::__libcpp_erase_if_container(__c, __pred);
1857 template <class _Key, class _Tp, class _Compare = less<_Key>,
1858 class _Allocator = allocator<pair<const _Key, _Tp> > >
1859 class _LIBCPP_TEMPLATE_VIS multimap
1863 typedef _Key key_type;
1864 typedef _Tp mapped_type;
1865 typedef pair<const key_type, mapped_type> value_type;
1866 typedef __type_identity_t<_Compare> key_compare;
1867 typedef __type_identity_t<_Allocator> allocator_type;
1868 typedef value_type& reference;
1869 typedef const value_type& const_reference;
1871 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
1872 "Allocator::value_type must be same type as value_type");
1874 class _LIBCPP_TEMPLATE_VIS value_compare
1875 : public __binary_function<value_type, value_type, bool>
1877 friend class multimap;
1881 _LIBCPP_INLINE_VISIBILITY
1882 value_compare(key_compare __c) : comp(__c) {}
1884 _LIBCPP_INLINE_VISIBILITY
1885 bool operator()(const value_type& __x, const value_type& __y) const
1886 {return comp(__x.first, __y.first);}
1891 typedef _VSTD::__value_type<key_type, mapped_type> __value_type;
1892 typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
1893 typedef __rebind_alloc<allocator_traits<allocator_type>, __value_type> __allocator_type;
1894 typedef __tree<__value_type, __vc, __allocator_type> __base;
1895 typedef typename __base::__node_traits __node_traits;
1896 typedef allocator_traits<allocator_type> __alloc_traits;
1898 static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
1899 "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
1900 "original allocator");
1905 typedef typename __alloc_traits::pointer pointer;
1906 typedef typename __alloc_traits::const_pointer const_pointer;
1907 typedef typename __alloc_traits::size_type size_type;
1908 typedef typename __alloc_traits::difference_type difference_type;
1909 typedef __map_iterator<typename __base::iterator> iterator;
1910 typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
1911 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
1912 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
1914 #if _LIBCPP_STD_VER >= 17
1915 typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
1918 template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
1919 friend class _LIBCPP_TEMPLATE_VIS map;
1920 template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
1921 friend class _LIBCPP_TEMPLATE_VIS multimap;
1923 _LIBCPP_INLINE_VISIBILITY
1926 is_nothrow_default_constructible<allocator_type>::value &&
1927 is_nothrow_default_constructible<key_compare>::value &&
1928 is_nothrow_copy_constructible<key_compare>::value)
1929 : __tree_(__vc(key_compare())) {}
1931 _LIBCPP_INLINE_VISIBILITY
1932 explicit multimap(const key_compare& __comp)
1934 is_nothrow_default_constructible<allocator_type>::value &&
1935 is_nothrow_copy_constructible<key_compare>::value)
1936 : __tree_(__vc(__comp)) {}
1938 _LIBCPP_INLINE_VISIBILITY
1939 explicit multimap(const key_compare& __comp, const allocator_type& __a)
1940 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}
1942 template <class _InputIterator>
1943 _LIBCPP_INLINE_VISIBILITY
1944 multimap(_InputIterator __f, _InputIterator __l,
1945 const key_compare& __comp = key_compare())
1946 : __tree_(__vc(__comp))
1951 template <class _InputIterator>
1952 _LIBCPP_INLINE_VISIBILITY
1953 multimap(_InputIterator __f, _InputIterator __l,
1954 const key_compare& __comp, const allocator_type& __a)
1955 : __tree_(__vc(__comp), typename __base::allocator_type(__a))
1960 #if _LIBCPP_STD_VER >= 23
1961 template <_ContainerCompatibleRange<value_type> _Range>
1962 _LIBCPP_HIDE_FROM_ABI
1963 multimap(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(),
1964 const allocator_type& __a = allocator_type())
1965 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
1966 insert_range(std::forward<_Range>(__range));
1970 #if _LIBCPP_STD_VER >= 14
1971 template <class _InputIterator>
1972 _LIBCPP_INLINE_VISIBILITY
1973 multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
1974 : multimap(__f, __l, key_compare(), __a) {}
1977 #if _LIBCPP_STD_VER >= 23
1978 template <_ContainerCompatibleRange<value_type> _Range>
1979 _LIBCPP_HIDE_FROM_ABI
1980 multimap(from_range_t, _Range&& __range, const allocator_type& __a)
1981 : multimap(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
1984 _LIBCPP_INLINE_VISIBILITY
1985 multimap(const multimap& __m)
1986 : __tree_(__m.__tree_.value_comp(),
1987 __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc()))
1989 insert(__m.begin(), __m.end());
1992 _LIBCPP_INLINE_VISIBILITY
1993 multimap& operator=(const multimap& __m)
1995 #ifndef _LIBCPP_CXX03_LANG
1996 __tree_ = __m.__tree_;
1998 if (this != _VSTD::addressof(__m)) {
2000 __tree_.value_comp() = __m.__tree_.value_comp();
2001 __tree_.__copy_assign_alloc(__m.__tree_);
2002 insert(__m.begin(), __m.end());
2008 #ifndef _LIBCPP_CXX03_LANG
2010 _LIBCPP_INLINE_VISIBILITY
2011 multimap(multimap&& __m)
2012 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
2013 : __tree_(_VSTD::move(__m.__tree_))
2017 _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a);
2019 _LIBCPP_INLINE_VISIBILITY
2020 multimap& operator=(multimap&& __m)
2021 _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
2023 __tree_ = _VSTD::move(__m.__tree_);
2027 _LIBCPP_INLINE_VISIBILITY
2028 multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
2029 : __tree_(__vc(__comp))
2031 insert(__il.begin(), __il.end());
2034 _LIBCPP_INLINE_VISIBILITY
2035 multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
2036 : __tree_(__vc(__comp), typename __base::allocator_type(__a))
2038 insert(__il.begin(), __il.end());
2041 #if _LIBCPP_STD_VER >= 14
2042 _LIBCPP_INLINE_VISIBILITY
2043 multimap(initializer_list<value_type> __il, const allocator_type& __a)
2044 : multimap(__il, key_compare(), __a) {}
2047 _LIBCPP_INLINE_VISIBILITY
2048 multimap& operator=(initializer_list<value_type> __il)
2050 __tree_.__assign_multi(__il.begin(), __il.end());
2054 #endif // _LIBCPP_CXX03_LANG
2056 _LIBCPP_INLINE_VISIBILITY
2057 explicit multimap(const allocator_type& __a)
2058 : __tree_(typename __base::allocator_type(__a))
2062 _LIBCPP_INLINE_VISIBILITY
2063 multimap(const multimap& __m, const allocator_type& __a)
2064 : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a))
2066 insert(__m.begin(), __m.end());
2069 _LIBCPP_INLINE_VISIBILITY
2071 static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
2074 _LIBCPP_INLINE_VISIBILITY
2075 iterator begin() _NOEXCEPT {return __tree_.begin();}
2076 _LIBCPP_INLINE_VISIBILITY
2077 const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
2078 _LIBCPP_INLINE_VISIBILITY
2079 iterator end() _NOEXCEPT {return __tree_.end();}
2080 _LIBCPP_INLINE_VISIBILITY
2081 const_iterator end() const _NOEXCEPT {return __tree_.end();}
2083 _LIBCPP_INLINE_VISIBILITY
2084 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
2085 _LIBCPP_INLINE_VISIBILITY
2086 const_reverse_iterator rbegin() const _NOEXCEPT
2087 {return const_reverse_iterator(end());}
2088 _LIBCPP_INLINE_VISIBILITY
2089 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
2090 _LIBCPP_INLINE_VISIBILITY
2091 const_reverse_iterator rend() const _NOEXCEPT
2092 {return const_reverse_iterator(begin());}
2094 _LIBCPP_INLINE_VISIBILITY
2095 const_iterator cbegin() const _NOEXCEPT {return begin();}
2096 _LIBCPP_INLINE_VISIBILITY
2097 const_iterator cend() const _NOEXCEPT {return end();}
2098 _LIBCPP_INLINE_VISIBILITY
2099 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
2100 _LIBCPP_INLINE_VISIBILITY
2101 const_reverse_iterator crend() const _NOEXCEPT {return rend();}
2103 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
2104 bool empty() const _NOEXCEPT {return __tree_.size() == 0;}
2105 _LIBCPP_INLINE_VISIBILITY
2106 size_type size() const _NOEXCEPT {return __tree_.size();}
2107 _LIBCPP_INLINE_VISIBILITY
2108 size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
2110 _LIBCPP_INLINE_VISIBILITY
2111 allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());}
2112 _LIBCPP_INLINE_VISIBILITY
2113 key_compare key_comp() const {return __tree_.value_comp().key_comp();}
2114 _LIBCPP_INLINE_VISIBILITY
2115 value_compare value_comp() const
2116 {return value_compare(__tree_.value_comp().key_comp());}
2118 #ifndef _LIBCPP_CXX03_LANG
2120 template <class ..._Args>
2121 _LIBCPP_INLINE_VISIBILITY
2122 iterator emplace(_Args&& ...__args) {
2123 return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...);
2126 template <class ..._Args>
2127 _LIBCPP_INLINE_VISIBILITY
2128 iterator emplace_hint(const_iterator __p, _Args&& ...__args) {
2129 return __tree_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...);
2132 template <class _Pp,
2133 class = __enable_if_t<is_constructible<value_type, _Pp>::value>>
2134 _LIBCPP_INLINE_VISIBILITY
2135 iterator insert(_Pp&& __p)
2136 {return __tree_.__insert_multi(_VSTD::forward<_Pp>(__p));}
2138 template <class _Pp,
2139 class = __enable_if_t<is_constructible<value_type, _Pp>::value>>
2140 _LIBCPP_INLINE_VISIBILITY
2141 iterator insert(const_iterator __pos, _Pp&& __p)
2142 {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));}
2144 _LIBCPP_INLINE_VISIBILITY
2145 iterator insert(value_type&& __v)
2146 {return __tree_.__insert_multi(_VSTD::move(__v));}
2148 _LIBCPP_INLINE_VISIBILITY
2149 iterator insert(const_iterator __p, value_type&& __v)
2150 {return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));}
2153 _LIBCPP_INLINE_VISIBILITY
2154 void insert(initializer_list<value_type> __il)
2155 {insert(__il.begin(), __il.end());}
2157 #endif // _LIBCPP_CXX03_LANG
2159 _LIBCPP_INLINE_VISIBILITY
2160 iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);}
2162 _LIBCPP_INLINE_VISIBILITY
2163 iterator insert(const_iterator __p, const value_type& __v)
2164 {return __tree_.__insert_multi(__p.__i_, __v);}
2166 template <class _InputIterator>
2167 _LIBCPP_INLINE_VISIBILITY
2168 void insert(_InputIterator __f, _InputIterator __l)
2170 for (const_iterator __e = cend(); __f != __l; ++__f)
2171 __tree_.__insert_multi(__e.__i_, *__f);
2174 #if _LIBCPP_STD_VER >= 23
2175 template <_ContainerCompatibleRange<value_type> _Range>
2176 _LIBCPP_HIDE_FROM_ABI
2177 void insert_range(_Range&& __range) {
2178 const_iterator __end = cend();
2179 for (auto&& __element : __range) {
2180 __tree_.__insert_multi(__end.__i_, std::forward<decltype(__element)>(__element));
2185 _LIBCPP_INLINE_VISIBILITY
2186 iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
2187 _LIBCPP_INLINE_VISIBILITY
2188 iterator erase(iterator __p) {return __tree_.erase(__p.__i_);}
2189 _LIBCPP_INLINE_VISIBILITY
2190 size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}
2191 _LIBCPP_INLINE_VISIBILITY
2192 iterator erase(const_iterator __f, const_iterator __l)
2193 {return __tree_.erase(__f.__i_, __l.__i_);}
2195 #if _LIBCPP_STD_VER >= 17
2196 _LIBCPP_INLINE_VISIBILITY
2197 iterator insert(node_type&& __nh)
2199 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
2200 "node_type with incompatible allocator passed to multimap::insert()");
2201 return __tree_.template __node_handle_insert_multi<node_type>(
2204 _LIBCPP_INLINE_VISIBILITY
2205 iterator insert(const_iterator __hint, node_type&& __nh)
2207 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
2208 "node_type with incompatible allocator passed to multimap::insert()");
2209 return __tree_.template __node_handle_insert_multi<node_type>(
2210 __hint.__i_, _VSTD::move(__nh));
2212 _LIBCPP_INLINE_VISIBILITY
2213 node_type extract(key_type const& __key)
2215 return __tree_.template __node_handle_extract<node_type>(__key);
2217 _LIBCPP_INLINE_VISIBILITY
2218 node_type extract(const_iterator __it)
2220 return __tree_.template __node_handle_extract<node_type>(
2223 template <class _Compare2>
2224 _LIBCPP_INLINE_VISIBILITY
2225 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
2227 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2228 "merging container with incompatible allocator");
2229 return __tree_.__node_handle_merge_multi(__source.__tree_);
2231 template <class _Compare2>
2232 _LIBCPP_INLINE_VISIBILITY
2233 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
2235 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2236 "merging container with incompatible allocator");
2237 return __tree_.__node_handle_merge_multi(__source.__tree_);
2239 template <class _Compare2>
2240 _LIBCPP_INLINE_VISIBILITY
2241 void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
2243 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2244 "merging container with incompatible allocator");
2245 return __tree_.__node_handle_merge_multi(__source.__tree_);
2247 template <class _Compare2>
2248 _LIBCPP_INLINE_VISIBILITY
2249 void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
2251 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(),
2252 "merging container with incompatible allocator");
2253 return __tree_.__node_handle_merge_multi(__source.__tree_);
2257 _LIBCPP_INLINE_VISIBILITY
2258 void clear() _NOEXCEPT {__tree_.clear();}
2260 _LIBCPP_INLINE_VISIBILITY
2261 void swap(multimap& __m)
2262 _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
2263 {__tree_.swap(__m.__tree_);}
2265 _LIBCPP_INLINE_VISIBILITY
2266 iterator find(const key_type& __k) {return __tree_.find(__k);}
2267 _LIBCPP_INLINE_VISIBILITY
2268 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
2269 #if _LIBCPP_STD_VER >= 14
2270 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
2271 _LIBCPP_INLINE_VISIBILITY
2273 find(const _K2& __k) {return __tree_.find(__k);}
2274 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
2275 _LIBCPP_INLINE_VISIBILITY
2277 find(const _K2& __k) const {return __tree_.find(__k);}
2280 _LIBCPP_INLINE_VISIBILITY
2281 size_type count(const key_type& __k) const
2282 {return __tree_.__count_multi(__k);}
2283 #if _LIBCPP_STD_VER >= 14
2284 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
2285 _LIBCPP_INLINE_VISIBILITY
2287 count(const _K2& __k) const {return __tree_.__count_multi(__k);}
2290 #if _LIBCPP_STD_VER >= 20
2291 _LIBCPP_INLINE_VISIBILITY
2292 bool contains(const key_type& __k) const {return find(__k) != end();}
2293 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
2294 _LIBCPP_INLINE_VISIBILITY
2296 contains(const _K2& __k) const { return find(__k) != end(); }
2297 #endif // _LIBCPP_STD_VER >= 20
2299 _LIBCPP_INLINE_VISIBILITY
2300 iterator lower_bound(const key_type& __k)
2301 {return __tree_.lower_bound(__k);}
2302 _LIBCPP_INLINE_VISIBILITY
2303 const_iterator lower_bound(const key_type& __k) const
2304 {return __tree_.lower_bound(__k);}
2305 #if _LIBCPP_STD_VER >= 14
2306 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
2307 _LIBCPP_INLINE_VISIBILITY
2309 lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);}
2311 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
2312 _LIBCPP_INLINE_VISIBILITY
2314 lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
2317 _LIBCPP_INLINE_VISIBILITY
2318 iterator upper_bound(const key_type& __k)
2319 {return __tree_.upper_bound(__k);}
2320 _LIBCPP_INLINE_VISIBILITY
2321 const_iterator upper_bound(const key_type& __k) const
2322 {return __tree_.upper_bound(__k);}
2323 #if _LIBCPP_STD_VER >= 14
2324 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
2325 _LIBCPP_INLINE_VISIBILITY
2327 upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);}
2328 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
2329 _LIBCPP_INLINE_VISIBILITY
2331 upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
2334 _LIBCPP_INLINE_VISIBILITY
2335 pair<iterator,iterator> equal_range(const key_type& __k)
2336 {return __tree_.__equal_range_multi(__k);}
2337 _LIBCPP_INLINE_VISIBILITY
2338 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
2339 {return __tree_.__equal_range_multi(__k);}
2340 #if _LIBCPP_STD_VER >= 14
2341 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
2342 _LIBCPP_INLINE_VISIBILITY
2343 pair<iterator,iterator>
2344 equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
2345 template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
2346 _LIBCPP_INLINE_VISIBILITY
2347 pair<const_iterator,const_iterator>
2348 equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
2352 typedef typename __base::__node __node;
2353 typedef typename __base::__node_allocator __node_allocator;
2354 typedef typename __base::__node_pointer __node_pointer;
2356 typedef __map_node_destructor<__node_allocator> _Dp;
2357 typedef unique_ptr<__node, _Dp> __node_holder;
2360 #if _LIBCPP_STD_VER >= 17
2361 template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>,
2362 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
2363 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
2364 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
2365 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2366 multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
2367 -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
2369 #if _LIBCPP_STD_VER >= 23
2370 template <ranges::input_range _Range, class _Compare = less<__range_key_type<_Range>>,
2371 class _Allocator = allocator<__range_to_alloc_type<_Range>>,
2372 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
2373 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2374 multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
2375 -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
2378 template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>,
2379 class _Allocator = allocator<pair<const _Key, _Tp>>,
2380 class = enable_if_t<!__is_allocator<_Compare>::value, void>,
2381 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2382 multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator())
2383 -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
2385 template<class _InputIterator, class _Allocator,
2386 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
2387 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2388 multimap(_InputIterator, _InputIterator, _Allocator)
2389 -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
2390 less<__iter_key_type<_InputIterator>>, _Allocator>;
2392 #if _LIBCPP_STD_VER >= 23
2393 template <ranges::input_range _Range, class _Allocator,
2394 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2395 multimap(from_range_t, _Range&&, _Allocator)
2396 -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
2399 template<class _Key, class _Tp, class _Allocator,
2400 class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2401 multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
2402 -> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
2405 #ifndef _LIBCPP_CXX03_LANG
2406 template <class _Key, class _Tp, class _Compare, class _Allocator>
2407 multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a)
2408 : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a))
2410 if (__a != __m.get_allocator())
2412 const_iterator __e = cend();
2413 while (!__m.empty())
2414 __tree_.__insert_multi(__e.__i_,
2415 _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__move()));
2420 template <class _Key, class _Tp, class _Compare, class _Allocator>
2421 inline _LIBCPP_INLINE_VISIBILITY
2423 operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2424 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2426 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
2429 #if _LIBCPP_STD_VER <= 17
2431 template <class _Key, class _Tp, class _Compare, class _Allocator>
2432 inline _LIBCPP_INLINE_VISIBILITY
2434 operator< (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2435 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2437 return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
2440 template <class _Key, class _Tp, class _Compare, class _Allocator>
2441 inline _LIBCPP_INLINE_VISIBILITY
2443 operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2444 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2446 return !(__x == __y);
2449 template <class _Key, class _Tp, class _Compare, class _Allocator>
2450 inline _LIBCPP_INLINE_VISIBILITY
2452 operator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2453 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2458 template <class _Key, class _Tp, class _Compare, class _Allocator>
2459 inline _LIBCPP_INLINE_VISIBILITY
2461 operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2462 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2464 return !(__x < __y);
2467 template <class _Key, class _Tp, class _Compare, class _Allocator>
2468 inline _LIBCPP_INLINE_VISIBILITY
2470 operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2471 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2473 return !(__y < __x);
2476 #else // #if _LIBCPP_STD_VER <= 17
2478 template <class _Key, class _Tp, class _Compare, class _Allocator>
2479 _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
2480 operator<=>(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2481 const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
2482 return std::lexicographical_compare_three_way(
2487 std::__synth_three_way<pair<const _Key, _Tp>, pair<const _Key, _Tp>>);
2490 #endif // #if _LIBCPP_STD_VER <= 17
2492 template <class _Key, class _Tp, class _Compare, class _Allocator>
2493 inline _LIBCPP_INLINE_VISIBILITY
2495 swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2496 multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2497 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2502 #if _LIBCPP_STD_VER >= 20
2503 template <class _Key, class _Tp, class _Compare, class _Allocator,
2505 inline _LIBCPP_INLINE_VISIBILITY
2506 typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type
2507 erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c,
2508 _Predicate __pred) {
2509 return _VSTD::__libcpp_erase_if_container(__c, __pred);
2513 _LIBCPP_END_NAMESPACE_STD
2515 #if _LIBCPP_STD_VER >= 17
2516 _LIBCPP_BEGIN_NAMESPACE_STD
2518 template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
2519 using map _LIBCPP_AVAILABILITY_PMR = std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
2521 template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
2522 using multimap _LIBCPP_AVAILABILITY_PMR = std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
2524 _LIBCPP_END_NAMESPACE_STD
2527 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
2528 # include <concepts>
2530 # include <functional>
2531 # include <iterator>
2532 # include <type_traits>
2536 #endif // _LIBCPP_MAP