// -*- 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

*/

#if 0
#else // 0
#  include <__algorithm/equal.h>
#  include <__algorithm/lexicographical_compare.h>
#  include <__algorithm/lexicographical_compare_three_way.h>
#  include <__assert>
#  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/allocator_traits.h>
#  include <__memory/pointer_traits.h>
#  include <__memory/unique_ptr.h>
#  include <__memory_resource/polymorphic_allocator.h>
#  include <__new/launder.h>
#  include <__node_handle>
#  include <__ranges/concepts.h>
#  include <__ranges/container_compatible_range.h>
#  include <__ranges/from_range.h>
#  include <__tree>
#  include <__type_traits/container_traits.h>
#  include <__type_traits/is_allocator.h>
#  include <__type_traits/remove_const.h>
#  include <__type_traits/type_identity.h>
#  include <__utility/forward.h>
#  include <__utility/pair.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_v<_Compare>) {
    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_v<_Compare>) {
    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_;

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

  __map_node_destructor& operator=(const __map_node_destructor&) = delete;

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

  __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_; }

  __value_type()                               = delete;
  __value_type(__value_type const&)            = delete;
  __value_type& operator=(__value_type const&) = delete;
  ~__value_type()                              = delete;
};

#  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(__check_valid_allocator<allocator_type>::value, "");

  __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(); }

  [[__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_v<__base>) { __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_v<_Compare, _K2>, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
    return __tree_.find(__k);
  }
  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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);
}

#  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, class _Allocator>
struct __container_traits<map<_Key, _Tp, _Compare, _Allocator> > {
  // http://eel.is/c++draft/associative.reqmts.except#2
  // For associative containers, if an exception is thrown by any operation from within
  // an insert or emplace function inserting a single element, the insertion has no effect.
  static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = true;
};

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(__check_valid_allocator<allocator_type>::value, "");
  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;

  __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(); }

  [[__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_v<__base>) {
    __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_v<_Compare, _K2>, int> = 0>
  _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
    return __tree_.find(__k);
  }
  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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_v<_Compare, _K2>, 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(), __synth_three_way);
}

#  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

template <class _Key, class _Tp, class _Compare, class _Allocator>
struct __container_traits<multimap<_Key, _Tp, _Compare, _Allocator> > {
  // http://eel.is/c++draft/associative.reqmts.except#2
  // For associative containers, if an exception is thrown by any operation from within
  // an insert or emplace function inserting a single element, the insertion has no effect.
  static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = true;
};

_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 // 0

#endif // _LIBCPP_MAP
