// -*- 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 __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#  include <__cxx03/map>
#else
#  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 <__fwd/map.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 <__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.first, __y.first);
  }
  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const {
    return static_cast<const _Compare&>(*this)(__x.first, __y);
  }
  _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const {
    return static_cast<const _Compare&>(*this)(__x, __y.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.first);
  }

  template <typename _K2>
  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const {
    return static_cast<const _Compare&>(*this)(__x.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.first, __y.first); }
  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const { return __comp_(__x.first, __y); }
  _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const { return __comp_(__x, __y.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_.second));
    if (__first_constructed)
      __alloc_traits::destroy(__na_, std::addressof(__p->__value_.first));
    if (__p)
      __alloc_traits::deallocate(__na_, __p, 1);
  }
};

template <class _TreeIterator>
class __map_const_iterator;

template <class _Key, class _Tp>
struct __value_type;

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 __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_; }
  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(*__i_); }

  _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 map;
  template <class, class, class, class>
  friend class multimap;
  template <class>
  friend class __map_const_iterator;
};

template <class _TreeIterator>
class __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_; }
  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(*__i_); }

  _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 map;
  template <class, class, class, class>
  friend class multimap;
  template <class, class, class>
  friend class __tree_const_iterator;
};

template <class _Key, class _Tp, class _Compare, class _Allocator>
class 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 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 map;
  template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
  friend class 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(std::__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->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->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_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
    }
  }
}

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->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->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_.first), __k);
  __h.get_deleter().__first_constructed = true;
  __node_traits::construct(__na, std::addressof(__h->__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_.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)
    std::__throw_out_of_range("map::at:  key not found");
  return static_cast<__node_pointer>(__child)->__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)
    std::__throw_out_of_range("map::at:  key not found");
  return static_cast<__node_pointer>(__child)->__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, class _Allocator>
class 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 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 map;
  template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
  friend class 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(std::__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_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
  }
}
#  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 // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

#endif // _LIBCPP_MAP
