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