// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_MAP
#define _LIBCPP_MAP

/*

    map synopsis

namespace std
{

template <class Key, class T, class Compare = less<Key>,
          class Allocator = allocator<pair<const Key, T>>>
class map
{
public:
    // types:
    typedef Key                                      key_type;
    typedef T                                        mapped_type;
    typedef pair<const key_type, mapped_type>        value_type;
    typedef Compare                                  key_compare;
    typedef Allocator                                allocator_type;
    typedef typename allocator_type::reference       reference;
    typedef typename allocator_type::const_reference const_reference;
    typedef typename allocator_type::pointer         pointer;
    typedef typename allocator_type::const_pointer   const_pointer;
    typedef typename allocator_type::size_type       size_type;
    typedef typename allocator_type::difference_type difference_type;

    typedef implementation-defined                   iterator;
    typedef implementation-defined                   const_iterator;
    typedef std::reverse_iterator<iterator>          reverse_iterator;
    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
    typedef unspecified                              node_type;              // C++17
    typedef INSERT_RETURN_TYPE<iterator, node_type>  insert_return_type;     // C++17

    class value_compare
    {
        friend class map;
    protected:
        key_compare comp;

        value_compare(key_compare c);
    public:
        typedef bool result_type;  // deprecated in C++17, removed in C++20
        typedef value_type first_argument_type;  // deprecated in C++17, removed in C++20
        typedef value_type second_argument_type;  // deprecated in C++17, removed in C++20
        bool operator()(const value_type& x, const value_type& y) const;
    };

    // construct/copy/destroy:
    map()
        noexcept(
            is_nothrow_default_constructible<allocator_type>::value &&
            is_nothrow_default_constructible<key_compare>::value &&
            is_nothrow_copy_constructible<key_compare>::value);
    explicit map(const key_compare& comp);
    map(const key_compare& comp, const allocator_type& a);
    template <class InputIterator>
        map(InputIterator first, InputIterator last,
            const key_compare& comp = key_compare());
    template <class InputIterator>
        map(InputIterator first, InputIterator last,
            const key_compare& comp, const allocator_type& a);
    map(const map& m);
    map(map&& m)
        noexcept(
            is_nothrow_move_constructible<allocator_type>::value &&
            is_nothrow_move_constructible<key_compare>::value);
    explicit map(const allocator_type& a);
    map(const map& m, const allocator_type& a);
    map(map&& m, const allocator_type& a);
    map(initializer_list<value_type> il, const key_compare& comp = key_compare());
    map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
    template <class InputIterator>
        map(InputIterator first, InputIterator last, const allocator_type& a)
            : map(first, last, Compare(), a) {}  // C++14
    map(initializer_list<value_type> il, const allocator_type& a)
        : map(il, Compare(), a) {}  // C++14
   ~map();

    map& operator=(const map& m);
    map& operator=(map&& m)
        noexcept(
            allocator_type::propagate_on_container_move_assignment::value &&
            is_nothrow_move_assignable<allocator_type>::value &&
            is_nothrow_move_assignable<key_compare>::value);
    map& operator=(initializer_list<value_type> il);

    // iterators:
          iterator begin() noexcept;
    const_iterator begin() const noexcept;
          iterator end() noexcept;
    const_iterator end()   const noexcept;

          reverse_iterator rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
          reverse_iterator rend() noexcept;
    const_reverse_iterator rend()   const noexcept;

    const_iterator         cbegin()  const noexcept;
    const_iterator         cend()    const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend()   const noexcept;

    // capacity:
    bool      empty()    const noexcept;
    size_type size()     const noexcept;
    size_type max_size() const noexcept;

    // element access:
    mapped_type& operator[](const key_type& k);
    mapped_type& operator[](key_type&& k);

          mapped_type& at(const key_type& k);
    const mapped_type& at(const key_type& k) const;

    // modifiers:
    template <class... Args>
        pair<iterator, bool> emplace(Args&&... args);
    template <class... Args>
        iterator emplace_hint(const_iterator position, Args&&... args);
    pair<iterator, bool> insert(const value_type& v);
    pair<iterator, bool> insert(      value_type&& v);                                // C++17
    template <class P>
        pair<iterator, bool> insert(P&& p);
    iterator insert(const_iterator position, const value_type& v);
    iterator insert(const_iterator position,       value_type&& v);                   // C++17
    template <class P>
        iterator insert(const_iterator position, P&& p);
    template <class InputIterator>
        void insert(InputIterator first, InputIterator last);
    void insert(initializer_list<value_type> il);

    node_type extract(const_iterator position);                                       // C++17
    node_type extract(const key_type& x);                                             // C++17
    insert_return_type insert(node_type&& nh);                                        // C++17
    iterator insert(const_iterator hint, node_type&& nh);                             // C++17

    template <class... Args>
        pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);          // C++17
    template <class... Args>
        pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);               // C++17
    template <class... Args>
        iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
    template <class... Args>
        iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);      // C++17
    template <class M>
        pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);            // C++17
    template <class M>
        pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);                 // C++17
    template <class M>
        iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);   // C++17
    template <class M>
        iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);        // C++17

    iterator  erase(const_iterator position);
    iterator  erase(iterator position); // C++14
    size_type erase(const key_type& k);
    iterator  erase(const_iterator first, const_iterator last);
    void clear() noexcept;

    template<class C2>
      void merge(map<Key, T, C2, Allocator>& source);         // C++17
    template<class C2>
      void merge(map<Key, T, C2, Allocator>&& source);        // C++17
    template<class C2>
      void merge(multimap<Key, T, C2, Allocator>& source);    // C++17
    template<class C2>
      void merge(multimap<Key, T, C2, Allocator>&& source);   // C++17

    void swap(map& m)
        noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
            is_nothrow_swappable<key_compare>::value); // C++17

    // observers:
    allocator_type get_allocator() const noexcept;
    key_compare    key_comp()      const;
    value_compare  value_comp()    const;

    // map operations:
          iterator find(const key_type& k);
    const_iterator find(const key_type& k) const;
    template<typename K>
        iterator find(const K& x);              // C++14
    template<typename K>
        const_iterator find(const K& x) const;  // C++14

    template<typename K>
      size_type count(const K& x) const;        // C++14
    size_type      count(const key_type& k) const;

    bool           contains(const key_type& x) const;  // C++20
    template<class K> bool contains(const K& x) const; // C++20

          iterator lower_bound(const key_type& k);
    const_iterator lower_bound(const key_type& k) const;
    template<typename K>
        iterator lower_bound(const K& x);              // C++14
    template<typename K>
        const_iterator lower_bound(const K& x) const;  // C++14

          iterator upper_bound(const key_type& k);
    const_iterator upper_bound(const key_type& k) const;
    template<typename K>
        iterator upper_bound(const K& x);              // C++14
    template<typename K>
        const_iterator upper_bound(const K& x) const;  // C++14

    pair<iterator,iterator>             equal_range(const key_type& k);
    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
    template<typename K>
        pair<iterator,iterator>             equal_range(const K& x);        // C++14
    template<typename K>
        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
};

template <class InputIterator,
      class Compare = less<iter_key_t<InputIterator>>,
      class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
  -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17

template<class Key, class T, class Compare = less<Key>,
    class Allocator = allocator<pair<const Key, T>>>
map(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
  -> map<Key, T, Compare, Allocator>; // C++17

template <class InputIterator, class Allocator>
map(InputIterator, InputIterator, Allocator)
  -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, less<iter_key_t<InputIterator>>,
    Allocator>; // C++17

template<class Key, class T, class Allocator>
map(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>; // C++17

template <class Key, class T, class Compare, class Allocator>
bool
operator==(const map<Key, T, Compare, Allocator>& x,
           const map<Key, T, Compare, Allocator>& y);

template <class Key, class T, class Compare, class Allocator>
bool
operator< (const map<Key, T, Compare, Allocator>& x,
           const map<Key, T, Compare, Allocator>& y);

template <class Key, class T, class Compare, class Allocator>
bool
operator!=(const map<Key, T, Compare, Allocator>& x,
           const map<Key, T, Compare, Allocator>& y);

template <class Key, class T, class Compare, class Allocator>
bool
operator> (const map<Key, T, Compare, Allocator>& x,
           const map<Key, T, Compare, Allocator>& y);

template <class Key, class T, class Compare, class Allocator>
bool
operator>=(const map<Key, T, Compare, Allocator>& x,
           const map<Key, T, Compare, Allocator>& y);

template <class Key, class T, class Compare, class Allocator>
bool
operator<=(const map<Key, T, Compare, Allocator>& x,
           const map<Key, T, Compare, Allocator>& y);

// specialized algorithms:
template <class Key, class T, class Compare, class Allocator>
void
swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
    noexcept(noexcept(x.swap(y)));

template <class Key, class T, class Compare, class Allocator, class Predicate>
typename map<Key, T, Compare, Allocator>::size_type
erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20


template <class Key, class T, class Compare = less<Key>,
          class Allocator = allocator<pair<const Key, T>>>
class multimap
{
public:
    // types:
    typedef Key                                      key_type;
    typedef T                                        mapped_type;
    typedef pair<const key_type,mapped_type>         value_type;
    typedef Compare                                  key_compare;
    typedef Allocator                                allocator_type;
    typedef typename allocator_type::reference       reference;
    typedef typename allocator_type::const_reference const_reference;
    typedef typename allocator_type::size_type       size_type;
    typedef typename allocator_type::difference_type difference_type;
    typedef typename allocator_type::pointer         pointer;
    typedef typename allocator_type::const_pointer   const_pointer;

    typedef implementation-defined                   iterator;
    typedef implementation-defined                   const_iterator;
    typedef std::reverse_iterator<iterator>          reverse_iterator;
    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
    typedef unspecified                              node_type;              // C++17

    class value_compare
    {
        friend class multimap;
    protected:
        key_compare comp;
        value_compare(key_compare c);
    public:
        typedef bool result_type;  // deprecated in C++17, removed in C++20
        typedef value_type first_argument_type;  // deprecated in C++17, removed in C++20
        typedef value_type second_argument_type;  // deprecated in C++17, removed in C++20
        bool operator()(const value_type& x, const value_type& y) const;
    };

    // construct/copy/destroy:
    multimap()
        noexcept(
            is_nothrow_default_constructible<allocator_type>::value &&
            is_nothrow_default_constructible<key_compare>::value &&
            is_nothrow_copy_constructible<key_compare>::value);
    explicit multimap(const key_compare& comp);
    multimap(const key_compare& comp, const allocator_type& a);
    template <class InputIterator>
        multimap(InputIterator first, InputIterator last, const key_compare& comp);
    template <class InputIterator>
        multimap(InputIterator first, InputIterator last, const key_compare& comp,
                 const allocator_type& a);
    multimap(const multimap& m);
    multimap(multimap&& m)
        noexcept(
            is_nothrow_move_constructible<allocator_type>::value &&
            is_nothrow_move_constructible<key_compare>::value);
    explicit multimap(const allocator_type& a);
    multimap(const multimap& m, const allocator_type& a);
    multimap(multimap&& m, const allocator_type& a);
    multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());
    multimap(initializer_list<value_type> il, const key_compare& comp,
             const allocator_type& a);
    template <class InputIterator>
        multimap(InputIterator first, InputIterator last, const allocator_type& a)
            : multimap(first, last, Compare(), a) {} // C++14
    multimap(initializer_list<value_type> il, const allocator_type& a)
        : multimap(il, Compare(), a) {} // C++14
    ~multimap();

    multimap& operator=(const multimap& m);
    multimap& operator=(multimap&& m)
        noexcept(
            allocator_type::propagate_on_container_move_assignment::value &&
            is_nothrow_move_assignable<allocator_type>::value &&
            is_nothrow_move_assignable<key_compare>::value);
    multimap& operator=(initializer_list<value_type> il);

    // iterators:
          iterator begin() noexcept;
    const_iterator begin() const noexcept;
          iterator end() noexcept;
    const_iterator end()   const noexcept;

          reverse_iterator rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
          reverse_iterator rend() noexcept;
    const_reverse_iterator rend()   const noexcept;

    const_iterator         cbegin()  const noexcept;
    const_iterator         cend()    const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend()   const noexcept;

    // capacity:
    bool      empty()    const noexcept;
    size_type size()     const noexcept;
    size_type max_size() const noexcept;

    // modifiers:
    template <class... Args>
        iterator emplace(Args&&... args);
    template <class... Args>
        iterator emplace_hint(const_iterator position, Args&&... args);
    iterator insert(const value_type& v);
    iterator insert(      value_type&& v);                                            // C++17
    template <class P>
        iterator insert(P&& p);
    iterator insert(const_iterator position, const value_type& v);
    iterator insert(const_iterator position,       value_type&& v);                   // C++17
    template <class P>
        iterator insert(const_iterator position, P&& p);
    template <class InputIterator>
        void insert(InputIterator first, InputIterator last);
    void insert(initializer_list<value_type> il);

    node_type extract(const_iterator position);                                       // C++17
    node_type extract(const key_type& x);                                             // C++17
    iterator insert(node_type&& nh);                                                  // C++17
    iterator insert(const_iterator hint, node_type&& nh);                             // C++17

    iterator  erase(const_iterator position);
    iterator  erase(iterator position); // C++14
    size_type erase(const key_type& k);
    iterator  erase(const_iterator first, const_iterator last);
    void clear() noexcept;

    template<class C2>
      void merge(multimap<Key, T, C2, Allocator>& source);    // C++17
    template<class C2>
      void merge(multimap<Key, T, C2, Allocator>&& source);   // C++17
    template<class C2>
      void merge(map<Key, T, C2, Allocator>& source);         // C++17
    template<class C2>
      void merge(map<Key, T, C2, Allocator>&& source);        // C++17

    void swap(multimap& m)
        noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
            is_nothrow_swappable<key_compare>::value); // C++17

    // observers:
    allocator_type get_allocator() const noexcept;
    key_compare    key_comp()      const;
    value_compare  value_comp()    const;

    // map operations:
          iterator find(const key_type& k);
    const_iterator find(const key_type& k) const;
    template<typename K>
        iterator find(const K& x);              // C++14
    template<typename K>
        const_iterator find(const K& x) const;  // C++14

    template<typename K>
      size_type count(const K& x) const;        // C++14
    size_type      count(const key_type& k) const;

    bool           contains(const key_type& x) const;  // C++20
    template<class K> bool contains(const K& x) const; // C++20

          iterator lower_bound(const key_type& k);
    const_iterator lower_bound(const key_type& k) const;
    template<typename K>
        iterator lower_bound(const K& x);              // C++14
    template<typename K>
        const_iterator lower_bound(const K& x) const;  // C++14

          iterator upper_bound(const key_type& k);
    const_iterator upper_bound(const key_type& k) const;
    template<typename K>
        iterator upper_bound(const K& x);              // C++14
    template<typename K>
        const_iterator upper_bound(const K& x) const;  // C++14

    pair<iterator,iterator>             equal_range(const key_type& k);
    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
    template<typename K>
        pair<iterator,iterator>             equal_range(const K& x);        // C++14
    template<typename K>
        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
};

template <class InputIterator,
      class Compare = less<iter_key_t<InputIterator>>,
      class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
  -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17

template<class Key, class T, class Compare = less<Key>,
    class Allocator = allocator<pair<const Key, T>>>
multimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
  -> multimap<Key, T, Compare, Allocator>; // C++17

template <class InputIterator, class Allocator>
multimap(InputIterator, InputIterator, Allocator)
  -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
    less<iter_key_t<InputIterator>>, Allocator>; // C++17

template<class Key, class T, class Allocator>
multimap(initializer_list<pair<const Key, T>>, Allocator)
  -> multimap<Key, T, less<Key>, Allocator>; // C++17

template <class Key, class T, class Compare, class Allocator>
bool
operator==(const multimap<Key, T, Compare, Allocator>& x,
           const multimap<Key, T, Compare, Allocator>& y);

template <class Key, class T, class Compare, class Allocator>
bool
operator< (const multimap<Key, T, Compare, Allocator>& x,
           const multimap<Key, T, Compare, Allocator>& y);

template <class Key, class T, class Compare, class Allocator>
bool
operator!=(const multimap<Key, T, Compare, Allocator>& x,
           const multimap<Key, T, Compare, Allocator>& y);

template <class Key, class T, class Compare, class Allocator>
bool
operator> (const multimap<Key, T, Compare, Allocator>& x,
           const multimap<Key, T, Compare, Allocator>& y);

template <class Key, class T, class Compare, class Allocator>
bool
operator>=(const multimap<Key, T, Compare, Allocator>& x,
           const multimap<Key, T, Compare, Allocator>& y);

template <class Key, class T, class Compare, class Allocator>
bool
operator<=(const multimap<Key, T, Compare, Allocator>& x,
           const multimap<Key, T, Compare, Allocator>& y);

// specialized algorithms:
template <class Key, class T, class Compare, class Allocator>
void
swap(multimap<Key, T, Compare, Allocator>& x,
     multimap<Key, T, Compare, Allocator>& y)
    noexcept(noexcept(x.swap(y)));

template <class Key, class T, class Compare, class Allocator, class Predicate>
typename multimap<Key, T, Compare, Allocator>::size_type
erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20

}  // std

*/

#include <__config>
#include <__debug>
#include <__functional/is_transparent.h>
#include <__iterator/iterator_traits.h>
#include <__node_handle>
#include <__tree>
#include <__utility/forward.h>
#include <compare>
#include <functional>
#include <initializer_list>
#include <iterator> // __libcpp_erase_if_container
#include <memory>
#include <type_traits>
#include <utility>
#include <version>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Key, class _CP, class _Compare,
          bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
class __map_value_compare
    : private _Compare
{
public:
    _LIBCPP_INLINE_VISIBILITY
    __map_value_compare()
        _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
        : _Compare() {}
    _LIBCPP_INLINE_VISIBILITY
    __map_value_compare(_Compare c)
        _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
        : _Compare(c) {}
    _LIBCPP_INLINE_VISIBILITY
    const _Compare& key_comp() const _NOEXCEPT {return *this;}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _CP& __x, const _CP& __y) const
        {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y.__get_value().first);}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _CP& __x, const _Key& __y) const
        {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _Key& __x, const _CP& __y) const
        {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);}
    void swap(__map_value_compare& __y)
        _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
    {
      using _VSTD::swap;
      swap(static_cast<_Compare&>(*this), static_cast<_Compare&>(__y));
    }

#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _K2& __x, const _CP& __y) const
        {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);}

    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _CP& __x, const _K2& __y) const
        {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);}
#endif
};

template <class _Key, class _CP, class _Compare>
class __map_value_compare<_Key, _CP, _Compare, false>
{
    _Compare comp;

public:
    _LIBCPP_INLINE_VISIBILITY
    __map_value_compare()
        _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
        : comp() {}
    _LIBCPP_INLINE_VISIBILITY
    __map_value_compare(_Compare c)
        _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
        : comp(c) {}
    _LIBCPP_INLINE_VISIBILITY
    const _Compare& key_comp() const _NOEXCEPT {return comp;}

    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _CP& __x, const _CP& __y) const
        {return comp(__x.__get_value().first, __y.__get_value().first);}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _CP& __x, const _Key& __y) const
        {return comp(__x.__get_value().first, __y);}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _Key& __x, const _CP& __y) const
        {return comp(__x, __y.__get_value().first);}
    void swap(__map_value_compare& __y)
        _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
    {
        using _VSTD::swap;
        swap(comp, __y.comp);
    }

#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _K2& __x, const _CP& __y) const
        {return comp(__x, __y.__get_value().first);}

    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _CP& __x, const _K2& __y) const
        {return comp(__x.__get_value().first, __y);}
#endif
};

template <class _Key, class _CP, class _Compare, bool __b>
inline _LIBCPP_INLINE_VISIBILITY
void
swap(__map_value_compare<_Key, _CP, _Compare, __b>& __x,
     __map_value_compare<_Key, _CP, _Compare, __b>& __y)
    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
{
    __x.swap(__y);
}

template <class _Allocator>
class __map_node_destructor
{
    typedef _Allocator                          allocator_type;
    typedef allocator_traits<allocator_type>    __alloc_traits;

public:
    typedef typename __alloc_traits::pointer    pointer;

private:
    allocator_type& __na_;

    __map_node_destructor& operator=(const __map_node_destructor&);

public:
    bool __first_constructed;
    bool __second_constructed;

    _LIBCPP_INLINE_VISIBILITY
    explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT
        : __na_(__na),
          __first_constructed(false),
          __second_constructed(false)
        {}

#ifndef _LIBCPP_CXX03_LANG
    _LIBCPP_INLINE_VISIBILITY
    __map_node_destructor(__tree_node_destructor<allocator_type>&& __x) _NOEXCEPT
        : __na_(__x.__na_),
          __first_constructed(__x.__value_constructed),
          __second_constructed(__x.__value_constructed)
        {
            __x.__value_constructed = false;
        }
#endif // _LIBCPP_CXX03_LANG

    _LIBCPP_INLINE_VISIBILITY
    void operator()(pointer __p) _NOEXCEPT
    {
        if (__second_constructed)
            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().second));
        if (__first_constructed)
            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().first));
        if (__p)
            __alloc_traits::deallocate(__na_, __p, 1);
    }
};

template <class _Key, class _Tp, class _Compare, class _Allocator>
    class map;
template <class _Key, class _Tp, class _Compare, class _Allocator>
    class multimap;
template <class _TreeIterator> class __map_const_iterator;

#ifndef _LIBCPP_CXX03_LANG

template <class _Key, class _Tp>
struct _LIBCPP_STANDALONE_DEBUG __value_type
{
    typedef _Key                                     key_type;
    typedef _Tp                                      mapped_type;
    typedef pair<const key_type, mapped_type>        value_type;
    typedef pair<key_type&, mapped_type&>            __nc_ref_pair_type;
    typedef pair<key_type&&, mapped_type&&>          __nc_rref_pair_type;

private:
    value_type __cc;

public:
    _LIBCPP_INLINE_VISIBILITY
    value_type& __get_value()
    {
#if _LIBCPP_STD_VER > 14
        return *_VSTD::launder(_VSTD::addressof(__cc));
#else
        return __cc;
#endif
    }

    _LIBCPP_INLINE_VISIBILITY
    const value_type& __get_value() const
    {
#if _LIBCPP_STD_VER > 14
        return *_VSTD::launder(_VSTD::addressof(__cc));
#else
        return __cc;
#endif
    }

    _LIBCPP_INLINE_VISIBILITY
    __nc_ref_pair_type __ref()
    {
        value_type& __v = __get_value();
        return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second);
    }

    _LIBCPP_INLINE_VISIBILITY
    __nc_rref_pair_type __move()
    {
        value_type& __v = __get_value();
        return __nc_rref_pair_type(
            _VSTD::move(const_cast<key_type&>(__v.first)),
            _VSTD::move(__v.second));
    }

    _LIBCPP_INLINE_VISIBILITY
    __value_type& operator=(const __value_type& __v)
    {
        __ref() = __v.__get_value();
        return *this;
    }

    _LIBCPP_INLINE_VISIBILITY
    __value_type& operator=(__value_type&& __v)
    {
        __ref() = __v.__move();
        return *this;
    }

    template <class _ValueTp,
              class = typename enable_if<
                    __is_same_uncvref<_ValueTp, value_type>::value
                 >::type
             >
    _LIBCPP_INLINE_VISIBILITY
    __value_type& operator=(_ValueTp&& __v)
    {
        __ref() = _VSTD::forward<_ValueTp>(__v);
        return *this;
    }

private:
    __value_type() = delete;
    ~__value_type() = delete;
    __value_type(const __value_type&) = delete;
    __value_type(__value_type&&) = delete;
};

#else

template <class _Key, class _Tp>
struct __value_type
{
    typedef _Key                                     key_type;
    typedef _Tp                                      mapped_type;
    typedef pair<const key_type, mapped_type>        value_type;

private:
    value_type __cc;

public:
    _LIBCPP_INLINE_VISIBILITY
    value_type& __get_value() { return __cc; }
    _LIBCPP_INLINE_VISIBILITY
    const value_type& __get_value() const { return __cc; }

private:
   __value_type();
   __value_type(__value_type const&);
   __value_type& operator=(__value_type const&);
   ~__value_type();
};

#endif // _LIBCPP_CXX03_LANG

template <class _Tp>
struct __extract_key_value_types;

template <class _Key, class _Tp>
struct __extract_key_value_types<__value_type<_Key, _Tp> >
{
  typedef _Key const __key_type;
  typedef _Tp        __mapped_type;
};

template <class _TreeIterator>
class _LIBCPP_TEMPLATE_VIS __map_iterator
{
    typedef typename _TreeIterator::_NodeTypes                   _NodeTypes;
    typedef typename _TreeIterator::__pointer_traits             __pointer_traits;

    _TreeIterator __i_;

public:
    typedef bidirectional_iterator_tag                           iterator_category;
    typedef typename _NodeTypes::__map_value_type                value_type;
    typedef typename _TreeIterator::difference_type              difference_type;
    typedef value_type&                                          reference;
    typedef typename _NodeTypes::__map_value_type_pointer        pointer;

    _LIBCPP_INLINE_VISIBILITY
    __map_iterator() _NOEXCEPT {}

    _LIBCPP_INLINE_VISIBILITY
    __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}

    _LIBCPP_INLINE_VISIBILITY
    reference operator*() const {return __i_->__get_value();}
    _LIBCPP_INLINE_VISIBILITY
    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}

    _LIBCPP_INLINE_VISIBILITY
    __map_iterator& operator++() {++__i_; return *this;}
    _LIBCPP_INLINE_VISIBILITY
    __map_iterator operator++(int)
    {
        __map_iterator __t(*this);
        ++(*this);
        return __t;
    }

    _LIBCPP_INLINE_VISIBILITY
    __map_iterator& operator--() {--__i_; return *this;}
    _LIBCPP_INLINE_VISIBILITY
    __map_iterator operator--(int)
    {
        __map_iterator __t(*this);
        --(*this);
        return __t;
    }

    friend _LIBCPP_INLINE_VISIBILITY
    bool operator==(const __map_iterator& __x, const __map_iterator& __y)
        {return __x.__i_ == __y.__i_;}
    friend
    _LIBCPP_INLINE_VISIBILITY
    bool operator!=(const __map_iterator& __x, const __map_iterator& __y)
        {return __x.__i_ != __y.__i_;}

    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
    template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
};

template <class _TreeIterator>
class _LIBCPP_TEMPLATE_VIS __map_const_iterator
{
    typedef typename _TreeIterator::_NodeTypes                   _NodeTypes;
    typedef typename _TreeIterator::__pointer_traits             __pointer_traits;

    _TreeIterator __i_;

public:
    typedef bidirectional_iterator_tag                           iterator_category;
    typedef typename _NodeTypes::__map_value_type                value_type;
    typedef typename _TreeIterator::difference_type              difference_type;
    typedef const value_type&                                    reference;
    typedef typename _NodeTypes::__const_map_value_type_pointer  pointer;

    _LIBCPP_INLINE_VISIBILITY
    __map_const_iterator() _NOEXCEPT {}

    _LIBCPP_INLINE_VISIBILITY
    __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
    _LIBCPP_INLINE_VISIBILITY
    __map_const_iterator(__map_iterator<
        typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT
        : __i_(__i.__i_) {}

    _LIBCPP_INLINE_VISIBILITY
    reference operator*() const {return __i_->__get_value();}
    _LIBCPP_INLINE_VISIBILITY
    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}

    _LIBCPP_INLINE_VISIBILITY
    __map_const_iterator& operator++() {++__i_; return *this;}
    _LIBCPP_INLINE_VISIBILITY
    __map_const_iterator operator++(int)
    {
        __map_const_iterator __t(*this);
        ++(*this);
        return __t;
    }

    _LIBCPP_INLINE_VISIBILITY
    __map_const_iterator& operator--() {--__i_; return *this;}
    _LIBCPP_INLINE_VISIBILITY
    __map_const_iterator operator--(int)
    {
        __map_const_iterator __t(*this);
        --(*this);
        return __t;
    }

    friend _LIBCPP_INLINE_VISIBILITY
    bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y)
        {return __x.__i_ == __y.__i_;}
    friend _LIBCPP_INLINE_VISIBILITY
    bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y)
        {return __x.__i_ != __y.__i_;}

    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map;
    template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap;
    template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
};

template <class _Key, class _Tp, class _Compare = less<_Key>,
          class _Allocator = allocator<pair<const _Key, _Tp> > >
class _LIBCPP_TEMPLATE_VIS map
{
public:
    // types:
    typedef _Key                                     key_type;
    typedef _Tp                                      mapped_type;
    typedef pair<const key_type, mapped_type>        value_type;
    typedef __identity_t<_Compare>                   key_compare;
    typedef __identity_t<_Allocator>                 allocator_type;
    typedef value_type&                              reference;
    typedef const value_type&                        const_reference;

    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
                  "Allocator::value_type must be same type as value_type");

_LIBCPP_SUPPRESS_DEPRECATED_PUSH
    class _LIBCPP_TEMPLATE_VIS value_compare
#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
        : public binary_function<value_type, value_type, bool>
#endif
    {
_LIBCPP_SUPPRESS_DEPRECATED_POP
        friend class map;
    protected:
        key_compare comp;

        _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {}
    public:
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
        _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type first_argument_type;
        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type second_argument_type;
#endif
        _LIBCPP_INLINE_VISIBILITY
        bool operator()(const value_type& __x, const value_type& __y) const
            {return comp(__x.first, __y.first);}
    };

private:

    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
    typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
                                                 __value_type>::type __allocator_type;
    typedef __tree<__value_type, __vc, __allocator_type>   __base;
    typedef typename __base::__node_traits                 __node_traits;
    typedef allocator_traits<allocator_type>               __alloc_traits;

    __base __tree_;

public:
    typedef typename __alloc_traits::pointer               pointer;
    typedef typename __alloc_traits::const_pointer         const_pointer;
    typedef typename __alloc_traits::size_type             size_type;
    typedef typename __alloc_traits::difference_type       difference_type;
    typedef __map_iterator<typename __base::iterator>             iterator;
    typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
    typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
    typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;

#if _LIBCPP_STD_VER > 14
    typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
    typedef __insert_return_type<iterator, node_type> insert_return_type;
#endif

    template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
        friend class _LIBCPP_TEMPLATE_VIS map;
    template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
        friend class _LIBCPP_TEMPLATE_VIS multimap;

    _LIBCPP_INLINE_VISIBILITY
    map()
        _NOEXCEPT_(
            is_nothrow_default_constructible<allocator_type>::value &&
            is_nothrow_default_constructible<key_compare>::value &&
            is_nothrow_copy_constructible<key_compare>::value)
        : __tree_(__vc(key_compare())) {}

    _LIBCPP_INLINE_VISIBILITY
    explicit map(const key_compare& __comp)
        _NOEXCEPT_(
            is_nothrow_default_constructible<allocator_type>::value &&
            is_nothrow_copy_constructible<key_compare>::value)
        : __tree_(__vc(__comp)) {}

    _LIBCPP_INLINE_VISIBILITY
    explicit map(const key_compare& __comp, const allocator_type& __a)
        : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}

    template <class _InputIterator>
    _LIBCPP_INLINE_VISIBILITY
        map(_InputIterator __f, _InputIterator __l,
            const key_compare& __comp = key_compare())
        : __tree_(__vc(__comp))
        {
            insert(__f, __l);
        }

    template <class _InputIterator>
    _LIBCPP_INLINE_VISIBILITY
        map(_InputIterator __f, _InputIterator __l,
            const key_compare& __comp, const allocator_type& __a)
        : __tree_(__vc(__comp), typename __base::allocator_type(__a))
        {
            insert(__f, __l);
        }

#if _LIBCPP_STD_VER > 11
    template <class _InputIterator>
    _LIBCPP_INLINE_VISIBILITY
    map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
        : map(__f, __l, key_compare(), __a) {}
#endif

    _LIBCPP_INLINE_VISIBILITY
    map(const map& __m)
        : __tree_(__m.__tree_)
        {
            insert(__m.begin(), __m.end());
        }

    _LIBCPP_INLINE_VISIBILITY
    map& operator=(const map& __m)
        {
#ifndef _LIBCPP_CXX03_LANG
            __tree_ = __m.__tree_;
#else
            if (this != _VSTD::addressof(__m)) {
                __tree_.clear();
                __tree_.value_comp() = __m.__tree_.value_comp();
                __tree_.__copy_assign_alloc(__m.__tree_);
                insert(__m.begin(), __m.end());
            }
#endif
            return *this;
        }

#ifndef _LIBCPP_CXX03_LANG

    _LIBCPP_INLINE_VISIBILITY
    map(map&& __m)
        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
        : __tree_(_VSTD::move(__m.__tree_))
        {
        }

    map(map&& __m, const allocator_type& __a);

    _LIBCPP_INLINE_VISIBILITY
    map& operator=(map&& __m)
        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
        {
            __tree_ = _VSTD::move(__m.__tree_);
            return *this;
        }

    _LIBCPP_INLINE_VISIBILITY
    map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
        : __tree_(__vc(__comp))
        {
            insert(__il.begin(), __il.end());
        }

    _LIBCPP_INLINE_VISIBILITY
    map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
        : __tree_(__vc(__comp), typename __base::allocator_type(__a))
        {
            insert(__il.begin(), __il.end());
        }

#if _LIBCPP_STD_VER > 11
    _LIBCPP_INLINE_VISIBILITY
    map(initializer_list<value_type> __il, const allocator_type& __a)
        : map(__il, key_compare(), __a) {}
#endif

    _LIBCPP_INLINE_VISIBILITY
    map& operator=(initializer_list<value_type> __il)
        {
            __tree_.__assign_unique(__il.begin(), __il.end());
            return *this;
        }

#endif // _LIBCPP_CXX03_LANG

    _LIBCPP_INLINE_VISIBILITY
    explicit map(const allocator_type& __a)
        : __tree_(typename __base::allocator_type(__a))
        {
        }

    _LIBCPP_INLINE_VISIBILITY
    map(const map& __m, const allocator_type& __a)
        : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a))
        {
            insert(__m.begin(), __m.end());
        }

    _LIBCPP_INLINE_VISIBILITY
    ~map() {
        static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
    }

    _LIBCPP_INLINE_VISIBILITY
          iterator begin() _NOEXCEPT {return __tree_.begin();}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
    _LIBCPP_INLINE_VISIBILITY
          iterator end() _NOEXCEPT {return __tree_.end();}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator end() const _NOEXCEPT {return __tree_.end();}

    _LIBCPP_INLINE_VISIBILITY
          reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
    _LIBCPP_INLINE_VISIBILITY
    const_reverse_iterator rbegin() const _NOEXCEPT
        {return const_reverse_iterator(end());}
    _LIBCPP_INLINE_VISIBILITY
          reverse_iterator rend() _NOEXCEPT
            {return       reverse_iterator(begin());}
    _LIBCPP_INLINE_VISIBILITY
    const_reverse_iterator rend() const _NOEXCEPT
        {return const_reverse_iterator(begin());}

    _LIBCPP_INLINE_VISIBILITY
    const_iterator cbegin() const _NOEXCEPT {return begin();}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator cend() const _NOEXCEPT {return end();}
    _LIBCPP_INLINE_VISIBILITY
    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
    _LIBCPP_INLINE_VISIBILITY
    const_reverse_iterator crend() const _NOEXCEPT {return rend();}

    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
    bool      empty() const _NOEXCEPT {return __tree_.size() == 0;}
    _LIBCPP_INLINE_VISIBILITY
    size_type size() const _NOEXCEPT {return __tree_.size();}
    _LIBCPP_INLINE_VISIBILITY
    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}

    mapped_type& operator[](const key_type& __k);
#ifndef _LIBCPP_CXX03_LANG
    mapped_type& operator[](key_type&& __k);
#endif

          mapped_type& at(const key_type& __k);
    const mapped_type& at(const key_type& __k) const;

    _LIBCPP_INLINE_VISIBILITY
    allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());}
    _LIBCPP_INLINE_VISIBILITY
    key_compare    key_comp()      const {return __tree_.value_comp().key_comp();}
    _LIBCPP_INLINE_VISIBILITY
    value_compare  value_comp()    const {return value_compare(__tree_.value_comp().key_comp());}

#ifndef _LIBCPP_CXX03_LANG
    template <class ..._Args>
    _LIBCPP_INLINE_VISIBILITY
    pair<iterator, bool> emplace(_Args&& ...__args) {
        return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...);
    }

    template <class ..._Args>
    _LIBCPP_INLINE_VISIBILITY
    iterator emplace_hint(const_iterator __p, _Args&& ...__args) {
        return __tree_.__emplace_hint_unique(__p.__i_, _VSTD::forward<_Args>(__args)...);
    }

    template <class _Pp,
              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
        _LIBCPP_INLINE_VISIBILITY
        pair<iterator, bool> insert(_Pp&& __p)
            {return __tree_.__insert_unique(_VSTD::forward<_Pp>(__p));}

    template <class _Pp,
              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
        _LIBCPP_INLINE_VISIBILITY
        iterator insert(const_iterator __pos, _Pp&& __p)
            {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));}

#endif // _LIBCPP_CXX03_LANG

    _LIBCPP_INLINE_VISIBILITY
    pair<iterator, bool>
        insert(const value_type& __v) {return __tree_.__insert_unique(__v);}

    _LIBCPP_INLINE_VISIBILITY
    iterator
        insert(const_iterator __p, const value_type& __v)
            {return __tree_.__insert_unique(__p.__i_, __v);}

#ifndef _LIBCPP_CXX03_LANG
    _LIBCPP_INLINE_VISIBILITY
    pair<iterator, bool>
    insert(value_type&& __v) {return __tree_.__insert_unique(_VSTD::move(__v));}

    _LIBCPP_INLINE_VISIBILITY
    iterator insert(const_iterator __p,  value_type&& __v)
    {return __tree_.__insert_unique(__p.__i_, _VSTD::move(__v));}

    _LIBCPP_INLINE_VISIBILITY
    void insert(initializer_list<value_type> __il)
        {insert(__il.begin(), __il.end());}
#endif

    template <class _InputIterator>
        _LIBCPP_INLINE_VISIBILITY
        void insert(_InputIterator __f, _InputIterator __l)
        {
            for (const_iterator __e = cend(); __f != __l; ++__f)
                insert(__e.__i_, *__f);
        }

#if _LIBCPP_STD_VER > 14

    template <class... _Args>
        _LIBCPP_INLINE_VISIBILITY
        pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args)
    {
        return __tree_.__emplace_unique_key_args(__k,
            _VSTD::piecewise_construct,
            _VSTD::forward_as_tuple(__k),
            _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
    }

    template <class... _Args>
        _LIBCPP_INLINE_VISIBILITY
        pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args)
    {
        return __tree_.__emplace_unique_key_args(__k,
            _VSTD::piecewise_construct,
            _VSTD::forward_as_tuple(_VSTD::move(__k)),
            _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
    }

    template <class... _Args>
        _LIBCPP_INLINE_VISIBILITY
        iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args)
    {
        return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k,
            _VSTD::piecewise_construct,
            _VSTD::forward_as_tuple(__k),
            _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)).first;
    }

    template <class... _Args>
        _LIBCPP_INLINE_VISIBILITY
        iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args)
    {
        return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k,
            _VSTD::piecewise_construct,
            _VSTD::forward_as_tuple(_VSTD::move(__k)),
            _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)).first;
    }

    template <class _Vp>
        _LIBCPP_INLINE_VISIBILITY
        pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v)
    {
        iterator __p = lower_bound(__k);
        if ( __p != end() && !key_comp()(__k, __p->first))
        {
            __p->second = _VSTD::forward<_Vp>(__v);
            return _VSTD::make_pair(__p, false);
        }
        return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true);
    }

    template <class _Vp>
        _LIBCPP_INLINE_VISIBILITY
        pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v)
    {
        iterator __p = lower_bound(__k);
        if ( __p != end() && !key_comp()(__k, __p->first))
        {
            __p->second = _VSTD::forward<_Vp>(__v);
            return _VSTD::make_pair(__p, false);
        }
        return _VSTD::make_pair(emplace_hint(__p, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)), true);
    }

    template <class _Vp>
    _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h,
                                                        const key_type& __k,
                                                        _Vp&& __v) {
      auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args(
          __h.__i_, __k, __k, _VSTD::forward<_Vp>(__v));

      if (!__inserted)
        __r->__get_value().second = _VSTD::forward<_Vp>(__v);

      return __r;
    }

    template <class _Vp>
    _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h,
                                                        key_type&& __k,
                                                        _Vp&& __v) {
      auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args(
          __h.__i_, __k, _VSTD::move(__k), _VSTD::forward<_Vp>(__v));

      if (!__inserted)
        __r->__get_value().second = _VSTD::forward<_Vp>(__v);

      return __r;
    }

#endif // _LIBCPP_STD_VER > 14

    _LIBCPP_INLINE_VISIBILITY
    iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
    _LIBCPP_INLINE_VISIBILITY
    iterator erase(iterator __p)       {return __tree_.erase(__p.__i_);}
    _LIBCPP_INLINE_VISIBILITY
    size_type erase(const key_type& __k)
        {return __tree_.__erase_unique(__k);}
    _LIBCPP_INLINE_VISIBILITY
    iterator  erase(const_iterator __f, const_iterator __l)
        {return __tree_.erase(__f.__i_, __l.__i_);}
    _LIBCPP_INLINE_VISIBILITY
    void clear() _NOEXCEPT {__tree_.clear();}

#if _LIBCPP_STD_VER > 14
    _LIBCPP_INLINE_VISIBILITY
    insert_return_type insert(node_type&& __nh)
    {
        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
            "node_type with incompatible allocator passed to map::insert()");
        return __tree_.template __node_handle_insert_unique<
            node_type, insert_return_type>(_VSTD::move(__nh));
    }
    _LIBCPP_INLINE_VISIBILITY
    iterator insert(const_iterator __hint, node_type&& __nh)
    {
        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
            "node_type with incompatible allocator passed to map::insert()");
        return __tree_.template __node_handle_insert_unique<node_type>(
            __hint.__i_, _VSTD::move(__nh));
    }
    _LIBCPP_INLINE_VISIBILITY
    node_type extract(key_type const& __key)
    {
        return __tree_.template __node_handle_extract<node_type>(__key);
    }
    _LIBCPP_INLINE_VISIBILITY
    node_type extract(const_iterator __it)
    {
        return __tree_.template __node_handle_extract<node_type>(__it.__i_);
    }
    template <class _Compare2>
    _LIBCPP_INLINE_VISIBILITY
    void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
    {
        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
                       "merging container with incompatible allocator");
        __tree_.__node_handle_merge_unique(__source.__tree_);
    }
    template <class _Compare2>
    _LIBCPP_INLINE_VISIBILITY
    void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
    {
        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
                       "merging container with incompatible allocator");
        __tree_.__node_handle_merge_unique(__source.__tree_);
    }
    template <class _Compare2>
    _LIBCPP_INLINE_VISIBILITY
    void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
    {
        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
                       "merging container with incompatible allocator");
        __tree_.__node_handle_merge_unique(__source.__tree_);
    }
    template <class _Compare2>
    _LIBCPP_INLINE_VISIBILITY
    void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
    {
        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
                       "merging container with incompatible allocator");
        __tree_.__node_handle_merge_unique(__source.__tree_);
    }
#endif

    _LIBCPP_INLINE_VISIBILITY
    void swap(map& __m)
        _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
        {__tree_.swap(__m.__tree_);}

    _LIBCPP_INLINE_VISIBILITY
    iterator find(const key_type& __k)             {return __tree_.find(__k);}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
    find(const _K2& __k)                           {return __tree_.find(__k);}
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
    find(const _K2& __k) const                     {return __tree_.find(__k);}
#endif

    _LIBCPP_INLINE_VISIBILITY
    size_type      count(const key_type& __k) const
        {return __tree_.__count_unique(__k);}
#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
    count(const _K2& __k) const {return __tree_.__count_multi(__k);}
#endif

#if _LIBCPP_STD_VER > 17
    _LIBCPP_INLINE_VISIBILITY
    bool contains(const key_type& __k) const {return find(__k) != end();}
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
    contains(const _K2& __k) const { return find(__k) != end(); }
#endif // _LIBCPP_STD_VER > 17

    _LIBCPP_INLINE_VISIBILITY
    iterator lower_bound(const key_type& __k)
        {return __tree_.lower_bound(__k);}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator lower_bound(const key_type& __k) const
        {return __tree_.lower_bound(__k);}
#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}

    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
#endif

    _LIBCPP_INLINE_VISIBILITY
    iterator upper_bound(const key_type& __k)
        {return __tree_.upper_bound(__k);}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator upper_bound(const key_type& __k) const
        {return __tree_.upper_bound(__k);}
#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
#endif

    _LIBCPP_INLINE_VISIBILITY
    pair<iterator,iterator> equal_range(const key_type& __k)
        {return __tree_.__equal_range_unique(__k);}
    _LIBCPP_INLINE_VISIBILITY
    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
        {return __tree_.__equal_range_unique(__k);}
#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
    equal_range(const _K2& __k)       {return __tree_.__equal_range_multi(__k);}
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
    equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
#endif

private:
    typedef typename __base::__node                    __node;
    typedef typename __base::__node_allocator          __node_allocator;
    typedef typename __base::__node_pointer            __node_pointer;
    typedef typename __base::__node_base_pointer       __node_base_pointer;
    typedef typename __base::__parent_pointer          __parent_pointer;

    typedef __map_node_destructor<__node_allocator> _Dp;
    typedef unique_ptr<__node, _Dp> __node_holder;

#ifdef _LIBCPP_CXX03_LANG
    __node_holder __construct_node_with_key(const key_type& __k);
#endif
};

#if _LIBCPP_STD_VER >= 17
template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>,
         class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
         class = enable_if_t<!__is_allocator<_Compare>::value, void>,
         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
  -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;

template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>,
         class _Allocator = allocator<pair<const _Key, _Tp>>,
         class = enable_if_t<!__is_allocator<_Compare>::value, void>,
         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator())
  -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;

template<class _InputIterator, class _Allocator,
         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
map(_InputIterator, _InputIterator, _Allocator)
  -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
         less<__iter_key_type<_InputIterator>>, _Allocator>;

template<class _Key, class _Tp, class _Allocator,
         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
map(initializer_list<pair<_Key, _Tp>>, _Allocator)
  -> map<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
#endif

#ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Tp, class _Compare, class _Allocator>
map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
    : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a))
{
    if (__a != __m.get_allocator())
    {
        const_iterator __e = cend();
        while (!__m.empty())
            __tree_.__insert_unique(__e.__i_,
                    __m.__tree_.remove(__m.begin().__i_)->__value_.__move());
    }
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
_Tp&
map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
{
    return __tree_.__emplace_unique_key_args(__k,
        _VSTD::piecewise_construct,
        _VSTD::forward_as_tuple(__k),
        _VSTD::forward_as_tuple()).first->__get_value().second;
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
_Tp&
map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k)
{
    return __tree_.__emplace_unique_key_args(__k,
        _VSTD::piecewise_construct,
        _VSTD::forward_as_tuple(_VSTD::move(__k)),
        _VSTD::forward_as_tuple()).first->__get_value().second;
}

#else // _LIBCPP_CXX03_LANG

template <class _Key, class _Tp, class _Compare, class _Allocator>
typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k)
{
    __node_allocator& __na = __tree_.__node_alloc();
    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().first), __k);
    __h.get_deleter().__first_constructed = true;
    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().second));
    __h.get_deleter().__second_constructed = true;
    return __h;
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
_Tp&
map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
{
    __parent_pointer __parent;
    __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
    __node_pointer __r = static_cast<__node_pointer>(__child);
    if (__child == nullptr)
    {
        __node_holder __h = __construct_node_with_key(__k);
        __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
        __r = __h.release();
    }
    return __r->__value_.__get_value().second;
}

#endif // _LIBCPP_CXX03_LANG

template <class _Key, class _Tp, class _Compare, class _Allocator>
_Tp&
map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k)
{
    __parent_pointer __parent;
    __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
    if (__child == nullptr)
        __throw_out_of_range("map::at:  key not found");
    return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
const _Tp&
map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const
{
    __parent_pointer __parent;
    __node_base_pointer __child = __tree_.__find_equal(__parent, __k);
    if (__child == nullptr)
        __throw_out_of_range("map::at:  key not found");
    return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
}


template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x,
           const map<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator< (const map<_Key, _Tp, _Compare, _Allocator>& __x,
           const map<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
           const map<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return !(__x == __y);
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator> (const map<_Key, _Tp, _Compare, _Allocator>& __x,
           const map<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return __y < __x;
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
           const map<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return !(__x < __y);
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
           const map<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return !(__y < __x);
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
     map<_Key, _Tp, _Compare, _Allocator>& __y)
    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
{
    __x.swap(__y);
}

#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Compare, class _Allocator,
          class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
    typename map<_Key, _Tp, _Compare, _Allocator>::size_type
    erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
  return _VSTD::__libcpp_erase_if_container(__c, __pred);
}
#endif


template <class _Key, class _Tp, class _Compare = less<_Key>,
          class _Allocator = allocator<pair<const _Key, _Tp> > >
class _LIBCPP_TEMPLATE_VIS multimap
{
public:
    // types:
    typedef _Key                                     key_type;
    typedef _Tp                                      mapped_type;
    typedef pair<const key_type, mapped_type>        value_type;
    typedef __identity_t<_Compare>                   key_compare;
    typedef __identity_t<_Allocator>                 allocator_type;
    typedef value_type&                              reference;
    typedef const value_type&                        const_reference;

    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
                  "Allocator::value_type must be same type as value_type");

_LIBCPP_SUPPRESS_DEPRECATED_PUSH
    class _LIBCPP_TEMPLATE_VIS value_compare
#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
        : public binary_function<value_type, value_type, bool>
#endif
    {
_LIBCPP_SUPPRESS_DEPRECATED_POP
        friend class multimap;
    protected:
        key_compare comp;

        _LIBCPP_INLINE_VISIBILITY
        value_compare(key_compare c) : comp(c) {}
    public:
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
        _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type first_argument_type;
        _LIBCPP_DEPRECATED_IN_CXX17 typedef value_type second_argument_type;
#endif
        _LIBCPP_INLINE_VISIBILITY
        bool operator()(const value_type& __x, const value_type& __y) const
            {return comp(__x.first, __y.first);}
    };

private:

    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
    typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
                                                 __value_type>::type __allocator_type;
    typedef __tree<__value_type, __vc, __allocator_type>            __base;
    typedef typename __base::__node_traits                          __node_traits;
    typedef allocator_traits<allocator_type>                        __alloc_traits;

    __base __tree_;

public:
    typedef typename __alloc_traits::pointer               pointer;
    typedef typename __alloc_traits::const_pointer         const_pointer;
    typedef typename __alloc_traits::size_type             size_type;
    typedef typename __alloc_traits::difference_type       difference_type;
    typedef __map_iterator<typename __base::iterator>      iterator;
    typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
    typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
    typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;

#if _LIBCPP_STD_VER > 14
    typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
#endif

    template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
        friend class _LIBCPP_TEMPLATE_VIS map;
    template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
        friend class _LIBCPP_TEMPLATE_VIS multimap;

    _LIBCPP_INLINE_VISIBILITY
    multimap()
        _NOEXCEPT_(
            is_nothrow_default_constructible<allocator_type>::value &&
            is_nothrow_default_constructible<key_compare>::value &&
            is_nothrow_copy_constructible<key_compare>::value)
        : __tree_(__vc(key_compare())) {}

    _LIBCPP_INLINE_VISIBILITY
    explicit multimap(const key_compare& __comp)
        _NOEXCEPT_(
            is_nothrow_default_constructible<allocator_type>::value &&
            is_nothrow_copy_constructible<key_compare>::value)
        : __tree_(__vc(__comp)) {}

    _LIBCPP_INLINE_VISIBILITY
    explicit multimap(const key_compare& __comp, const allocator_type& __a)
        : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}

    template <class _InputIterator>
        _LIBCPP_INLINE_VISIBILITY
        multimap(_InputIterator __f, _InputIterator __l,
            const key_compare& __comp = key_compare())
        : __tree_(__vc(__comp))
        {
            insert(__f, __l);
        }

    template <class _InputIterator>
        _LIBCPP_INLINE_VISIBILITY
        multimap(_InputIterator __f, _InputIterator __l,
            const key_compare& __comp, const allocator_type& __a)
        : __tree_(__vc(__comp), typename __base::allocator_type(__a))
        {
            insert(__f, __l);
        }

#if _LIBCPP_STD_VER > 11
    template <class _InputIterator>
    _LIBCPP_INLINE_VISIBILITY
    multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
        : multimap(__f, __l, key_compare(), __a) {}
#endif

    _LIBCPP_INLINE_VISIBILITY
    multimap(const multimap& __m)
        : __tree_(__m.__tree_.value_comp(),
          __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc()))
        {
            insert(__m.begin(), __m.end());
        }

    _LIBCPP_INLINE_VISIBILITY
    multimap& operator=(const multimap& __m)
        {
#ifndef _LIBCPP_CXX03_LANG
            __tree_ = __m.__tree_;
#else
            if (this != _VSTD::addressof(__m)) {
                __tree_.clear();
                __tree_.value_comp() = __m.__tree_.value_comp();
                __tree_.__copy_assign_alloc(__m.__tree_);
                insert(__m.begin(), __m.end());
            }
#endif
            return *this;
        }

#ifndef _LIBCPP_CXX03_LANG

    _LIBCPP_INLINE_VISIBILITY
    multimap(multimap&& __m)
        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
        : __tree_(_VSTD::move(__m.__tree_))
        {
        }

    multimap(multimap&& __m, const allocator_type& __a);

    _LIBCPP_INLINE_VISIBILITY
    multimap& operator=(multimap&& __m)
        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
        {
            __tree_ = _VSTD::move(__m.__tree_);
            return *this;
        }

    _LIBCPP_INLINE_VISIBILITY
    multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
        : __tree_(__vc(__comp))
        {
            insert(__il.begin(), __il.end());
        }

    _LIBCPP_INLINE_VISIBILITY
    multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
        : __tree_(__vc(__comp), typename __base::allocator_type(__a))
        {
            insert(__il.begin(), __il.end());
        }

#if _LIBCPP_STD_VER > 11
    _LIBCPP_INLINE_VISIBILITY
    multimap(initializer_list<value_type> __il, const allocator_type& __a)
        : multimap(__il, key_compare(), __a) {}
#endif

    _LIBCPP_INLINE_VISIBILITY
    multimap& operator=(initializer_list<value_type> __il)
        {
            __tree_.__assign_multi(__il.begin(), __il.end());
            return *this;
        }

#endif // _LIBCPP_CXX03_LANG

    _LIBCPP_INLINE_VISIBILITY
    explicit multimap(const allocator_type& __a)
        : __tree_(typename __base::allocator_type(__a))
        {
        }

    _LIBCPP_INLINE_VISIBILITY
    multimap(const multimap& __m, const allocator_type& __a)
        : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a))
        {
            insert(__m.begin(), __m.end());
        }

    _LIBCPP_INLINE_VISIBILITY
    ~multimap() {
        static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
    }

    _LIBCPP_INLINE_VISIBILITY
          iterator begin() _NOEXCEPT {return __tree_.begin();}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
    _LIBCPP_INLINE_VISIBILITY
          iterator end() _NOEXCEPT {return __tree_.end();}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator end() const _NOEXCEPT {return __tree_.end();}

    _LIBCPP_INLINE_VISIBILITY
          reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
    _LIBCPP_INLINE_VISIBILITY
    const_reverse_iterator rbegin() const _NOEXCEPT
        {return const_reverse_iterator(end());}
    _LIBCPP_INLINE_VISIBILITY
          reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
    _LIBCPP_INLINE_VISIBILITY
    const_reverse_iterator rend() const _NOEXCEPT
        {return const_reverse_iterator(begin());}

    _LIBCPP_INLINE_VISIBILITY
    const_iterator cbegin()  const _NOEXCEPT {return begin();}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator cend() const _NOEXCEPT {return end();}
    _LIBCPP_INLINE_VISIBILITY
    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
    _LIBCPP_INLINE_VISIBILITY
    const_reverse_iterator crend() const _NOEXCEPT {return rend();}

    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
    bool empty() const _NOEXCEPT {return __tree_.size() == 0;}
    _LIBCPP_INLINE_VISIBILITY
    size_type size() const _NOEXCEPT {return __tree_.size();}
    _LIBCPP_INLINE_VISIBILITY
    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}

    _LIBCPP_INLINE_VISIBILITY
    allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());}
    _LIBCPP_INLINE_VISIBILITY
    key_compare    key_comp() const {return __tree_.value_comp().key_comp();}
    _LIBCPP_INLINE_VISIBILITY
    value_compare  value_comp() const
        {return value_compare(__tree_.value_comp().key_comp());}

#ifndef _LIBCPP_CXX03_LANG

    template <class ..._Args>
    _LIBCPP_INLINE_VISIBILITY
    iterator emplace(_Args&& ...__args) {
        return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...);
    }

    template <class ..._Args>
    _LIBCPP_INLINE_VISIBILITY
    iterator emplace_hint(const_iterator __p, _Args&& ...__args) {
        return __tree_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...);
    }

    template <class _Pp,
              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
        _LIBCPP_INLINE_VISIBILITY
        iterator insert(_Pp&& __p)
            {return __tree_.__insert_multi(_VSTD::forward<_Pp>(__p));}

    template <class _Pp,
              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
        _LIBCPP_INLINE_VISIBILITY
        iterator insert(const_iterator __pos, _Pp&& __p)
            {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));}

    _LIBCPP_INLINE_VISIBILITY
    iterator insert(value_type&& __v)
        {return __tree_.__insert_multi(_VSTD::move(__v));}

    _LIBCPP_INLINE_VISIBILITY
    iterator insert(const_iterator __p, value_type&& __v)
        {return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));}


    _LIBCPP_INLINE_VISIBILITY
    void insert(initializer_list<value_type> __il)
        {insert(__il.begin(), __il.end());}

#endif // _LIBCPP_CXX03_LANG

    _LIBCPP_INLINE_VISIBILITY
    iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);}

    _LIBCPP_INLINE_VISIBILITY
    iterator insert(const_iterator __p, const value_type& __v)
            {return __tree_.__insert_multi(__p.__i_, __v);}

    template <class _InputIterator>
        _LIBCPP_INLINE_VISIBILITY
        void insert(_InputIterator __f, _InputIterator __l)
        {
            for (const_iterator __e = cend(); __f != __l; ++__f)
                __tree_.__insert_multi(__e.__i_, *__f);
        }

    _LIBCPP_INLINE_VISIBILITY
    iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
    _LIBCPP_INLINE_VISIBILITY
    iterator erase(iterator __p)       {return __tree_.erase(__p.__i_);}
    _LIBCPP_INLINE_VISIBILITY
    size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}
    _LIBCPP_INLINE_VISIBILITY
    iterator  erase(const_iterator __f, const_iterator __l)
        {return __tree_.erase(__f.__i_, __l.__i_);}

#if _LIBCPP_STD_VER > 14
    _LIBCPP_INLINE_VISIBILITY
    iterator insert(node_type&& __nh)
    {
        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
            "node_type with incompatible allocator passed to multimap::insert()");
        return __tree_.template __node_handle_insert_multi<node_type>(
            _VSTD::move(__nh));
    }
    _LIBCPP_INLINE_VISIBILITY
    iterator insert(const_iterator __hint, node_type&& __nh)
    {
        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
            "node_type with incompatible allocator passed to multimap::insert()");
        return __tree_.template __node_handle_insert_multi<node_type>(
            __hint.__i_, _VSTD::move(__nh));
    }
    _LIBCPP_INLINE_VISIBILITY
    node_type extract(key_type const& __key)
    {
        return __tree_.template __node_handle_extract<node_type>(__key);
    }
    _LIBCPP_INLINE_VISIBILITY
    node_type extract(const_iterator __it)
    {
        return __tree_.template __node_handle_extract<node_type>(
            __it.__i_);
    }
    template <class _Compare2>
    _LIBCPP_INLINE_VISIBILITY
    void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
    {
        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
                       "merging container with incompatible allocator");
        return __tree_.__node_handle_merge_multi(__source.__tree_);
    }
    template <class _Compare2>
    _LIBCPP_INLINE_VISIBILITY
    void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
    {
        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
                       "merging container with incompatible allocator");
        return __tree_.__node_handle_merge_multi(__source.__tree_);
    }
    template <class _Compare2>
    _LIBCPP_INLINE_VISIBILITY
    void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
    {
        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
                       "merging container with incompatible allocator");
        return __tree_.__node_handle_merge_multi(__source.__tree_);
    }
    template <class _Compare2>
    _LIBCPP_INLINE_VISIBILITY
    void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
    {
        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
                       "merging container with incompatible allocator");
        return __tree_.__node_handle_merge_multi(__source.__tree_);
    }
#endif

    _LIBCPP_INLINE_VISIBILITY
    void clear() _NOEXCEPT {__tree_.clear();}

    _LIBCPP_INLINE_VISIBILITY
    void swap(multimap& __m)
        _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
        {__tree_.swap(__m.__tree_);}

    _LIBCPP_INLINE_VISIBILITY
    iterator find(const key_type& __k)             {return __tree_.find(__k);}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
    find(const _K2& __k)                           {return __tree_.find(__k);}
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
    find(const _K2& __k) const                     {return __tree_.find(__k);}
#endif

    _LIBCPP_INLINE_VISIBILITY
    size_type      count(const key_type& __k) const
        {return __tree_.__count_multi(__k);}
#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
    count(const _K2& __k) const {return __tree_.__count_multi(__k);}
#endif

#if _LIBCPP_STD_VER > 17
    _LIBCPP_INLINE_VISIBILITY
    bool contains(const key_type& __k) const {return find(__k) != end();}
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
    contains(const _K2& __k) const { return find(__k) != end(); }
#endif // _LIBCPP_STD_VER > 17

    _LIBCPP_INLINE_VISIBILITY
    iterator lower_bound(const key_type& __k)
        {return __tree_.lower_bound(__k);}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator lower_bound(const key_type& __k) const
            {return __tree_.lower_bound(__k);}
#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}

    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
#endif

    _LIBCPP_INLINE_VISIBILITY
    iterator upper_bound(const key_type& __k)
            {return __tree_.upper_bound(__k);}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator upper_bound(const key_type& __k) const
            {return __tree_.upper_bound(__k);}
#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
#endif

    _LIBCPP_INLINE_VISIBILITY
    pair<iterator,iterator>             equal_range(const key_type& __k)
            {return __tree_.__equal_range_multi(__k);}
    _LIBCPP_INLINE_VISIBILITY
    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
            {return __tree_.__equal_range_multi(__k);}
#if _LIBCPP_STD_VER > 11
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
    equal_range(const _K2& __k)       {return __tree_.__equal_range_multi(__k);}
    template <typename _K2>
    _LIBCPP_INLINE_VISIBILITY
    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
    equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
#endif

private:
    typedef typename __base::__node                    __node;
    typedef typename __base::__node_allocator          __node_allocator;
    typedef typename __base::__node_pointer            __node_pointer;

    typedef __map_node_destructor<__node_allocator> _Dp;
    typedef unique_ptr<__node, _Dp> __node_holder;
};

#if _LIBCPP_STD_VER >= 17
template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>,
         class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
         class = enable_if_t<!__is_allocator<_Compare>::value, void>,
         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
  -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;

template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>,
         class _Allocator = allocator<pair<const _Key, _Tp>>,
         class = enable_if_t<!__is_allocator<_Compare>::value, void>,
         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator())
  -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;

template<class _InputIterator, class _Allocator,
         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>,
         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
multimap(_InputIterator, _InputIterator, _Allocator)
  -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>,
         less<__iter_key_type<_InputIterator>>, _Allocator>;

template<class _Key, class _Tp, class _Allocator,
         class = enable_if_t<__is_allocator<_Allocator>::value, void>>
multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
  -> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
#endif

#ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Tp, class _Compare, class _Allocator>
multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a)
    : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a))
{
    if (__a != __m.get_allocator())
    {
        const_iterator __e = cend();
        while (!__m.empty())
            __tree_.__insert_multi(__e.__i_,
                    _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__move()));
    }
}
#endif

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator< (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return !(__x == __y);
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return __y < __x;
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return !(__x < __y);
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
{
    return !(__y < __x);
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
     multimap<_Key, _Tp, _Compare, _Allocator>& __y)
    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
{
    __x.swap(__y);
}

#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Compare, class _Allocator,
          class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
    typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type
    erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c,
             _Predicate __pred) {
  return _VSTD::__libcpp_erase_if_container(__c, __pred);
}
#endif

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_MAP
