xref: /llvm-project-15.0.7/libcxx/include/map (revision cf6a7c19)
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_MAP
11#define _LIBCPP_MAP
12
13/*
14
15    map synopsis
16
17namespace std
18{
19
20template <class Key, class T, class Compare = less<Key>,
21          class Allocator = allocator<pair<const Key, T>>>
22class map
23{
24public:
25    // types:
26    typedef Key                                      key_type;
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;
37
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
44
45    class value_compare
46    {
47        friend class map;
48    protected:
49        key_compare comp;
50
51        value_compare(key_compare c);
52    public:
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;
57    };
58
59    // construct/copy/destroy:
60    map()
61        noexcept(
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    map(const map& m);
74    map(map&& m)
75        noexcept(
76            is_nothrow_move_constructible<allocator_type>::value &&
77            is_nothrow_move_constructible<key_compare>::value);
78    explicit map(const allocator_type& a);
79    map(const map& m, const allocator_type& a);
80    map(map&& m, const allocator_type& a);
81    map(initializer_list<value_type> il, const key_compare& comp = key_compare());
82    map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
83    template <class InputIterator>
84        map(InputIterator first, InputIterator last, const allocator_type& a)
85            : map(first, last, Compare(), a) {}  // C++14
86    map(initializer_list<value_type> il, const allocator_type& a)
87        : map(il, Compare(), a) {}  // C++14
88   ~map();
89
90    map& operator=(const map& m);
91    map& operator=(map&& m)
92        noexcept(
93            allocator_type::propagate_on_container_move_assignment::value &&
94            is_nothrow_move_assignable<allocator_type>::value &&
95            is_nothrow_move_assignable<key_compare>::value);
96    map& operator=(initializer_list<value_type> il);
97
98    // iterators:
99          iterator begin() noexcept;
100    const_iterator begin() const noexcept;
101          iterator end() noexcept;
102    const_iterator end()   const noexcept;
103
104          reverse_iterator rbegin() noexcept;
105    const_reverse_iterator rbegin() const noexcept;
106          reverse_iterator rend() noexcept;
107    const_reverse_iterator rend()   const noexcept;
108
109    const_iterator         cbegin()  const noexcept;
110    const_iterator         cend()    const noexcept;
111    const_reverse_iterator crbegin() const noexcept;
112    const_reverse_iterator crend()   const noexcept;
113
114    // capacity:
115    bool      empty()    const noexcept;
116    size_type size()     const noexcept;
117    size_type max_size() const noexcept;
118
119    // element access:
120    mapped_type& operator[](const key_type& k);
121    mapped_type& operator[](key_type&& k);
122
123          mapped_type& at(const key_type& k);
124    const mapped_type& at(const key_type& k) const;
125
126    // modifiers:
127    template <class... Args>
128        pair<iterator, bool> emplace(Args&&... args);
129    template <class... Args>
130        iterator emplace_hint(const_iterator position, Args&&... args);
131    pair<iterator, bool> insert(const value_type& v);
132    pair<iterator, bool> insert(      value_type&& v);                                // C++17
133    template <class P>
134        pair<iterator, bool> insert(P&& p);
135    iterator insert(const_iterator position, const value_type& v);
136    iterator insert(const_iterator position,       value_type&& v);                   // C++17
137    template <class P>
138        iterator insert(const_iterator position, P&& p);
139    template <class InputIterator>
140        void insert(InputIterator first, InputIterator last);
141    void insert(initializer_list<value_type> il);
142
143    node_type extract(const_iterator position);                                       // C++17
144    node_type extract(const key_type& x);                                             // C++17
145    insert_return_type insert(node_type&& nh);                                        // C++17
146    iterator insert(const_iterator hint, node_type&& nh);                             // C++17
147
148    template <class... Args>
149        pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);          // C++17
150    template <class... Args>
151        pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);               // C++17
152    template <class... Args>
153        iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
154    template <class... Args>
155        iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);      // C++17
156    template <class M>
157        pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);            // C++17
158    template <class M>
159        pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);                 // C++17
160    template <class M>
161        iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);   // C++17
162    template <class M>
163        iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);        // C++17
164
165    iterator  erase(const_iterator position);
166    iterator  erase(iterator position); // C++14
167    size_type erase(const key_type& k);
168    iterator  erase(const_iterator first, const_iterator last);
169    void clear() noexcept;
170
171    template<class C2>
172      void merge(map<Key, T, C2, Allocator>& source);         // C++17
173    template<class C2>
174      void merge(map<Key, T, C2, Allocator>&& source);        // C++17
175    template<class C2>
176      void merge(multimap<Key, T, C2, Allocator>& source);    // C++17
177    template<class C2>
178      void merge(multimap<Key, T, C2, Allocator>&& source);   // C++17
179
180    void swap(map& m)
181        noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
182            is_nothrow_swappable<key_compare>::value); // C++17
183
184    // observers:
185    allocator_type get_allocator() const noexcept;
186    key_compare    key_comp()      const;
187    value_compare  value_comp()    const;
188
189    // map operations:
190          iterator find(const key_type& k);
191    const_iterator find(const key_type& k) const;
192    template<typename K>
193        iterator find(const K& x);              // C++14
194    template<typename K>
195        const_iterator find(const K& x) const;  // C++14
196
197    template<typename K>
198      size_type count(const K& x) const;        // C++14
199    size_type      count(const key_type& k) const;
200
201    bool           contains(const key_type& x) const;  // C++20
202    template<class K> bool contains(const K& x) const; // C++20
203
204          iterator lower_bound(const key_type& k);
205    const_iterator lower_bound(const key_type& k) const;
206    template<typename K>
207        iterator lower_bound(const K& x);              // C++14
208    template<typename K>
209        const_iterator lower_bound(const K& x) const;  // C++14
210
211          iterator upper_bound(const key_type& k);
212    const_iterator upper_bound(const key_type& k) const;
213    template<typename K>
214        iterator upper_bound(const K& x);              // C++14
215    template<typename K>
216        const_iterator upper_bound(const K& x) const;  // C++14
217
218    pair<iterator,iterator>             equal_range(const key_type& k);
219    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
220    template<typename K>
221        pair<iterator,iterator>             equal_range(const K& x);        // C++14
222    template<typename K>
223        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
224};
225
226template <class InputIterator,
227      class Compare = less<iter_key_t<InputIterator>>,
228      class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
229map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
230  -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17
231
232template<class Key, class T, class Compare = less<Key>,
233    class Allocator = allocator<pair<const Key, T>>>
234map(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
235  -> map<Key, T, Compare, Allocator>; // C++17
236
237template <class InputIterator, class Allocator>
238map(InputIterator, InputIterator, Allocator)
239  -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, less<iter_key_t<InputIterator>>,
240    Allocator>; // C++17
241
242template<class Key, class T, class Allocator>
243map(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>; // C++17
244
245template <class Key, class T, class Compare, class Allocator>
246bool
247operator==(const map<Key, T, Compare, Allocator>& x,
248           const map<Key, T, Compare, Allocator>& y);
249
250template <class Key, class T, class Compare, class Allocator>
251bool
252operator< (const map<Key, T, Compare, Allocator>& x,
253           const map<Key, T, Compare, Allocator>& y);
254
255template <class Key, class T, class Compare, class Allocator>
256bool
257operator!=(const map<Key, T, Compare, Allocator>& x,
258           const map<Key, T, Compare, Allocator>& y);
259
260template <class Key, class T, class Compare, class Allocator>
261bool
262operator> (const map<Key, T, Compare, Allocator>& x,
263           const map<Key, T, Compare, Allocator>& y);
264
265template <class Key, class T, class Compare, class Allocator>
266bool
267operator>=(const map<Key, T, Compare, Allocator>& x,
268           const map<Key, T, Compare, Allocator>& y);
269
270template <class Key, class T, class Compare, class Allocator>
271bool
272operator<=(const map<Key, T, Compare, Allocator>& x,
273           const map<Key, T, Compare, Allocator>& y);
274
275// specialized algorithms:
276template <class Key, class T, class Compare, class Allocator>
277void
278swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
279    noexcept(noexcept(x.swap(y)));
280
281template <class Key, class T, class Compare, class Allocator, class Predicate>
282typename map<Key, T, Compare, Allocator>::size_type
283erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20
284
285
286template <class Key, class T, class Compare = less<Key>,
287          class Allocator = allocator<pair<const Key, T>>>
288class multimap
289{
290public:
291    // types:
292    typedef Key                                      key_type;
293    typedef T                                        mapped_type;
294    typedef pair<const key_type,mapped_type>         value_type;
295    typedef Compare                                  key_compare;
296    typedef Allocator                                allocator_type;
297    typedef typename allocator_type::reference       reference;
298    typedef typename allocator_type::const_reference const_reference;
299    typedef typename allocator_type::size_type       size_type;
300    typedef typename allocator_type::difference_type difference_type;
301    typedef typename allocator_type::pointer         pointer;
302    typedef typename allocator_type::const_pointer   const_pointer;
303
304    typedef implementation-defined                   iterator;
305    typedef implementation-defined                   const_iterator;
306    typedef std::reverse_iterator<iterator>          reverse_iterator;
307    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
308    typedef unspecified                              node_type;              // C++17
309
310    class value_compare
311    {
312        friend class multimap;
313    protected:
314        key_compare comp;
315        value_compare(key_compare c);
316    public:
317        typedef bool result_type;  // deprecated in C++17, removed in C++20
318        typedef value_type first_argument_type;  // deprecated in C++17, removed in C++20
319        typedef value_type second_argument_type;  // deprecated in C++17, removed in C++20
320        bool operator()(const value_type& x, const value_type& y) const;
321    };
322
323    // construct/copy/destroy:
324    multimap()
325        noexcept(
326            is_nothrow_default_constructible<allocator_type>::value &&
327            is_nothrow_default_constructible<key_compare>::value &&
328            is_nothrow_copy_constructible<key_compare>::value);
329    explicit multimap(const key_compare& comp);
330    multimap(const key_compare& comp, const allocator_type& a);
331    template <class InputIterator>
332        multimap(InputIterator first, InputIterator last, const key_compare& comp);
333    template <class InputIterator>
334        multimap(InputIterator first, InputIterator last, const key_compare& comp,
335                 const allocator_type& a);
336    multimap(const multimap& m);
337    multimap(multimap&& m)
338        noexcept(
339            is_nothrow_move_constructible<allocator_type>::value &&
340            is_nothrow_move_constructible<key_compare>::value);
341    explicit multimap(const allocator_type& a);
342    multimap(const multimap& m, const allocator_type& a);
343    multimap(multimap&& m, const allocator_type& a);
344    multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());
345    multimap(initializer_list<value_type> il, const key_compare& comp,
346             const allocator_type& a);
347    template <class InputIterator>
348        multimap(InputIterator first, InputIterator last, const allocator_type& a)
349            : multimap(first, last, Compare(), a) {} // C++14
350    multimap(initializer_list<value_type> il, const allocator_type& a)
351        : multimap(il, Compare(), a) {} // C++14
352    ~multimap();
353
354    multimap& operator=(const multimap& m);
355    multimap& operator=(multimap&& m)
356        noexcept(
357            allocator_type::propagate_on_container_move_assignment::value &&
358            is_nothrow_move_assignable<allocator_type>::value &&
359            is_nothrow_move_assignable<key_compare>::value);
360    multimap& operator=(initializer_list<value_type> il);
361
362    // iterators:
363          iterator begin() noexcept;
364    const_iterator begin() const noexcept;
365          iterator end() noexcept;
366    const_iterator end()   const noexcept;
367
368          reverse_iterator rbegin() noexcept;
369    const_reverse_iterator rbegin() const noexcept;
370          reverse_iterator rend() noexcept;
371    const_reverse_iterator rend()   const noexcept;
372
373    const_iterator         cbegin()  const noexcept;
374    const_iterator         cend()    const noexcept;
375    const_reverse_iterator crbegin() const noexcept;
376    const_reverse_iterator crend()   const noexcept;
377
378    // capacity:
379    bool      empty()    const noexcept;
380    size_type size()     const noexcept;
381    size_type max_size() const noexcept;
382
383    // modifiers:
384    template <class... Args>
385        iterator emplace(Args&&... args);
386    template <class... Args>
387        iterator emplace_hint(const_iterator position, Args&&... args);
388    iterator insert(const value_type& v);
389    iterator insert(      value_type&& v);                                            // C++17
390    template <class P>
391        iterator insert(P&& p);
392    iterator insert(const_iterator position, const value_type& v);
393    iterator insert(const_iterator position,       value_type&& v);                   // C++17
394    template <class P>
395        iterator insert(const_iterator position, P&& p);
396    template <class InputIterator>
397        void insert(InputIterator first, InputIterator last);
398    void insert(initializer_list<value_type> il);
399
400    node_type extract(const_iterator position);                                       // C++17
401    node_type extract(const key_type& x);                                             // C++17
402    iterator insert(node_type&& nh);                                                  // C++17
403    iterator insert(const_iterator hint, node_type&& nh);                             // C++17
404
405    iterator  erase(const_iterator position);
406    iterator  erase(iterator position); // C++14
407    size_type erase(const key_type& k);
408    iterator  erase(const_iterator first, const_iterator last);
409    void clear() noexcept;
410
411    template<class C2>
412      void merge(multimap<Key, T, C2, Allocator>& source);    // C++17
413    template<class C2>
414      void merge(multimap<Key, T, C2, Allocator>&& source);   // C++17
415    template<class C2>
416      void merge(map<Key, T, C2, Allocator>& source);         // C++17
417    template<class C2>
418      void merge(map<Key, T, C2, Allocator>&& source);        // C++17
419
420    void swap(multimap& m)
421        noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
422            is_nothrow_swappable<key_compare>::value); // C++17
423
424    // observers:
425    allocator_type get_allocator() const noexcept;
426    key_compare    key_comp()      const;
427    value_compare  value_comp()    const;
428
429    // map operations:
430          iterator find(const key_type& k);
431    const_iterator find(const key_type& k) const;
432    template<typename K>
433        iterator find(const K& x);              // C++14
434    template<typename K>
435        const_iterator find(const K& x) const;  // C++14
436
437    template<typename K>
438      size_type count(const K& x) const;        // C++14
439    size_type      count(const key_type& k) const;
440
441    bool           contains(const key_type& x) const;  // C++20
442    template<class K> bool contains(const K& x) const; // C++20
443
444          iterator lower_bound(const key_type& k);
445    const_iterator lower_bound(const key_type& k) const;
446    template<typename K>
447        iterator lower_bound(const K& x);              // C++14
448    template<typename K>
449        const_iterator lower_bound(const K& x) const;  // C++14
450
451          iterator upper_bound(const key_type& k);
452    const_iterator upper_bound(const key_type& k) const;
453    template<typename K>
454        iterator upper_bound(const K& x);              // C++14
455    template<typename K>
456        const_iterator upper_bound(const K& x) const;  // C++14
457
458    pair<iterator,iterator>             equal_range(const key_type& k);
459    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
460    template<typename K>
461        pair<iterator,iterator>             equal_range(const K& x);        // C++14
462    template<typename K>
463        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
464};
465
466template <class InputIterator,
467      class Compare = less<iter_key_t<InputIterator>>,
468      class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
469multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
470  -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17
471
472template<class Key, class T, class Compare = less<Key>,
473    class Allocator = allocator<pair<const Key, T>>>
474multimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
475  -> multimap<Key, T, Compare, Allocator>; // C++17
476
477template <class InputIterator, class Allocator>
478multimap(InputIterator, InputIterator, Allocator)
479  -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
480    less<iter_key_t<InputIterator>>, Allocator>; // C++17
481
482template<class Key, class T, class Allocator>
483multimap(initializer_list<pair<const Key, T>>, Allocator)
484  -> multimap<Key, T, less<Key>, Allocator>; // C++17
485
486template <class Key, class T, class Compare, class Allocator>
487bool
488operator==(const multimap<Key, T, Compare, Allocator>& x,
489           const multimap<Key, T, Compare, Allocator>& y);
490
491template <class Key, class T, class Compare, class Allocator>
492bool
493operator< (const multimap<Key, T, Compare, Allocator>& x,
494           const multimap<Key, T, Compare, Allocator>& y);
495
496template <class Key, class T, class Compare, class Allocator>
497bool
498operator!=(const multimap<Key, T, Compare, Allocator>& x,
499           const multimap<Key, T, Compare, Allocator>& y);
500
501template <class Key, class T, class Compare, class Allocator>
502bool
503operator> (const multimap<Key, T, Compare, Allocator>& x,
504           const multimap<Key, T, Compare, Allocator>& y);
505
506template <class Key, class T, class Compare, class Allocator>
507bool
508operator>=(const multimap<Key, T, Compare, Allocator>& x,
509           const multimap<Key, T, Compare, Allocator>& y);
510
511template <class Key, class T, class Compare, class Allocator>
512bool
513operator<=(const multimap<Key, T, Compare, Allocator>& x,
514           const multimap<Key, T, Compare, Allocator>& y);
515
516// specialized algorithms:
517template <class Key, class T, class Compare, class Allocator>
518void
519swap(multimap<Key, T, Compare, Allocator>& x,
520     multimap<Key, T, Compare, Allocator>& y)
521    noexcept(noexcept(x.swap(y)));
522
523template <class Key, class T, class Compare, class Allocator, class Predicate>
524typename multimap<Key, T, Compare, Allocator>::size_type
525erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20
526
527}  // std
528
529*/
530
531#include <__algorithm/equal.h>
532#include <__algorithm/lexicographical_compare.h>
533#include <__assert> // all public C++ headers provide the assertion handler
534#include <__config>
535#include <__functional/binary_function.h>
536#include <__functional/is_transparent.h>
537#include <__functional/operations.h>
538#include <__iterator/erase_if_container.h>
539#include <__iterator/iterator_traits.h>
540#include <__iterator/reverse_iterator.h>
541#include <__node_handle>
542#include <__tree>
543#include <__utility/forward.h>
544#include <__utility/swap.h>
545#include <compare>
546#include <initializer_list>
547#include <iterator> // TODO: Remove this include
548#include <memory>
549#include <type_traits>
550#include <version>
551
552#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
553#  pragma GCC system_header
554#endif
555
556_LIBCPP_BEGIN_NAMESPACE_STD
557
558template <class _Key, class _CP, class _Compare,
559          bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
560class __map_value_compare
561    : private _Compare
562{
563public:
564    _LIBCPP_INLINE_VISIBILITY
565    __map_value_compare()
566        _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
567        : _Compare() {}
568    _LIBCPP_INLINE_VISIBILITY
569    __map_value_compare(_Compare c)
570        _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
571        : _Compare(c) {}
572    _LIBCPP_INLINE_VISIBILITY
573    const _Compare& key_comp() const _NOEXCEPT {return *this;}
574    _LIBCPP_INLINE_VISIBILITY
575    bool operator()(const _CP& __x, const _CP& __y) const
576        {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y.__get_value().first);}
577    _LIBCPP_INLINE_VISIBILITY
578    bool operator()(const _CP& __x, const _Key& __y) const
579        {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);}
580    _LIBCPP_INLINE_VISIBILITY
581    bool operator()(const _Key& __x, const _CP& __y) const
582        {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);}
583    void swap(__map_value_compare& __y)
584        _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
585    {
586      using _VSTD::swap;
587      swap(static_cast<_Compare&>(*this), static_cast<_Compare&>(__y));
588    }
589
590#if _LIBCPP_STD_VER > 11
591    template <typename _K2>
592    _LIBCPP_INLINE_VISIBILITY
593    bool operator()(const _K2& __x, const _CP& __y) const
594        {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);}
595
596    template <typename _K2>
597    _LIBCPP_INLINE_VISIBILITY
598    bool operator()(const _CP& __x, const _K2& __y) const
599        {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);}
600#endif
601};
602
603template <class _Key, class _CP, class _Compare>
604class __map_value_compare<_Key, _CP, _Compare, false>
605{
606    _Compare comp;
607
608public:
609    _LIBCPP_INLINE_VISIBILITY
610    __map_value_compare()
611        _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
612        : comp() {}
613    _LIBCPP_INLINE_VISIBILITY
614    __map_value_compare(_Compare c)
615        _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
616        : comp(c) {}
617    _LIBCPP_INLINE_VISIBILITY
618    const _Compare& key_comp() const _NOEXCEPT {return comp;}
619
620    _LIBCPP_INLINE_VISIBILITY
621    bool operator()(const _CP& __x, const _CP& __y) const
622        {return comp(__x.__get_value().first, __y.__get_value().first);}
623    _LIBCPP_INLINE_VISIBILITY
624    bool operator()(const _CP& __x, const _Key& __y) const
625        {return comp(__x.__get_value().first, __y);}
626    _LIBCPP_INLINE_VISIBILITY
627    bool operator()(const _Key& __x, const _CP& __y) const
628        {return comp(__x, __y.__get_value().first);}
629    void swap(__map_value_compare& __y)
630        _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
631    {
632        using _VSTD::swap;
633        swap(comp, __y.comp);
634    }
635
636#if _LIBCPP_STD_VER > 11
637    template <typename _K2>
638    _LIBCPP_INLINE_VISIBILITY
639    bool operator()(const _K2& __x, const _CP& __y) const
640        {return comp(__x, __y.__get_value().first);}
641
642    template <typename _K2>
643    _LIBCPP_INLINE_VISIBILITY
644    bool operator()(const _CP& __x, const _K2& __y) const
645        {return comp(__x.__get_value().first, __y);}
646#endif
647};
648
649template <class _Key, class _CP, class _Compare, bool __b>
650inline _LIBCPP_INLINE_VISIBILITY
651void
652swap(__map_value_compare<_Key, _CP, _Compare, __b>& __x,
653     __map_value_compare<_Key, _CP, _Compare, __b>& __y)
654    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
655{
656    __x.swap(__y);
657}
658
659template <class _Allocator>
660class __map_node_destructor
661{
662    typedef _Allocator                          allocator_type;
663    typedef allocator_traits<allocator_type>    __alloc_traits;
664
665public:
666    typedef typename __alloc_traits::pointer    pointer;
667
668private:
669    allocator_type& __na_;
670
671    __map_node_destructor& operator=(const __map_node_destructor&);
672
673public:
674    bool __first_constructed;
675    bool __second_constructed;
676
677    _LIBCPP_INLINE_VISIBILITY
678    explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT
679        : __na_(__na),
680          __first_constructed(false),
681          __second_constructed(false)
682        {}
683
684#ifndef _LIBCPP_CXX03_LANG
685    _LIBCPP_INLINE_VISIBILITY
686    __map_node_destructor(__tree_node_destructor<allocator_type>&& __x) _NOEXCEPT
687        : __na_(__x.__na_),
688          __first_constructed(__x.__value_constructed),
689          __second_constructed(__x.__value_constructed)
690        {
691            __x.__value_constructed = false;
692        }
693#endif // _LIBCPP_CXX03_LANG
694
695    _LIBCPP_INLINE_VISIBILITY
696    void operator()(pointer __p) _NOEXCEPT
697    {
698        if (__second_constructed)
699            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().second));
700        if (__first_constructed)
701            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().first));
702        if (__p)
703            __alloc_traits::deallocate(__na_, __p, 1);
704    }
705};
706
707template <class _Key, class _Tp, class _Compare, class _Allocator>
708    class map;
709template <class _Key, class _Tp, class _Compare, class _Allocator>
710    class multimap;
711template <class _TreeIterator> class __map_const_iterator;
712
713#ifndef _LIBCPP_CXX03_LANG
714
715template <class _Key, class _Tp>
716struct _LIBCPP_STANDALONE_DEBUG __value_type
717{
718    typedef _Key                                     key_type;
719    typedef _Tp                                      mapped_type;
720    typedef pair<const key_type, mapped_type>        value_type;
721    typedef pair<key_type&, mapped_type&>            __nc_ref_pair_type;
722    typedef pair<key_type&&, mapped_type&&>          __nc_rref_pair_type;
723
724private:
725    value_type __cc;
726
727public:
728    _LIBCPP_INLINE_VISIBILITY
729    value_type& __get_value()
730    {
731#if _LIBCPP_STD_VER > 14
732        return *_VSTD::launder(_VSTD::addressof(__cc));
733#else
734        return __cc;
735#endif
736    }
737
738    _LIBCPP_INLINE_VISIBILITY
739    const value_type& __get_value() const
740    {
741#if _LIBCPP_STD_VER > 14
742        return *_VSTD::launder(_VSTD::addressof(__cc));
743#else
744        return __cc;
745#endif
746    }
747
748    _LIBCPP_INLINE_VISIBILITY
749    __nc_ref_pair_type __ref()
750    {
751        value_type& __v = __get_value();
752        return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second);
753    }
754
755    _LIBCPP_INLINE_VISIBILITY
756    __nc_rref_pair_type __move()
757    {
758        value_type& __v = __get_value();
759        return __nc_rref_pair_type(
760            _VSTD::move(const_cast<key_type&>(__v.first)),
761            _VSTD::move(__v.second));
762    }
763
764    _LIBCPP_INLINE_VISIBILITY
765    __value_type& operator=(const __value_type& __v)
766    {
767        __ref() = __v.__get_value();
768        return *this;
769    }
770
771    _LIBCPP_INLINE_VISIBILITY
772    __value_type& operator=(__value_type&& __v)
773    {
774        __ref() = __v.__move();
775        return *this;
776    }
777
778    template <class _ValueTp,
779              class = typename enable_if<
780                    __is_same_uncvref<_ValueTp, value_type>::value
781                 >::type
782             >
783    _LIBCPP_INLINE_VISIBILITY
784    __value_type& operator=(_ValueTp&& __v)
785    {
786        __ref() = _VSTD::forward<_ValueTp>(__v);
787        return *this;
788    }
789
790private:
791    __value_type() = delete;
792    ~__value_type() = delete;
793    __value_type(const __value_type&) = delete;
794    __value_type(__value_type&&) = delete;
795};
796
797#else
798
799template <class _Key, class _Tp>
800struct __value_type
801{
802    typedef _Key                                     key_type;
803    typedef _Tp                                      mapped_type;
804    typedef pair<const key_type, mapped_type>        value_type;
805
806private:
807    value_type __cc;
808
809public:
810    _LIBCPP_INLINE_VISIBILITY
811    value_type& __get_value() { return __cc; }
812    _LIBCPP_INLINE_VISIBILITY
813    const value_type& __get_value() const { return __cc; }
814
815private:
816   __value_type();
817   __value_type(__value_type const&);
818   __value_type& operator=(__value_type const&);
819   ~__value_type();
820};
821
822#endif // _LIBCPP_CXX03_LANG
823
824template <class _Tp>
825struct __extract_key_value_types;
826
827template <class _Key, class _Tp>
828struct __extract_key_value_types<__value_type<_Key, _Tp> >
829{
830  typedef _Key const __key_type;
831  typedef _Tp        __mapped_type;
832};
833
834template <class _TreeIterator>
835class _LIBCPP_TEMPLATE_VIS __map_iterator
836{
837    typedef typename _TreeIterator::_NodeTypes                   _NodeTypes;
838    typedef typename _TreeIterator::__pointer_traits             __pointer_traits;
839
840    _TreeIterator __i_;
841
842public:
843    typedef bidirectional_iterator_tag                           iterator_category;
844    typedef typename _NodeTypes::__map_value_type                value_type;
845    typedef typename _TreeIterator::difference_type              difference_type;
846    typedef value_type&                                          reference;
847    typedef typename _NodeTypes::__map_value_type_pointer        pointer;
848
849    _LIBCPP_INLINE_VISIBILITY
850    __map_iterator() _NOEXCEPT {}
851
852    _LIBCPP_INLINE_VISIBILITY
853    __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
854
855    _LIBCPP_INLINE_VISIBILITY
856    reference operator*() const {return __i_->__get_value();}
857    _LIBCPP_INLINE_VISIBILITY
858    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}
859
860    _LIBCPP_INLINE_VISIBILITY
861    __map_iterator& operator++() {++__i_; return *this;}
862    _LIBCPP_INLINE_VISIBILITY
863    __map_iterator operator++(int)
864    {
865        __map_iterator __t(*this);
866        ++(*this);
867        return __t;
868    }
869
870    _LIBCPP_INLINE_VISIBILITY
871    __map_iterator& operator--() {--__i_; return *this;}
872    _LIBCPP_INLINE_VISIBILITY
873    __map_iterator operator--(int)
874    {
875        __map_iterator __t(*this);
876        --(*this);
877        return __t;
878    }
879
880    friend _LIBCPP_INLINE_VISIBILITY
881    bool operator==(const __map_iterator& __x, const __map_iterator& __y)
882        {return __x.__i_ == __y.__i_;}
883    friend
884    _LIBCPP_INLINE_VISIBILITY
885    bool operator!=(const __map_iterator& __x, const __map_iterator& __y)
886        {return __x.__i_ != __y.__i_;}
887
888    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
889    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
890    template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
891};
892
893template <class _TreeIterator>
894class _LIBCPP_TEMPLATE_VIS __map_const_iterator
895{
896    typedef typename _TreeIterator::_NodeTypes                   _NodeTypes;
897    typedef typename _TreeIterator::__pointer_traits             __pointer_traits;
898
899    _TreeIterator __i_;
900
901public:
902    typedef bidirectional_iterator_tag                           iterator_category;
903    typedef typename _NodeTypes::__map_value_type                value_type;
904    typedef typename _TreeIterator::difference_type              difference_type;
905    typedef const value_type&                                    reference;
906    typedef typename _NodeTypes::__const_map_value_type_pointer  pointer;
907
908    _LIBCPP_INLINE_VISIBILITY
909    __map_const_iterator() _NOEXCEPT {}
910
911    _LIBCPP_INLINE_VISIBILITY
912    __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
913    _LIBCPP_INLINE_VISIBILITY
914    __map_const_iterator(__map_iterator<
915        typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT
916        : __i_(__i.__i_) {}
917
918    _LIBCPP_INLINE_VISIBILITY
919    reference operator*() const {return __i_->__get_value();}
920    _LIBCPP_INLINE_VISIBILITY
921    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}
922
923    _LIBCPP_INLINE_VISIBILITY
924    __map_const_iterator& operator++() {++__i_; return *this;}
925    _LIBCPP_INLINE_VISIBILITY
926    __map_const_iterator operator++(int)
927    {
928        __map_const_iterator __t(*this);
929        ++(*this);
930        return __t;
931    }
932
933    _LIBCPP_INLINE_VISIBILITY
934    __map_const_iterator& operator--() {--__i_; return *this;}
935    _LIBCPP_INLINE_VISIBILITY
936    __map_const_iterator operator--(int)
937    {
938        __map_const_iterator __t(*this);
939        --(*this);
940        return __t;
941    }
942
943    friend _LIBCPP_INLINE_VISIBILITY
944    bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y)
945        {return __x.__i_ == __y.__i_;}
946    friend _LIBCPP_INLINE_VISIBILITY
947    bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y)
948        {return __x.__i_ != __y.__i_;}
949
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, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
953};
954
955template <class _Key, class _Tp, class _Compare = less<_Key>,
956          class _Allocator = allocator<pair<const _Key, _Tp> > >
957class _LIBCPP_TEMPLATE_VIS map
958{
959public:
960    // types:
961    typedef _Key                                     key_type;
962    typedef _Tp                                      mapped_type;
963    typedef pair<const key_type, mapped_type>        value_type;
964    typedef __type_identity_t<_Compare>              key_compare;
965    typedef __type_identity_t<_Allocator>            allocator_type;
966    typedef value_type&                              reference;
967    typedef const value_type&                        const_reference;
968
969    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
970                  "Allocator::value_type must be same type as value_type");
971
972_LIBCPP_SUPPRESS_DEPRECATED_PUSH
973    class _LIBCPP_TEMPLATE_VIS value_compare
974#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
975        : public binary_function<value_type, value_type, bool>
976#endif
977    {
978_LIBCPP_SUPPRESS_DEPRECATED_POP
979        friend class map;
980    protected:
981        key_compare comp;
982
983        _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {}
984    public:
985#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
986        _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
987        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type first_argument_type;
988        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type second_argument_type;
989#endif
990        _LIBCPP_INLINE_VISIBILITY
991        bool operator()(const value_type& __x, const value_type& __y) const
992            {return comp(__x.first, __y.first);}
993    };
994
995private:
996
997    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
998    typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
999    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
1000                                                 __value_type>::type __allocator_type;
1001    typedef __tree<__value_type, __vc, __allocator_type>   __base;
1002    typedef typename __base::__node_traits                 __node_traits;
1003    typedef allocator_traits<allocator_type>               __alloc_traits;
1004
1005    __base __tree_;
1006
1007public:
1008    typedef typename __alloc_traits::pointer               pointer;
1009    typedef typename __alloc_traits::const_pointer         const_pointer;
1010    typedef typename __alloc_traits::size_type             size_type;
1011    typedef typename __alloc_traits::difference_type       difference_type;
1012    typedef __map_iterator<typename __base::iterator>             iterator;
1013    typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
1014    typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
1015    typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;
1016
1017#if _LIBCPP_STD_VER > 14
1018    typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
1019    typedef __insert_return_type<iterator, node_type> insert_return_type;
1020#endif
1021
1022    template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
1023        friend class _LIBCPP_TEMPLATE_VIS map;
1024    template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
1025        friend class _LIBCPP_TEMPLATE_VIS multimap;
1026
1027    _LIBCPP_INLINE_VISIBILITY
1028    map()
1029        _NOEXCEPT_(
1030            is_nothrow_default_constructible<allocator_type>::value &&
1031            is_nothrow_default_constructible<key_compare>::value &&
1032            is_nothrow_copy_constructible<key_compare>::value)
1033        : __tree_(__vc(key_compare())) {}
1034
1035    _LIBCPP_INLINE_VISIBILITY
1036    explicit map(const key_compare& __comp)
1037        _NOEXCEPT_(
1038            is_nothrow_default_constructible<allocator_type>::value &&
1039            is_nothrow_copy_constructible<key_compare>::value)
1040        : __tree_(__vc(__comp)) {}
1041
1042    _LIBCPP_INLINE_VISIBILITY
1043    explicit map(const key_compare& __comp, const allocator_type& __a)
1044        : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}
1045
1046    template <class _InputIterator>
1047    _LIBCPP_INLINE_VISIBILITY
1048        map(_InputIterator __f, _InputIterator __l,
1049            const key_compare& __comp = key_compare())
1050        : __tree_(__vc(__comp))
1051        {
1052            insert(__f, __l);
1053        }
1054
1055    template <class _InputIterator>
1056    _LIBCPP_INLINE_VISIBILITY
1057        map(_InputIterator __f, _InputIterator __l,
1058            const key_compare& __comp, const allocator_type& __a)
1059        : __tree_(__vc(__comp), typename __base::allocator_type(__a))
1060        {
1061            insert(__f, __l);
1062        }
1063
1064#if _LIBCPP_STD_VER > 11
1065    template <class _InputIterator>
1066    _LIBCPP_INLINE_VISIBILITY
1067    map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
1068        : map(__f, __l, key_compare(), __a) {}
1069#endif
1070
1071    _LIBCPP_INLINE_VISIBILITY
1072    map(const map& __m)
1073        : __tree_(__m.__tree_)
1074        {
1075            insert(__m.begin(), __m.end());
1076        }
1077
1078    _LIBCPP_INLINE_VISIBILITY
1079    map& operator=(const map& __m)
1080        {
1081#ifndef _LIBCPP_CXX03_LANG
1082            __tree_ = __m.__tree_;
1083#else
1084            if (this != _VSTD::addressof(__m)) {
1085                __tree_.clear();
1086                __tree_.value_comp() = __m.__tree_.value_comp();
1087                __tree_.__copy_assign_alloc(__m.__tree_);
1088                insert(__m.begin(), __m.end());
1089            }
1090#endif
1091            return *this;
1092        }
1093
1094#ifndef _LIBCPP_CXX03_LANG
1095
1096    _LIBCPP_INLINE_VISIBILITY
1097    map(map&& __m)
1098        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
1099        : __tree_(_VSTD::move(__m.__tree_))
1100        {
1101        }
1102
1103    map(map&& __m, const allocator_type& __a);
1104
1105    _LIBCPP_INLINE_VISIBILITY
1106    map& operator=(map&& __m)
1107        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
1108        {
1109            __tree_ = _VSTD::move(__m.__tree_);
1110            return *this;
1111        }
1112
1113    _LIBCPP_INLINE_VISIBILITY
1114    map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
1115        : __tree_(__vc(__comp))
1116        {
1117            insert(__il.begin(), __il.end());
1118        }
1119
1120    _LIBCPP_INLINE_VISIBILITY
1121    map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
1122        : __tree_(__vc(__comp), typename __base::allocator_type(__a))
1123        {
1124            insert(__il.begin(), __il.end());
1125        }
1126
1127#if _LIBCPP_STD_VER > 11
1128    _LIBCPP_INLINE_VISIBILITY
1129    map(initializer_list<value_type> __il, const allocator_type& __a)
1130        : map(__il, key_compare(), __a) {}
1131#endif
1132
1133    _LIBCPP_INLINE_VISIBILITY
1134    map& operator=(initializer_list<value_type> __il)
1135        {
1136            __tree_.__assign_unique(__il.begin(), __il.end());
1137            return *this;
1138        }
1139
1140#endif // _LIBCPP_CXX03_LANG
1141
1142    _LIBCPP_INLINE_VISIBILITY
1143    explicit map(const allocator_type& __a)
1144        : __tree_(typename __base::allocator_type(__a))
1145        {
1146        }
1147
1148    _LIBCPP_INLINE_VISIBILITY
1149    map(const map& __m, const allocator_type& __a)
1150        : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a))
1151        {
1152            insert(__m.begin(), __m.end());
1153        }
1154
1155    _LIBCPP_INLINE_VISIBILITY
1156    ~map() {
1157        static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
1158    }
1159
1160    _LIBCPP_INLINE_VISIBILITY
1161          iterator begin() _NOEXCEPT {return __tree_.begin();}
1162    _LIBCPP_INLINE_VISIBILITY
1163    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
1164    _LIBCPP_INLINE_VISIBILITY
1165          iterator end() _NOEXCEPT {return __tree_.end();}
1166    _LIBCPP_INLINE_VISIBILITY
1167    const_iterator end() const _NOEXCEPT {return __tree_.end();}
1168
1169    _LIBCPP_INLINE_VISIBILITY
1170          reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
1171    _LIBCPP_INLINE_VISIBILITY
1172    const_reverse_iterator rbegin() const _NOEXCEPT
1173        {return const_reverse_iterator(end());}
1174    _LIBCPP_INLINE_VISIBILITY
1175          reverse_iterator rend() _NOEXCEPT
1176            {return       reverse_iterator(begin());}
1177    _LIBCPP_INLINE_VISIBILITY
1178    const_reverse_iterator rend() const _NOEXCEPT
1179        {return const_reverse_iterator(begin());}
1180
1181    _LIBCPP_INLINE_VISIBILITY
1182    const_iterator cbegin() const _NOEXCEPT {return begin();}
1183    _LIBCPP_INLINE_VISIBILITY
1184    const_iterator cend() const _NOEXCEPT {return end();}
1185    _LIBCPP_INLINE_VISIBILITY
1186    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
1187    _LIBCPP_INLINE_VISIBILITY
1188    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
1189
1190    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1191    bool      empty() const _NOEXCEPT {return __tree_.size() == 0;}
1192    _LIBCPP_INLINE_VISIBILITY
1193    size_type size() const _NOEXCEPT {return __tree_.size();}
1194    _LIBCPP_INLINE_VISIBILITY
1195    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
1196
1197    mapped_type& operator[](const key_type& __k);
1198#ifndef _LIBCPP_CXX03_LANG
1199    mapped_type& operator[](key_type&& __k);
1200#endif
1201
1202          mapped_type& at(const key_type& __k);
1203    const mapped_type& at(const key_type& __k) const;
1204
1205    _LIBCPP_INLINE_VISIBILITY
1206    allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());}
1207    _LIBCPP_INLINE_VISIBILITY
1208    key_compare    key_comp()      const {return __tree_.value_comp().key_comp();}
1209    _LIBCPP_INLINE_VISIBILITY
1210    value_compare  value_comp()    const {return value_compare(__tree_.value_comp().key_comp());}
1211
1212#ifndef _LIBCPP_CXX03_LANG
1213    template <class ..._Args>
1214    _LIBCPP_INLINE_VISIBILITY
1215    pair<iterator, bool> emplace(_Args&& ...__args) {
1216        return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...);
1217    }
1218
1219    template <class ..._Args>
1220    _LIBCPP_INLINE_VISIBILITY
1221    iterator emplace_hint(const_iterator __p, _Args&& ...__args) {
1222        return __tree_.__emplace_hint_unique(__p.__i_, _VSTD::forward<_Args>(__args)...);
1223    }
1224
1225    template <class _Pp,
1226              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
1227        _LIBCPP_INLINE_VISIBILITY
1228        pair<iterator, bool> insert(_Pp&& __p)
1229            {return __tree_.__insert_unique(_VSTD::forward<_Pp>(__p));}
1230
1231    template <class _Pp,
1232              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
1233        _LIBCPP_INLINE_VISIBILITY
1234        iterator insert(const_iterator __pos, _Pp&& __p)
1235            {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));}
1236
1237#endif // _LIBCPP_CXX03_LANG
1238
1239    _LIBCPP_INLINE_VISIBILITY
1240    pair<iterator, bool>
1241        insert(const value_type& __v) {return __tree_.__insert_unique(__v);}
1242
1243    _LIBCPP_INLINE_VISIBILITY
1244    iterator
1245        insert(const_iterator __p, const value_type& __v)
1246            {return __tree_.__insert_unique(__p.__i_, __v);}
1247
1248#ifndef _LIBCPP_CXX03_LANG
1249    _LIBCPP_INLINE_VISIBILITY
1250    pair<iterator, bool>
1251    insert(value_type&& __v) {return __tree_.__insert_unique(_VSTD::move(__v));}
1252
1253    _LIBCPP_INLINE_VISIBILITY
1254    iterator insert(const_iterator __p,  value_type&& __v)
1255    {return __tree_.__insert_unique(__p.__i_, _VSTD::move(__v));}
1256
1257    _LIBCPP_INLINE_VISIBILITY
1258    void insert(initializer_list<value_type> __il)
1259        {insert(__il.begin(), __il.end());}
1260#endif
1261
1262    template <class _InputIterator>
1263        _LIBCPP_INLINE_VISIBILITY
1264        void insert(_InputIterator __f, _InputIterator __l)
1265        {
1266            for (const_iterator __e = cend(); __f != __l; ++__f)
1267                insert(__e.__i_, *__f);
1268        }
1269
1270#if _LIBCPP_STD_VER > 14
1271
1272    template <class... _Args>
1273        _LIBCPP_INLINE_VISIBILITY
1274        pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args)
1275    {
1276        return __tree_.__emplace_unique_key_args(__k,
1277            _VSTD::piecewise_construct,
1278            _VSTD::forward_as_tuple(__k),
1279            _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
1280    }
1281
1282    template <class... _Args>
1283        _LIBCPP_INLINE_VISIBILITY
1284        pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args)
1285    {
1286        return __tree_.__emplace_unique_key_args(__k,
1287            _VSTD::piecewise_construct,
1288            _VSTD::forward_as_tuple(_VSTD::move(__k)),
1289            _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
1290    }
1291
1292    template <class... _Args>
1293        _LIBCPP_INLINE_VISIBILITY
1294        iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args)
1295    {
1296        return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k,
1297            _VSTD::piecewise_construct,
1298            _VSTD::forward_as_tuple(__k),
1299            _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)).first;
1300    }
1301
1302    template <class... _Args>
1303        _LIBCPP_INLINE_VISIBILITY
1304        iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args)
1305    {
1306        return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k,
1307            _VSTD::piecewise_construct,
1308            _VSTD::forward_as_tuple(_VSTD::move(__k)),
1309            _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)).first;
1310    }
1311
1312    template <class _Vp>
1313        _LIBCPP_INLINE_VISIBILITY
1314        pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v)
1315    {
1316        iterator __p = lower_bound(__k);
1317        if ( __p != end() && !key_comp()(__k, __p->first))
1318        {
1319            __p->second = _VSTD::forward<_Vp>(__v);
1320            return _VSTD::make_pair(__p, false);
1321        }
1322        return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true);
1323    }
1324
1325    template <class _Vp>
1326        _LIBCPP_INLINE_VISIBILITY
1327        pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v)
1328    {
1329        iterator __p = lower_bound(__k);
1330        if ( __p != end() && !key_comp()(__k, __p->first))
1331        {
1332            __p->second = _VSTD::forward<_Vp>(__v);
1333            return _VSTD::make_pair(__p, false);
1334        }
1335        return _VSTD::make_pair(emplace_hint(__p, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)), true);
1336    }
1337
1338    template <class _Vp>
1339    _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h,
1340                                                        const key_type& __k,
1341                                                        _Vp&& __v) {
1342      auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args(
1343          __h.__i_, __k, __k, _VSTD::forward<_Vp>(__v));
1344
1345      if (!__inserted)
1346        __r->__get_value().second = _VSTD::forward<_Vp>(__v);
1347
1348      return __r;
1349    }
1350
1351    template <class _Vp>
1352    _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h,
1353                                                        key_type&& __k,
1354                                                        _Vp&& __v) {
1355      auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args(
1356          __h.__i_, __k, _VSTD::move(__k), _VSTD::forward<_Vp>(__v));
1357
1358      if (!__inserted)
1359        __r->__get_value().second = _VSTD::forward<_Vp>(__v);
1360
1361      return __r;
1362    }
1363
1364#endif // _LIBCPP_STD_VER > 14
1365
1366    _LIBCPP_INLINE_VISIBILITY
1367    iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
1368    _LIBCPP_INLINE_VISIBILITY
1369    iterator erase(iterator __p)       {return __tree_.erase(__p.__i_);}
1370    _LIBCPP_INLINE_VISIBILITY
1371    size_type erase(const key_type& __k)
1372        {return __tree_.__erase_unique(__k);}
1373    _LIBCPP_INLINE_VISIBILITY
1374    iterator  erase(const_iterator __f, const_iterator __l)
1375        {return __tree_.erase(__f.__i_, __l.__i_);}
1376    _LIBCPP_INLINE_VISIBILITY
1377    void clear() _NOEXCEPT {__tree_.clear();}
1378
1379#if _LIBCPP_STD_VER > 14
1380    _LIBCPP_INLINE_VISIBILITY
1381    insert_return_type insert(node_type&& __nh)
1382    {
1383        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1384            "node_type with incompatible allocator passed to map::insert()");
1385        return __tree_.template __node_handle_insert_unique<
1386            node_type, insert_return_type>(_VSTD::move(__nh));
1387    }
1388    _LIBCPP_INLINE_VISIBILITY
1389    iterator insert(const_iterator __hint, node_type&& __nh)
1390    {
1391        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1392            "node_type with incompatible allocator passed to map::insert()");
1393        return __tree_.template __node_handle_insert_unique<node_type>(
1394            __hint.__i_, _VSTD::move(__nh));
1395    }
1396    _LIBCPP_INLINE_VISIBILITY
1397    node_type extract(key_type const& __key)
1398    {
1399        return __tree_.template __node_handle_extract<node_type>(__key);
1400    }
1401    _LIBCPP_INLINE_VISIBILITY
1402    node_type extract(const_iterator __it)
1403    {
1404        return __tree_.template __node_handle_extract<node_type>(__it.__i_);
1405    }
1406    template <class _Compare2>
1407    _LIBCPP_INLINE_VISIBILITY
1408    void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
1409    {
1410        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1411                       "merging container with incompatible allocator");
1412        __tree_.__node_handle_merge_unique(__source.__tree_);
1413    }
1414    template <class _Compare2>
1415    _LIBCPP_INLINE_VISIBILITY
1416    void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
1417    {
1418        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1419                       "merging container with incompatible allocator");
1420        __tree_.__node_handle_merge_unique(__source.__tree_);
1421    }
1422    template <class _Compare2>
1423    _LIBCPP_INLINE_VISIBILITY
1424    void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
1425    {
1426        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1427                       "merging container with incompatible allocator");
1428        __tree_.__node_handle_merge_unique(__source.__tree_);
1429    }
1430    template <class _Compare2>
1431    _LIBCPP_INLINE_VISIBILITY
1432    void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
1433    {
1434        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1435                       "merging container with incompatible allocator");
1436        __tree_.__node_handle_merge_unique(__source.__tree_);
1437    }
1438#endif
1439
1440    _LIBCPP_INLINE_VISIBILITY
1441    void swap(map& __m)
1442        _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
1443        {__tree_.swap(__m.__tree_);}
1444
1445    _LIBCPP_INLINE_VISIBILITY
1446    iterator find(const key_type& __k)             {return __tree_.find(__k);}
1447    _LIBCPP_INLINE_VISIBILITY
1448    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
1449#if _LIBCPP_STD_VER > 11
1450    template <typename _K2>
1451    _LIBCPP_INLINE_VISIBILITY
1452    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
1453    find(const _K2& __k)                           {return __tree_.find(__k);}
1454    template <typename _K2>
1455    _LIBCPP_INLINE_VISIBILITY
1456    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
1457    find(const _K2& __k) const                     {return __tree_.find(__k);}
1458#endif
1459
1460    _LIBCPP_INLINE_VISIBILITY
1461    size_type      count(const key_type& __k) const
1462        {return __tree_.__count_unique(__k);}
1463#if _LIBCPP_STD_VER > 11
1464    template <typename _K2>
1465    _LIBCPP_INLINE_VISIBILITY
1466    typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
1467    count(const _K2& __k) const {return __tree_.__count_multi(__k);}
1468#endif
1469
1470#if _LIBCPP_STD_VER > 17
1471    _LIBCPP_INLINE_VISIBILITY
1472    bool contains(const key_type& __k) const {return find(__k) != end();}
1473    template <typename _K2>
1474    _LIBCPP_INLINE_VISIBILITY
1475    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
1476    contains(const _K2& __k) const { return find(__k) != end(); }
1477#endif // _LIBCPP_STD_VER > 17
1478
1479    _LIBCPP_INLINE_VISIBILITY
1480    iterator lower_bound(const key_type& __k)
1481        {return __tree_.lower_bound(__k);}
1482    _LIBCPP_INLINE_VISIBILITY
1483    const_iterator lower_bound(const key_type& __k) const
1484        {return __tree_.lower_bound(__k);}
1485#if _LIBCPP_STD_VER > 11
1486    template <typename _K2>
1487    _LIBCPP_INLINE_VISIBILITY
1488    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
1489    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}
1490
1491    template <typename _K2>
1492    _LIBCPP_INLINE_VISIBILITY
1493    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
1494    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
1495#endif
1496
1497    _LIBCPP_INLINE_VISIBILITY
1498    iterator upper_bound(const key_type& __k)
1499        {return __tree_.upper_bound(__k);}
1500    _LIBCPP_INLINE_VISIBILITY
1501    const_iterator upper_bound(const key_type& __k) const
1502        {return __tree_.upper_bound(__k);}
1503#if _LIBCPP_STD_VER > 11
1504    template <typename _K2>
1505    _LIBCPP_INLINE_VISIBILITY
1506    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
1507    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
1508    template <typename _K2>
1509    _LIBCPP_INLINE_VISIBILITY
1510    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
1511    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
1512#endif
1513
1514    _LIBCPP_INLINE_VISIBILITY
1515    pair<iterator,iterator> equal_range(const key_type& __k)
1516        {return __tree_.__equal_range_unique(__k);}
1517    _LIBCPP_INLINE_VISIBILITY
1518    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
1519        {return __tree_.__equal_range_unique(__k);}
1520#if _LIBCPP_STD_VER > 11
1521    template <typename _K2>
1522    _LIBCPP_INLINE_VISIBILITY
1523    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
1524    equal_range(const _K2& __k)       {return __tree_.__equal_range_multi(__k);}
1525    template <typename _K2>
1526    _LIBCPP_INLINE_VISIBILITY
1527    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
1528    equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
1529#endif
1530
1531private:
1532    typedef typename __base::__node                    __node;
1533    typedef typename __base::__node_allocator          __node_allocator;
1534    typedef typename __base::__node_pointer            __node_pointer;
1535    typedef typename __base::__node_base_pointer       __node_base_pointer;
1536    typedef typename __base::__parent_pointer          __parent_pointer;
1537
1538    typedef __map_node_destructor<__node_allocator> _Dp;
1539    typedef unique_ptr<__node, _Dp> __node_holder;
1540
1541#ifdef _LIBCPP_CXX03_LANG
1542    __node_holder __construct_node_with_key(const key_type& __k);
1543#endif
1544};
1545
1546#if _LIBCPP_STD_VER >= 17
1547template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>,
1548         class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
1549         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
1550         class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1551         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1552map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
1553  -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
1554
1555template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>,
1556         class _Allocator = allocator<pair<const _Key, _Tp>>,
1557         class = enable_if_t<!__is_allocator<_Compare>::value, void>,
1558         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1559map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator())
1560  -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
1561
1562template<class _InputIterator, class _Allocator,
1563         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
1564         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1565map(_InputIterator, _InputIterator, _Allocator)
1566  -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
1567         less<__iter_key_type<_InputIterator>>, _Allocator>;
1568
1569template<class _Key, class _Tp, class _Allocator,
1570         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1571map(initializer_list<pair<_Key, _Tp>>, _Allocator)
1572  -> map<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
1573#endif
1574
1575#ifndef _LIBCPP_CXX03_LANG
1576template <class _Key, class _Tp, class _Compare, class _Allocator>
1577map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
1578    : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a))
1579{
1580    if (__a != __m.get_allocator())
1581    {
1582        const_iterator __e = cend();
1583        while (!__m.empty())
1584            __tree_.__insert_unique(__e.__i_,
1585                    __m.__tree_.remove(__m.begin().__i_)->__value_.__move());
1586    }
1587}
1588
1589template <class _Key, class _Tp, class _Compare, class _Allocator>
1590_Tp&
1591map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
1592{
1593    return __tree_.__emplace_unique_key_args(__k,
1594        _VSTD::piecewise_construct,
1595        _VSTD::forward_as_tuple(__k),
1596        _VSTD::forward_as_tuple()).first->__get_value().second;
1597}
1598
1599template <class _Key, class _Tp, class _Compare, class _Allocator>
1600_Tp&
1601map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k)
1602{
1603    return __tree_.__emplace_unique_key_args(__k,
1604        _VSTD::piecewise_construct,
1605        _VSTD::forward_as_tuple(_VSTD::move(__k)),
1606        _VSTD::forward_as_tuple()).first->__get_value().second;
1607}
1608
1609#else // _LIBCPP_CXX03_LANG
1610
1611template <class _Key, class _Tp, class _Compare, class _Allocator>
1612typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1613map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k)
1614{
1615    __node_allocator& __na = __tree_.__node_alloc();
1616    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1617    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().first), __k);
1618    __h.get_deleter().__first_constructed = true;
1619    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().second));
1620    __h.get_deleter().__second_constructed = true;
1621    return __h;
1622}
1623
1624template <class _Key, class _Tp, class _Compare, class _Allocator>
1625_Tp&
1626map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
1627{
1628    __parent_pointer __parent;
1629    __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
1630    __node_pointer __r = static_cast<__node_pointer>(__child);
1631    if (__child == nullptr)
1632    {
1633        __node_holder __h = __construct_node_with_key(__k);
1634        __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1635        __r = __h.release();
1636    }
1637    return __r->__value_.__get_value().second;
1638}
1639
1640#endif // _LIBCPP_CXX03_LANG
1641
1642template <class _Key, class _Tp, class _Compare, class _Allocator>
1643_Tp&
1644map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k)
1645{
1646    __parent_pointer __parent;
1647    __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
1648    if (__child == nullptr)
1649        __throw_out_of_range("map::at:  key not found");
1650    return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
1651}
1652
1653template <class _Key, class _Tp, class _Compare, class _Allocator>
1654const _Tp&
1655map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const
1656{
1657    __parent_pointer __parent;
1658    __node_base_pointer __child = __tree_.__find_equal(__parent, __k);
1659    if (__child == nullptr)
1660        __throw_out_of_range("map::at:  key not found");
1661    return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
1662}
1663
1664
1665template <class _Key, class _Tp, class _Compare, class _Allocator>
1666inline _LIBCPP_INLINE_VISIBILITY
1667bool
1668operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1669           const map<_Key, _Tp, _Compare, _Allocator>& __y)
1670{
1671    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
1672}
1673
1674template <class _Key, class _Tp, class _Compare, class _Allocator>
1675inline _LIBCPP_INLINE_VISIBILITY
1676bool
1677operator< (const map<_Key, _Tp, _Compare, _Allocator>& __x,
1678           const map<_Key, _Tp, _Compare, _Allocator>& __y)
1679{
1680    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1681}
1682
1683template <class _Key, class _Tp, class _Compare, class _Allocator>
1684inline _LIBCPP_INLINE_VISIBILITY
1685bool
1686operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1687           const map<_Key, _Tp, _Compare, _Allocator>& __y)
1688{
1689    return !(__x == __y);
1690}
1691
1692template <class _Key, class _Tp, class _Compare, class _Allocator>
1693inline _LIBCPP_INLINE_VISIBILITY
1694bool
1695operator> (const map<_Key, _Tp, _Compare, _Allocator>& __x,
1696           const map<_Key, _Tp, _Compare, _Allocator>& __y)
1697{
1698    return __y < __x;
1699}
1700
1701template <class _Key, class _Tp, class _Compare, class _Allocator>
1702inline _LIBCPP_INLINE_VISIBILITY
1703bool
1704operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1705           const map<_Key, _Tp, _Compare, _Allocator>& __y)
1706{
1707    return !(__x < __y);
1708}
1709
1710template <class _Key, class _Tp, class _Compare, class _Allocator>
1711inline _LIBCPP_INLINE_VISIBILITY
1712bool
1713operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1714           const map<_Key, _Tp, _Compare, _Allocator>& __y)
1715{
1716    return !(__y < __x);
1717}
1718
1719template <class _Key, class _Tp, class _Compare, class _Allocator>
1720inline _LIBCPP_INLINE_VISIBILITY
1721void
1722swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
1723     map<_Key, _Tp, _Compare, _Allocator>& __y)
1724    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1725{
1726    __x.swap(__y);
1727}
1728
1729#if _LIBCPP_STD_VER > 17
1730template <class _Key, class _Tp, class _Compare, class _Allocator,
1731          class _Predicate>
1732inline _LIBCPP_INLINE_VISIBILITY
1733    typename map<_Key, _Tp, _Compare, _Allocator>::size_type
1734    erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
1735  return _VSTD::__libcpp_erase_if_container(__c, __pred);
1736}
1737#endif
1738
1739
1740template <class _Key, class _Tp, class _Compare = less<_Key>,
1741          class _Allocator = allocator<pair<const _Key, _Tp> > >
1742class _LIBCPP_TEMPLATE_VIS multimap
1743{
1744public:
1745    // types:
1746    typedef _Key                                     key_type;
1747    typedef _Tp                                      mapped_type;
1748    typedef pair<const key_type, mapped_type>        value_type;
1749    typedef __type_identity_t<_Compare>              key_compare;
1750    typedef __type_identity_t<_Allocator>            allocator_type;
1751    typedef value_type&                              reference;
1752    typedef const value_type&                        const_reference;
1753
1754    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
1755                  "Allocator::value_type must be same type as value_type");
1756
1757_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1758    class _LIBCPP_TEMPLATE_VIS value_compare
1759#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1760        : public binary_function<value_type, value_type, bool>
1761#endif
1762    {
1763_LIBCPP_SUPPRESS_DEPRECATED_POP
1764        friend class multimap;
1765    protected:
1766        key_compare comp;
1767
1768        _LIBCPP_INLINE_VISIBILITY
1769        value_compare(key_compare c) : comp(c) {}
1770    public:
1771#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1772        _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
1773        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type first_argument_type;
1774        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type second_argument_type;
1775#endif
1776        _LIBCPP_INLINE_VISIBILITY
1777        bool operator()(const value_type& __x, const value_type& __y) const
1778            {return comp(__x.first, __y.first);}
1779    };
1780
1781private:
1782
1783    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
1784    typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
1785    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
1786                                                 __value_type>::type __allocator_type;
1787    typedef __tree<__value_type, __vc, __allocator_type>            __base;
1788    typedef typename __base::__node_traits                          __node_traits;
1789    typedef allocator_traits<allocator_type>                        __alloc_traits;
1790
1791    __base __tree_;
1792
1793public:
1794    typedef typename __alloc_traits::pointer               pointer;
1795    typedef typename __alloc_traits::const_pointer         const_pointer;
1796    typedef typename __alloc_traits::size_type             size_type;
1797    typedef typename __alloc_traits::difference_type       difference_type;
1798    typedef __map_iterator<typename __base::iterator>      iterator;
1799    typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
1800    typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
1801    typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;
1802
1803#if _LIBCPP_STD_VER > 14
1804    typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
1805#endif
1806
1807    template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
1808        friend class _LIBCPP_TEMPLATE_VIS map;
1809    template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
1810        friend class _LIBCPP_TEMPLATE_VIS multimap;
1811
1812    _LIBCPP_INLINE_VISIBILITY
1813    multimap()
1814        _NOEXCEPT_(
1815            is_nothrow_default_constructible<allocator_type>::value &&
1816            is_nothrow_default_constructible<key_compare>::value &&
1817            is_nothrow_copy_constructible<key_compare>::value)
1818        : __tree_(__vc(key_compare())) {}
1819
1820    _LIBCPP_INLINE_VISIBILITY
1821    explicit multimap(const key_compare& __comp)
1822        _NOEXCEPT_(
1823            is_nothrow_default_constructible<allocator_type>::value &&
1824            is_nothrow_copy_constructible<key_compare>::value)
1825        : __tree_(__vc(__comp)) {}
1826
1827    _LIBCPP_INLINE_VISIBILITY
1828    explicit multimap(const key_compare& __comp, const allocator_type& __a)
1829        : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}
1830
1831    template <class _InputIterator>
1832        _LIBCPP_INLINE_VISIBILITY
1833        multimap(_InputIterator __f, _InputIterator __l,
1834            const key_compare& __comp = key_compare())
1835        : __tree_(__vc(__comp))
1836        {
1837            insert(__f, __l);
1838        }
1839
1840    template <class _InputIterator>
1841        _LIBCPP_INLINE_VISIBILITY
1842        multimap(_InputIterator __f, _InputIterator __l,
1843            const key_compare& __comp, const allocator_type& __a)
1844        : __tree_(__vc(__comp), typename __base::allocator_type(__a))
1845        {
1846            insert(__f, __l);
1847        }
1848
1849#if _LIBCPP_STD_VER > 11
1850    template <class _InputIterator>
1851    _LIBCPP_INLINE_VISIBILITY
1852    multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
1853        : multimap(__f, __l, key_compare(), __a) {}
1854#endif
1855
1856    _LIBCPP_INLINE_VISIBILITY
1857    multimap(const multimap& __m)
1858        : __tree_(__m.__tree_.value_comp(),
1859          __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc()))
1860        {
1861            insert(__m.begin(), __m.end());
1862        }
1863
1864    _LIBCPP_INLINE_VISIBILITY
1865    multimap& operator=(const multimap& __m)
1866        {
1867#ifndef _LIBCPP_CXX03_LANG
1868            __tree_ = __m.__tree_;
1869#else
1870            if (this != _VSTD::addressof(__m)) {
1871                __tree_.clear();
1872                __tree_.value_comp() = __m.__tree_.value_comp();
1873                __tree_.__copy_assign_alloc(__m.__tree_);
1874                insert(__m.begin(), __m.end());
1875            }
1876#endif
1877            return *this;
1878        }
1879
1880#ifndef _LIBCPP_CXX03_LANG
1881
1882    _LIBCPP_INLINE_VISIBILITY
1883    multimap(multimap&& __m)
1884        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
1885        : __tree_(_VSTD::move(__m.__tree_))
1886        {
1887        }
1888
1889    multimap(multimap&& __m, const allocator_type& __a);
1890
1891    _LIBCPP_INLINE_VISIBILITY
1892    multimap& operator=(multimap&& __m)
1893        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
1894        {
1895            __tree_ = _VSTD::move(__m.__tree_);
1896            return *this;
1897        }
1898
1899    _LIBCPP_INLINE_VISIBILITY
1900    multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
1901        : __tree_(__vc(__comp))
1902        {
1903            insert(__il.begin(), __il.end());
1904        }
1905
1906    _LIBCPP_INLINE_VISIBILITY
1907    multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
1908        : __tree_(__vc(__comp), typename __base::allocator_type(__a))
1909        {
1910            insert(__il.begin(), __il.end());
1911        }
1912
1913#if _LIBCPP_STD_VER > 11
1914    _LIBCPP_INLINE_VISIBILITY
1915    multimap(initializer_list<value_type> __il, const allocator_type& __a)
1916        : multimap(__il, key_compare(), __a) {}
1917#endif
1918
1919    _LIBCPP_INLINE_VISIBILITY
1920    multimap& operator=(initializer_list<value_type> __il)
1921        {
1922            __tree_.__assign_multi(__il.begin(), __il.end());
1923            return *this;
1924        }
1925
1926#endif // _LIBCPP_CXX03_LANG
1927
1928    _LIBCPP_INLINE_VISIBILITY
1929    explicit multimap(const allocator_type& __a)
1930        : __tree_(typename __base::allocator_type(__a))
1931        {
1932        }
1933
1934    _LIBCPP_INLINE_VISIBILITY
1935    multimap(const multimap& __m, const allocator_type& __a)
1936        : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a))
1937        {
1938            insert(__m.begin(), __m.end());
1939        }
1940
1941    _LIBCPP_INLINE_VISIBILITY
1942    ~multimap() {
1943        static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
1944    }
1945
1946    _LIBCPP_INLINE_VISIBILITY
1947          iterator begin() _NOEXCEPT {return __tree_.begin();}
1948    _LIBCPP_INLINE_VISIBILITY
1949    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
1950    _LIBCPP_INLINE_VISIBILITY
1951          iterator end() _NOEXCEPT {return __tree_.end();}
1952    _LIBCPP_INLINE_VISIBILITY
1953    const_iterator end() const _NOEXCEPT {return __tree_.end();}
1954
1955    _LIBCPP_INLINE_VISIBILITY
1956          reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
1957    _LIBCPP_INLINE_VISIBILITY
1958    const_reverse_iterator rbegin() const _NOEXCEPT
1959        {return const_reverse_iterator(end());}
1960    _LIBCPP_INLINE_VISIBILITY
1961          reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
1962    _LIBCPP_INLINE_VISIBILITY
1963    const_reverse_iterator rend() const _NOEXCEPT
1964        {return const_reverse_iterator(begin());}
1965
1966    _LIBCPP_INLINE_VISIBILITY
1967    const_iterator cbegin()  const _NOEXCEPT {return begin();}
1968    _LIBCPP_INLINE_VISIBILITY
1969    const_iterator cend() const _NOEXCEPT {return end();}
1970    _LIBCPP_INLINE_VISIBILITY
1971    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
1972    _LIBCPP_INLINE_VISIBILITY
1973    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
1974
1975    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1976    bool empty() const _NOEXCEPT {return __tree_.size() == 0;}
1977    _LIBCPP_INLINE_VISIBILITY
1978    size_type size() const _NOEXCEPT {return __tree_.size();}
1979    _LIBCPP_INLINE_VISIBILITY
1980    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
1981
1982    _LIBCPP_INLINE_VISIBILITY
1983    allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());}
1984    _LIBCPP_INLINE_VISIBILITY
1985    key_compare    key_comp() const {return __tree_.value_comp().key_comp();}
1986    _LIBCPP_INLINE_VISIBILITY
1987    value_compare  value_comp() const
1988        {return value_compare(__tree_.value_comp().key_comp());}
1989
1990#ifndef _LIBCPP_CXX03_LANG
1991
1992    template <class ..._Args>
1993    _LIBCPP_INLINE_VISIBILITY
1994    iterator emplace(_Args&& ...__args) {
1995        return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...);
1996    }
1997
1998    template <class ..._Args>
1999    _LIBCPP_INLINE_VISIBILITY
2000    iterator emplace_hint(const_iterator __p, _Args&& ...__args) {
2001        return __tree_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...);
2002    }
2003
2004    template <class _Pp,
2005              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
2006        _LIBCPP_INLINE_VISIBILITY
2007        iterator insert(_Pp&& __p)
2008            {return __tree_.__insert_multi(_VSTD::forward<_Pp>(__p));}
2009
2010    template <class _Pp,
2011              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
2012        _LIBCPP_INLINE_VISIBILITY
2013        iterator insert(const_iterator __pos, _Pp&& __p)
2014            {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));}
2015
2016    _LIBCPP_INLINE_VISIBILITY
2017    iterator insert(value_type&& __v)
2018        {return __tree_.__insert_multi(_VSTD::move(__v));}
2019
2020    _LIBCPP_INLINE_VISIBILITY
2021    iterator insert(const_iterator __p, value_type&& __v)
2022        {return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));}
2023
2024
2025    _LIBCPP_INLINE_VISIBILITY
2026    void insert(initializer_list<value_type> __il)
2027        {insert(__il.begin(), __il.end());}
2028
2029#endif // _LIBCPP_CXX03_LANG
2030
2031    _LIBCPP_INLINE_VISIBILITY
2032    iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);}
2033
2034    _LIBCPP_INLINE_VISIBILITY
2035    iterator insert(const_iterator __p, const value_type& __v)
2036            {return __tree_.__insert_multi(__p.__i_, __v);}
2037
2038    template <class _InputIterator>
2039        _LIBCPP_INLINE_VISIBILITY
2040        void insert(_InputIterator __f, _InputIterator __l)
2041        {
2042            for (const_iterator __e = cend(); __f != __l; ++__f)
2043                __tree_.__insert_multi(__e.__i_, *__f);
2044        }
2045
2046    _LIBCPP_INLINE_VISIBILITY
2047    iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
2048    _LIBCPP_INLINE_VISIBILITY
2049    iterator erase(iterator __p)       {return __tree_.erase(__p.__i_);}
2050    _LIBCPP_INLINE_VISIBILITY
2051    size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}
2052    _LIBCPP_INLINE_VISIBILITY
2053    iterator  erase(const_iterator __f, const_iterator __l)
2054        {return __tree_.erase(__f.__i_, __l.__i_);}
2055
2056#if _LIBCPP_STD_VER > 14
2057    _LIBCPP_INLINE_VISIBILITY
2058    iterator insert(node_type&& __nh)
2059    {
2060        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
2061            "node_type with incompatible allocator passed to multimap::insert()");
2062        return __tree_.template __node_handle_insert_multi<node_type>(
2063            _VSTD::move(__nh));
2064    }
2065    _LIBCPP_INLINE_VISIBILITY
2066    iterator insert(const_iterator __hint, node_type&& __nh)
2067    {
2068        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
2069            "node_type with incompatible allocator passed to multimap::insert()");
2070        return __tree_.template __node_handle_insert_multi<node_type>(
2071            __hint.__i_, _VSTD::move(__nh));
2072    }
2073    _LIBCPP_INLINE_VISIBILITY
2074    node_type extract(key_type const& __key)
2075    {
2076        return __tree_.template __node_handle_extract<node_type>(__key);
2077    }
2078    _LIBCPP_INLINE_VISIBILITY
2079    node_type extract(const_iterator __it)
2080    {
2081        return __tree_.template __node_handle_extract<node_type>(
2082            __it.__i_);
2083    }
2084    template <class _Compare2>
2085    _LIBCPP_INLINE_VISIBILITY
2086    void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
2087    {
2088        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2089                       "merging container with incompatible allocator");
2090        return __tree_.__node_handle_merge_multi(__source.__tree_);
2091    }
2092    template <class _Compare2>
2093    _LIBCPP_INLINE_VISIBILITY
2094    void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
2095    {
2096        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2097                       "merging container with incompatible allocator");
2098        return __tree_.__node_handle_merge_multi(__source.__tree_);
2099    }
2100    template <class _Compare2>
2101    _LIBCPP_INLINE_VISIBILITY
2102    void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
2103    {
2104        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2105                       "merging container with incompatible allocator");
2106        return __tree_.__node_handle_merge_multi(__source.__tree_);
2107    }
2108    template <class _Compare2>
2109    _LIBCPP_INLINE_VISIBILITY
2110    void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
2111    {
2112        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
2113                       "merging container with incompatible allocator");
2114        return __tree_.__node_handle_merge_multi(__source.__tree_);
2115    }
2116#endif
2117
2118    _LIBCPP_INLINE_VISIBILITY
2119    void clear() _NOEXCEPT {__tree_.clear();}
2120
2121    _LIBCPP_INLINE_VISIBILITY
2122    void swap(multimap& __m)
2123        _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
2124        {__tree_.swap(__m.__tree_);}
2125
2126    _LIBCPP_INLINE_VISIBILITY
2127    iterator find(const key_type& __k)             {return __tree_.find(__k);}
2128    _LIBCPP_INLINE_VISIBILITY
2129    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
2130#if _LIBCPP_STD_VER > 11
2131    template <typename _K2>
2132    _LIBCPP_INLINE_VISIBILITY
2133    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
2134    find(const _K2& __k)                           {return __tree_.find(__k);}
2135    template <typename _K2>
2136    _LIBCPP_INLINE_VISIBILITY
2137    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
2138    find(const _K2& __k) const                     {return __tree_.find(__k);}
2139#endif
2140
2141    _LIBCPP_INLINE_VISIBILITY
2142    size_type      count(const key_type& __k) const
2143        {return __tree_.__count_multi(__k);}
2144#if _LIBCPP_STD_VER > 11
2145    template <typename _K2>
2146    _LIBCPP_INLINE_VISIBILITY
2147    typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
2148    count(const _K2& __k) const {return __tree_.__count_multi(__k);}
2149#endif
2150
2151#if _LIBCPP_STD_VER > 17
2152    _LIBCPP_INLINE_VISIBILITY
2153    bool contains(const key_type& __k) const {return find(__k) != end();}
2154    template <typename _K2>
2155    _LIBCPP_INLINE_VISIBILITY
2156    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
2157    contains(const _K2& __k) const { return find(__k) != end(); }
2158#endif // _LIBCPP_STD_VER > 17
2159
2160    _LIBCPP_INLINE_VISIBILITY
2161    iterator lower_bound(const key_type& __k)
2162        {return __tree_.lower_bound(__k);}
2163    _LIBCPP_INLINE_VISIBILITY
2164    const_iterator lower_bound(const key_type& __k) const
2165            {return __tree_.lower_bound(__k);}
2166#if _LIBCPP_STD_VER > 11
2167    template <typename _K2>
2168    _LIBCPP_INLINE_VISIBILITY
2169    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
2170    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}
2171
2172    template <typename _K2>
2173    _LIBCPP_INLINE_VISIBILITY
2174    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
2175    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
2176#endif
2177
2178    _LIBCPP_INLINE_VISIBILITY
2179    iterator upper_bound(const key_type& __k)
2180            {return __tree_.upper_bound(__k);}
2181    _LIBCPP_INLINE_VISIBILITY
2182    const_iterator upper_bound(const key_type& __k) const
2183            {return __tree_.upper_bound(__k);}
2184#if _LIBCPP_STD_VER > 11
2185    template <typename _K2>
2186    _LIBCPP_INLINE_VISIBILITY
2187    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
2188    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
2189    template <typename _K2>
2190    _LIBCPP_INLINE_VISIBILITY
2191    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
2192    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
2193#endif
2194
2195    _LIBCPP_INLINE_VISIBILITY
2196    pair<iterator,iterator>             equal_range(const key_type& __k)
2197            {return __tree_.__equal_range_multi(__k);}
2198    _LIBCPP_INLINE_VISIBILITY
2199    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
2200            {return __tree_.__equal_range_multi(__k);}
2201#if _LIBCPP_STD_VER > 11
2202    template <typename _K2>
2203    _LIBCPP_INLINE_VISIBILITY
2204    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
2205    equal_range(const _K2& __k)       {return __tree_.__equal_range_multi(__k);}
2206    template <typename _K2>
2207    _LIBCPP_INLINE_VISIBILITY
2208    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
2209    equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
2210#endif
2211
2212private:
2213    typedef typename __base::__node                    __node;
2214    typedef typename __base::__node_allocator          __node_allocator;
2215    typedef typename __base::__node_pointer            __node_pointer;
2216
2217    typedef __map_node_destructor<__node_allocator> _Dp;
2218    typedef unique_ptr<__node, _Dp> __node_holder;
2219};
2220
2221#if _LIBCPP_STD_VER >= 17
2222template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>,
2223         class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
2224         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
2225         class = enable_if_t<!__is_allocator<_Compare>::value, void>,
2226         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2227multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
2228  -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
2229
2230template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>,
2231         class _Allocator = allocator<pair<const _Key, _Tp>>,
2232         class = enable_if_t<!__is_allocator<_Compare>::value, void>,
2233         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2234multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator())
2235  -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
2236
2237template<class _InputIterator, class _Allocator,
2238         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
2239         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2240multimap(_InputIterator, _InputIterator, _Allocator)
2241  -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
2242         less<__iter_key_type<_InputIterator>>, _Allocator>;
2243
2244template<class _Key, class _Tp, class _Allocator,
2245         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2246multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
2247  -> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
2248#endif
2249
2250#ifndef _LIBCPP_CXX03_LANG
2251template <class _Key, class _Tp, class _Compare, class _Allocator>
2252multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a)
2253    : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a))
2254{
2255    if (__a != __m.get_allocator())
2256    {
2257        const_iterator __e = cend();
2258        while (!__m.empty())
2259            __tree_.__insert_multi(__e.__i_,
2260                    _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__move()));
2261    }
2262}
2263#endif
2264
2265template <class _Key, class _Tp, class _Compare, class _Allocator>
2266inline _LIBCPP_INLINE_VISIBILITY
2267bool
2268operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2269           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2270{
2271    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
2272}
2273
2274template <class _Key, class _Tp, class _Compare, class _Allocator>
2275inline _LIBCPP_INLINE_VISIBILITY
2276bool
2277operator< (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2278           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2279{
2280    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
2281}
2282
2283template <class _Key, class _Tp, class _Compare, class _Allocator>
2284inline _LIBCPP_INLINE_VISIBILITY
2285bool
2286operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2287           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2288{
2289    return !(__x == __y);
2290}
2291
2292template <class _Key, class _Tp, class _Compare, class _Allocator>
2293inline _LIBCPP_INLINE_VISIBILITY
2294bool
2295operator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2296           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2297{
2298    return __y < __x;
2299}
2300
2301template <class _Key, class _Tp, class _Compare, class _Allocator>
2302inline _LIBCPP_INLINE_VISIBILITY
2303bool
2304operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2305           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2306{
2307    return !(__x < __y);
2308}
2309
2310template <class _Key, class _Tp, class _Compare, class _Allocator>
2311inline _LIBCPP_INLINE_VISIBILITY
2312bool
2313operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2314           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2315{
2316    return !(__y < __x);
2317}
2318
2319template <class _Key, class _Tp, class _Compare, class _Allocator>
2320inline _LIBCPP_INLINE_VISIBILITY
2321void
2322swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
2323     multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2324    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2325{
2326    __x.swap(__y);
2327}
2328
2329#if _LIBCPP_STD_VER > 17
2330template <class _Key, class _Tp, class _Compare, class _Allocator,
2331          class _Predicate>
2332inline _LIBCPP_INLINE_VISIBILITY
2333    typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type
2334    erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c,
2335             _Predicate __pred) {
2336  return _VSTD::__libcpp_erase_if_container(__c, __pred);
2337}
2338#endif
2339
2340_LIBCPP_END_NAMESPACE_STD
2341
2342#endif // _LIBCPP_MAP
2343