// -*- 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);
    template<container-compatible-range<value_type> R>
      map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
    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
    template<container-compatible-range<value_type> R>
      map(from_range_t, R&& rg, const Allocator& a))
        : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
    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);
    template<container-compatible-range<value_type> R>
      void insert_range(R&& rg);                                                      // C++23
    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<ranges::input_range R, class Compare = less<range-key-type<R>,
         class Allocator = allocator<range-to-alloc-type<R>>>
  map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
    -> map<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23

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<ranges::input_range R, class Allocator>
  map(from_range_t, R&&, Allocator)
    -> map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23

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);      // removed in C++20

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);      // removed in C++20

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);      // removed in C++20

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);      // removed in C++20

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);      // removed in C++20

template<class Key, class T, class Compare, class Allocator>
  synth-three-way-result<pair<const Key, T>>
    operator<=>(const map<Key, T, Compare, Allocator>& x,
                const map<Key, T, Compare, Allocator>& y); // since C++20

// 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);
    template<container-compatible-range<value_type> R>
      multimap(from_range_t, R&& rg,
               const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
    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
    template<container-compatible-range<value_type> R>
      multimap(from_range_t, R&& rg, const Allocator& a))
        : multimap(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
    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);
    template<container-compatible-range<value_type> R>
      void insert_range(R&& rg);                                                      // C++23
    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<ranges::input_range R, class Compare = less<range-key-type<R>>,
          class Allocator = allocator<range-to-alloc-type<R>>>
  multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
    -> multimap<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23

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<ranges::input_range R, class Allocator>
  multimap(from_range_t, R&&, Allocator)
    -> multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23

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);      // removed in C++20

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);      // removed in C++20

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);      // removed in C++20

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);      // removed in C++20

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);      // removed in C++20

template<class Key, class T, class Compare, class Allocator>
  synth-three-way-result<pair<const Key, T>>
    operator<=>(const multimap<Key, T, Compare, Allocator>& x,
                const multimap<Key, T, Compare, Allocator>& y); // since c++20

// 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 <__algorithm/equal.h>
#include <__algorithm/lexicographical_compare.h>
#include <__algorithm/lexicographical_compare_three_way.h>
#include <__assert>
#include <__availability>
#include <__config>
#include <__functional/binary_function.h>
#include <__functional/is_transparent.h>
#include <__functional/operations.h>
#include <__iterator/erase_if_container.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/ranges_iterator_traits.h>
#include <__iterator/reverse_iterator.h>
#include <__memory/addressof.h>
#include <__memory/allocator.h>
#include <__memory_resource/polymorphic_allocator.h>
#include <__node_handle>
#include <__ranges/concepts.h>
#include <__ranges/container_compatible_range.h>
#include <__ranges/from_range.h>
#include <__tree>
#include <__type_traits/is_allocator.h>
#include <__utility/forward.h>
#include <__utility/piecewise_construct.h>
#include <__utility/swap.h>
#include <stdexcept>
#include <tuple>
#include <version>

// standard-mandated includes

// [iterator.range]
#include <__iterator/access.h>
#include <__iterator/data.h>
#include <__iterator/empty.h>
#include <__iterator/reverse_access.h>
#include <__iterator/size.h>

// [associative.map.syn]
#include <compare>
#include <initializer_list>

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

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_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_HIDE_FROM_ABI __map_value_compare() _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
      : _Compare() {}
  _LIBCPP_HIDE_FROM_ABI __map_value_compare(_Compare __c) _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
      : _Compare(__c) {}
  _LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return *this; }
  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const {
    return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y.__get_value().first);
  }
  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const {
    return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);
  }
  _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const {
    return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);
  }
  _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) {
    using std::swap;
    swap(static_cast<_Compare&>(*this), static_cast<_Compare&>(__y));
  }

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

  template <typename _K2>
  _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI __map_value_compare() _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
      : __comp_() {}
  _LIBCPP_HIDE_FROM_ABI __map_value_compare(_Compare __c) _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
      : __comp_(__c) {}
  _LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return __comp_; }

  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const {
    return __comp_(__x.__get_value().first, __y.__get_value().first);
  }
  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const {
    return __comp_(__x.__get_value().first, __y);
  }
  _LIBCPP_HIDE_FROM_ABI 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 std::swap;
    swap(__comp_, __y.__comp_);
  }

#if _LIBCPP_STD_VER >= 14
  template <typename _K2>
  _LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const {
    return __comp_(__x, __y.__get_value().first);
  }

  template <typename _K2>
  _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI 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_HIDE_FROM_ABI explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT
      : __na_(__na),
        __first_constructed(false),
        __second_constructed(false) {}

#ifndef _LIBCPP_CXX03_LANG
  _LIBCPP_HIDE_FROM_ABI __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_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
    if (__second_constructed)
      __alloc_traits::destroy(__na_, std::addressof(__p->__value_.__get_value().second));
    if (__first_constructed)
      __alloc_traits::destroy(__na_, std::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_HIDE_FROM_ABI value_type& __get_value() {
#  if _LIBCPP_STD_VER >= 17
    return *std::launder(std::addressof(__cc_));
#  else
    return __cc_;
#  endif
  }

  _LIBCPP_HIDE_FROM_ABI const value_type& __get_value() const {
#  if _LIBCPP_STD_VER >= 17
    return *std::launder(std::addressof(__cc_));
#  else
    return __cc_;
#  endif
  }

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

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

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

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

  template <class _ValueTp, __enable_if_t<__is_same_uncvref<_ValueTp, value_type>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI __value_type& operator=(_ValueTp&& __v) {
    __ref() = std::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_HIDE_FROM_ABI value_type& __get_value() { return __cc_; }
  _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI __map_iterator() _NOEXCEPT {}

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

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

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

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

  friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __map_iterator& __x, const __map_iterator& __y) {
    return __x.__i_ == __y.__i_;
  }
  friend _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI __map_const_iterator() _NOEXCEPT {}

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

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

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

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

  friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y) {
    return __x.__i_ == __y.__i_;
  }
  friend _LIBCPP_HIDE_FROM_ABI 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 __type_identity_t<_Compare> key_compare;
  typedef __type_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");

  class _LIBCPP_TEMPLATE_VIS value_compare : public __binary_function<value_type, value_type, bool> {
    friend class map;

  protected:
    key_compare comp;

    _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : comp(__c) {}

  public:
    _LIBCPP_HIDE_FROM_ABI bool operator()(const value_type& __x, const value_type& __y) const {
      return comp(__x.first, __y.first);
    }
  };

private:
  typedef std::__value_type<key_type, mapped_type> __value_type;
  typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
  typedef __rebind_alloc<allocator_traits<allocator_type>, __value_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;

  static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
                "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
                "original allocator");

  __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 std::reverse_iterator<iterator> reverse_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

#if _LIBCPP_STD_VER >= 17
  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_HIDE_FROM_ABI 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_HIDE_FROM_ABI 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_HIDE_FROM_ABI explicit map(const key_compare& __comp, const allocator_type& __a)
      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}

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

  template <class _InputIterator>
  _LIBCPP_HIDE_FROM_ABI
  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 >= 23
  template <_ContainerCompatibleRange<value_type> _Range>
  _LIBCPP_HIDE_FROM_ABI
  map(from_range_t,
      _Range&& __range,
      const key_compare& __comp = key_compare(),
      const allocator_type& __a = allocator_type())
      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
    insert_range(std::forward<_Range>(__range));
  }
#endif

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

#if _LIBCPP_STD_VER >= 23
  template <_ContainerCompatibleRange<value_type> _Range>
  _LIBCPP_HIDE_FROM_ABI map(from_range_t, _Range&& __range, const allocator_type& __a)
      : map(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
#endif

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

  _LIBCPP_HIDE_FROM_ABI map& operator=(const map& __m) {
#ifndef _LIBCPP_CXX03_LANG
    __tree_ = __m.__tree_;
#else
    if (this != std::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_HIDE_FROM_ABI map(map&& __m) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
      : __tree_(std::move(__m.__tree_)) {}

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

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

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

  _LIBCPP_HIDE_FROM_ABI 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 >= 14
  _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const allocator_type& __a)
      : map(__il, key_compare(), __a) {}
#  endif

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

#endif // _LIBCPP_CXX03_LANG

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

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

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

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

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

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

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

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

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

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

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

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

  template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(_Pp&& __p) {
    return __tree_.__insert_unique(std::forward<_Pp>(__p));
  }

  template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, _Pp&& __p) {
    return __tree_.__insert_unique(__pos.__i_, std::forward<_Pp>(__p));
  }

#endif // _LIBCPP_CXX03_LANG

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

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

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

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

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

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

#if _LIBCPP_STD_VER >= 23
  template <_ContainerCompatibleRange<value_type> _Range>
  _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
    const_iterator __end = cend();
    for (auto&& __element : __range) {
      insert(__end.__i_, std::forward<decltype(__element)>(__element));
    }
  }
#endif

#if _LIBCPP_STD_VER >= 17

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

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

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

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

  template <class _Vp>
  _LIBCPP_HIDE_FROM_ABI 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 = std::forward<_Vp>(__v);
      return std::make_pair(__p, false);
    }
    return std::make_pair(emplace_hint(__p, __k, std::forward<_Vp>(__v)), true);
  }

  template <class _Vp>
  _LIBCPP_HIDE_FROM_ABI 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 = std::forward<_Vp>(__v);
      return std::make_pair(__p, false);
    }
    return std::make_pair(emplace_hint(__p, std::move(__k), std::forward<_Vp>(__v)), true);
  }

  template <class _Vp>
  _LIBCPP_HIDE_FROM_ABI 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, std::forward<_Vp>(__v));

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

    return __r;
  }

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

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

    return __r;
  }

#endif // _LIBCPP_STD_VER >= 17

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

#if _LIBCPP_STD_VER >= 17
  _LIBCPP_HIDE_FROM_ABI insert_return_type insert(node_type&& __nh) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__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>(std::move(__nh));
  }
  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__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_, std::move(__nh));
  }
  _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
    return __tree_.template __node_handle_extract<node_type>(__key);
  }
  _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
    return __tree_.template __node_handle_extract<node_type>(__it.__i_);
  }
  template <class _Compare2>
  _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
    __tree_.__node_handle_merge_unique(__source.__tree_);
  }
  template <class _Compare2>
  _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
    __tree_.__node_handle_merge_unique(__source.__tree_);
  }
  template <class _Compare2>
  _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
    __tree_.__node_handle_merge_unique(__source.__tree_);
  }
  template <class _Compare2>
  _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
    __tree_.__node_handle_merge_unique(__source.__tree_);
  }
#endif

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

  _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
  _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
#if _LIBCPP_STD_VER >= 14
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
    return __tree_.find(__k);
  }
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
    return __tree_.find(__k);
  }
#endif

  _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_unique(__k); }
#if _LIBCPP_STD_VER >= 14
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
    return __tree_.__count_multi(__k);
  }
#endif

#if _LIBCPP_STD_VER >= 20
  _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
    return find(__k) != end();
  }
#endif // _LIBCPP_STD_VER >= 20

  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
#if _LIBCPP_STD_VER >= 14
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
    return __tree_.lower_bound(__k);
  }

  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
    return __tree_.lower_bound(__k);
  }
#endif

  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
#if _LIBCPP_STD_VER >= 14
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
    return __tree_.upper_bound(__k);
  }
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
    return __tree_.upper_bound(__k);
  }
#endif

  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
    return __tree_.__equal_range_unique(__k);
  }
  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
    return __tree_.__equal_range_unique(__k);
  }
#if _LIBCPP_STD_VER >= 14
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
    return __tree_.__equal_range_multi(__k);
  }
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> 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
  _LIBCPP_HIDE_FROM_ABI __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<__has_input_iterator_category<_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>;

#  if _LIBCPP_STD_VER >= 23
template <ranges::input_range _Range,
          class _Compare   = less<__range_key_type<_Range>>,
          class _Allocator = allocator<__range_to_alloc_type<_Range>>,
          class            = enable_if_t<!__is_allocator<_Compare>::value, void>,
          class            = enable_if_t<__is_allocator<_Allocator>::value, void>>
map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
    -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
#  endif

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<__has_input_iterator_category<_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>;

#  if _LIBCPP_STD_VER >= 23
template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
map(from_range_t, _Range&&, _Allocator)
    -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
#  endif

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_(std::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, std::piecewise_construct, std::forward_as_tuple(__k), std::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) {
  // TODO investigate this clang-tidy warning.
  // NOLINTBEGIN(bugprone-use-after-move)
  return __tree_
      .__emplace_unique_key_args(
          __k, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple())
      .first->__get_value()
      .second;
  // NOLINTEND(bugprone-use-after-move)
}

#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, std::addressof(__h->__value_.__get_value().first), __k);
  __h.get_deleter().__first_constructed = true;
  __node_traits::construct(__na, std::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_HIDE_FROM_ABI bool
operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
  return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
}

#if _LIBCPP_STD_VER <= 17

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

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI 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_HIDE_FROM_ABI 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_HIDE_FROM_ABI bool
operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
  return !(__y < __x);
}

#else // #if _LIBCPP_STD_VER <= 17

template <class _Key, class _Tp, class _Compare, class _Allocator>
_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
operator<=>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
  return std::lexicographical_compare_three_way(
      __x.begin(),
      __x.end(),
      __y.begin(),
      __y.end(),
      std::__synth_three_way<pair<const _Key, _Tp>, pair<const _Key, _Tp>>);
}

#endif // #if _LIBCPP_STD_VER <= 17

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI 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 >= 20
template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI typename map<_Key, _Tp, _Compare, _Allocator>::size_type
erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
  return std::__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 __type_identity_t<_Compare> key_compare;
  typedef __type_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");

  class _LIBCPP_TEMPLATE_VIS value_compare : public __binary_function<value_type, value_type, bool> {
    friend class multimap;

  protected:
    key_compare comp;

    _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : comp(__c) {}

  public:
    _LIBCPP_HIDE_FROM_ABI bool operator()(const value_type& __x, const value_type& __y) const {
      return comp(__x.first, __y.first);
    }
  };

private:
  typedef std::__value_type<key_type, mapped_type> __value_type;
  typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
  typedef __rebind_alloc<allocator_traits<allocator_type>, __value_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;

  static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
                "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
                "original allocator");

  __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 std::reverse_iterator<iterator> reverse_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

#if _LIBCPP_STD_VER >= 17
  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_HIDE_FROM_ABI 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_HIDE_FROM_ABI 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_HIDE_FROM_ABI explicit multimap(const key_compare& __comp, const allocator_type& __a)
      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}

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

  template <class _InputIterator>
  _LIBCPP_HIDE_FROM_ABI
  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 >= 23
  template <_ContainerCompatibleRange<value_type> _Range>
  _LIBCPP_HIDE_FROM_ABI
  multimap(from_range_t,
           _Range&& __range,
           const key_compare& __comp = key_compare(),
           const allocator_type& __a = allocator_type())
      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
    insert_range(std::forward<_Range>(__range));
  }
#endif

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

#if _LIBCPP_STD_VER >= 23
  template <_ContainerCompatibleRange<value_type> _Range>
  _LIBCPP_HIDE_FROM_ABI multimap(from_range_t, _Range&& __range, const allocator_type& __a)
      : multimap(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
#endif

  _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI multimap& operator=(const multimap& __m) {
#ifndef _LIBCPP_CXX03_LANG
    __tree_ = __m.__tree_;
#else
    if (this != std::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_HIDE_FROM_ABI multimap(multimap&& __m) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
      : __tree_(std::move(__m.__tree_)) {}

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

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

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

  _LIBCPP_HIDE_FROM_ABI
  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 >= 14
  _LIBCPP_HIDE_FROM_ABI multimap(initializer_list<value_type> __il, const allocator_type& __a)
      : multimap(__il, key_compare(), __a) {}
#  endif

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

#endif // _LIBCPP_CXX03_LANG

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

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

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

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

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

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

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

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

#ifndef _LIBCPP_CXX03_LANG

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

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

  template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator insert(_Pp&& __p) {
    return __tree_.__insert_multi(std::forward<_Pp>(__p));
  }

  template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, _Pp&& __p) {
    return __tree_.__insert_multi(__pos.__i_, std::forward<_Pp>(__p));
  }

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

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

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

#endif // _LIBCPP_CXX03_LANG

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

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

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

#if _LIBCPP_STD_VER >= 23
  template <_ContainerCompatibleRange<value_type> _Range>
  _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
    const_iterator __end = cend();
    for (auto&& __element : __range) {
      __tree_.__insert_multi(__end.__i_, std::forward<decltype(__element)>(__element));
    }
  }
#endif

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

#if _LIBCPP_STD_VER >= 17
  _LIBCPP_HIDE_FROM_ABI iterator insert(node_type&& __nh) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__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>(std::move(__nh));
  }
  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__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_, std::move(__nh));
  }
  _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
    return __tree_.template __node_handle_extract<node_type>(__key);
  }
  _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
    return __tree_.template __node_handle_extract<node_type>(__it.__i_);
  }
  template <class _Compare2>
  _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
    return __tree_.__node_handle_merge_multi(__source.__tree_);
  }
  template <class _Compare2>
  _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
    return __tree_.__node_handle_merge_multi(__source.__tree_);
  }
  template <class _Compare2>
  _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
    return __tree_.__node_handle_merge_multi(__source.__tree_);
  }
  template <class _Compare2>
  _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) {
    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
    return __tree_.__node_handle_merge_multi(__source.__tree_);
  }
#endif

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

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

  _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
  _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
#if _LIBCPP_STD_VER >= 14
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
    return __tree_.find(__k);
  }
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
    return __tree_.find(__k);
  }
#endif

  _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_multi(__k); }
#if _LIBCPP_STD_VER >= 14
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
    return __tree_.__count_multi(__k);
  }
#endif

#if _LIBCPP_STD_VER >= 20
  _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
    return find(__k) != end();
  }
#endif // _LIBCPP_STD_VER >= 20

  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
#if _LIBCPP_STD_VER >= 14
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
    return __tree_.lower_bound(__k);
  }

  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
    return __tree_.lower_bound(__k);
  }
#endif

  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
#if _LIBCPP_STD_VER >= 14
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
    return __tree_.upper_bound(__k);
  }
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
    return __tree_.upper_bound(__k);
  }
#endif

  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
    return __tree_.__equal_range_multi(__k);
  }
  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
    return __tree_.__equal_range_multi(__k);
  }
#if _LIBCPP_STD_VER >= 14
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
    return __tree_.__equal_range_multi(__k);
  }
  template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> 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<__has_input_iterator_category<_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>;

#  if _LIBCPP_STD_VER >= 23
template <ranges::input_range _Range,
          class _Compare   = less<__range_key_type<_Range>>,
          class _Allocator = allocator<__range_to_alloc_type<_Range>>,
          class            = enable_if_t<!__is_allocator<_Compare>::value, void>,
          class            = enable_if_t<__is_allocator<_Allocator>::value, void>>
multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
    -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
#  endif

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<__has_input_iterator_category<_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>;

#  if _LIBCPP_STD_VER >= 23
template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
multimap(from_range_t, _Range&&, _Allocator)
    -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
#  endif

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_(std::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_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__move()));
  }
}
#endif

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

#if _LIBCPP_STD_VER <= 17

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

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI 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_HIDE_FROM_ABI 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_HIDE_FROM_ABI bool
operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
  return !(__y < __x);
}

#else // #if _LIBCPP_STD_VER <= 17

template <class _Key, class _Tp, class _Compare, class _Allocator>
_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
operator<=>(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
            const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
  return std::lexicographical_compare_three_way(
      __x.begin(),
      __x.end(),
      __y.begin(),
      __y.end(),
      std::__synth_three_way<pair<const _Key, _Tp>, pair<const _Key, _Tp>>);
}

#endif // #if _LIBCPP_STD_VER <= 17

template <class _Key, class _Tp, class _Compare, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI 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 >= 20
template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type
erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
  return std::__libcpp_erase_if_container(__c, __pred);
}
#endif

_LIBCPP_END_NAMESPACE_STD

#if _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
namespace pmr {
template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
using map _LIBCPP_AVAILABILITY_PMR =
    std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;

template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
using multimap _LIBCPP_AVAILABILITY_PMR =
    std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
} // namespace pmr
_LIBCPP_END_NAMESPACE_STD
#endif

_LIBCPP_POP_MACROS

#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
#  include <concepts>
#  include <cstdlib>
#  include <functional>
#  include <iterator>
#  include <type_traits>
#  include <utility>
#endif

#endif // _LIBCPP_MAP
