xref: /freebsd/contrib/llvm-project/libcxx/include/map (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_MAP
110b57cec5SDimitry Andric#define _LIBCPP_MAP
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric
150b57cec5SDimitry Andric    map synopsis
160b57cec5SDimitry Andric
170b57cec5SDimitry Andricnamespace std
180b57cec5SDimitry Andric{
190b57cec5SDimitry Andric
200b57cec5SDimitry Andrictemplate <class Key, class T, class Compare = less<Key>,
210b57cec5SDimitry Andric          class Allocator = allocator<pair<const Key, T>>>
220b57cec5SDimitry Andricclass map
230b57cec5SDimitry Andric{
240b57cec5SDimitry Andricpublic:
250b57cec5SDimitry Andric    // types:
260b57cec5SDimitry Andric    typedef Key                                      key_type;
270b57cec5SDimitry Andric    typedef T                                        mapped_type;
280b57cec5SDimitry Andric    typedef pair<const key_type, mapped_type>        value_type;
290b57cec5SDimitry Andric    typedef Compare                                  key_compare;
300b57cec5SDimitry Andric    typedef Allocator                                allocator_type;
310b57cec5SDimitry Andric    typedef typename allocator_type::reference       reference;
320b57cec5SDimitry Andric    typedef typename allocator_type::const_reference const_reference;
330b57cec5SDimitry Andric    typedef typename allocator_type::pointer         pointer;
340b57cec5SDimitry Andric    typedef typename allocator_type::const_pointer   const_pointer;
350b57cec5SDimitry Andric    typedef typename allocator_type::size_type       size_type;
360b57cec5SDimitry Andric    typedef typename allocator_type::difference_type difference_type;
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric    typedef implementation-defined                   iterator;
390b57cec5SDimitry Andric    typedef implementation-defined                   const_iterator;
400b57cec5SDimitry Andric    typedef std::reverse_iterator<iterator>          reverse_iterator;
410b57cec5SDimitry Andric    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
420b57cec5SDimitry Andric    typedef unspecified                              node_type;              // C++17
430b57cec5SDimitry Andric    typedef INSERT_RETURN_TYPE<iterator, node_type>  insert_return_type;     // C++17
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric    class value_compare
460b57cec5SDimitry Andric    {
470b57cec5SDimitry Andric        friend class map;
480b57cec5SDimitry Andric    protected:
490b57cec5SDimitry Andric        key_compare comp;
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric        value_compare(key_compare c);
520b57cec5SDimitry Andric    public:
53fe6060f1SDimitry Andric        typedef bool result_type;  // deprecated in C++17, removed in C++20
54fe6060f1SDimitry Andric        typedef value_type first_argument_type;  // deprecated in C++17, removed in C++20
55fe6060f1SDimitry Andric        typedef value_type second_argument_type;  // deprecated in C++17, removed in C++20
560b57cec5SDimitry Andric        bool operator()(const value_type& x, const value_type& y) const;
570b57cec5SDimitry Andric    };
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric    // construct/copy/destroy:
600b57cec5SDimitry Andric    map()
610b57cec5SDimitry Andric        noexcept(
620b57cec5SDimitry Andric            is_nothrow_default_constructible<allocator_type>::value &&
630b57cec5SDimitry Andric            is_nothrow_default_constructible<key_compare>::value &&
640b57cec5SDimitry Andric            is_nothrow_copy_constructible<key_compare>::value);
650b57cec5SDimitry Andric    explicit map(const key_compare& comp);
660b57cec5SDimitry Andric    map(const key_compare& comp, const allocator_type& a);
670b57cec5SDimitry Andric    template <class InputIterator>
680b57cec5SDimitry Andric        map(InputIterator first, InputIterator last,
690b57cec5SDimitry Andric            const key_compare& comp = key_compare());
700b57cec5SDimitry Andric    template <class InputIterator>
710b57cec5SDimitry Andric        map(InputIterator first, InputIterator last,
720b57cec5SDimitry Andric            const key_compare& comp, const allocator_type& a);
7306c3fb27SDimitry Andric    template<container-compatible-range<value_type> R>
7406c3fb27SDimitry Andric      map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
750b57cec5SDimitry Andric    map(const map& m);
760b57cec5SDimitry Andric    map(map&& m)
770b57cec5SDimitry Andric        noexcept(
780b57cec5SDimitry Andric            is_nothrow_move_constructible<allocator_type>::value &&
790b57cec5SDimitry Andric            is_nothrow_move_constructible<key_compare>::value);
800b57cec5SDimitry Andric    explicit map(const allocator_type& a);
810b57cec5SDimitry Andric    map(const map& m, const allocator_type& a);
820b57cec5SDimitry Andric    map(map&& m, const allocator_type& a);
830b57cec5SDimitry Andric    map(initializer_list<value_type> il, const key_compare& comp = key_compare());
840b57cec5SDimitry Andric    map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
850b57cec5SDimitry Andric    template <class InputIterator>
860b57cec5SDimitry Andric        map(InputIterator first, InputIterator last, const allocator_type& a)
870b57cec5SDimitry Andric            : map(first, last, Compare(), a) {}  // C++14
8806c3fb27SDimitry Andric    template<container-compatible-range<value_type> R>
8906c3fb27SDimitry Andric      map(from_range_t, R&& rg, const Allocator& a))
9006c3fb27SDimitry Andric        : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
910b57cec5SDimitry Andric    map(initializer_list<value_type> il, const allocator_type& a)
920b57cec5SDimitry Andric        : map(il, Compare(), a) {}  // C++14
930b57cec5SDimitry Andric   ~map();
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric    map& operator=(const map& m);
960b57cec5SDimitry Andric    map& operator=(map&& m)
970b57cec5SDimitry Andric        noexcept(
980b57cec5SDimitry Andric            allocator_type::propagate_on_container_move_assignment::value &&
990b57cec5SDimitry Andric            is_nothrow_move_assignable<allocator_type>::value &&
1000b57cec5SDimitry Andric            is_nothrow_move_assignable<key_compare>::value);
1010b57cec5SDimitry Andric    map& operator=(initializer_list<value_type> il);
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andric    // iterators:
1040b57cec5SDimitry Andric          iterator begin() noexcept;
1050b57cec5SDimitry Andric    const_iterator begin() const noexcept;
1060b57cec5SDimitry Andric          iterator end() noexcept;
1070b57cec5SDimitry Andric    const_iterator end()   const noexcept;
1080b57cec5SDimitry Andric
1090b57cec5SDimitry Andric          reverse_iterator rbegin() noexcept;
1100b57cec5SDimitry Andric    const_reverse_iterator rbegin() const noexcept;
1110b57cec5SDimitry Andric          reverse_iterator rend() noexcept;
1120b57cec5SDimitry Andric    const_reverse_iterator rend()   const noexcept;
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric    const_iterator         cbegin()  const noexcept;
1150b57cec5SDimitry Andric    const_iterator         cend()    const noexcept;
1160b57cec5SDimitry Andric    const_reverse_iterator crbegin() const noexcept;
1170b57cec5SDimitry Andric    const_reverse_iterator crend()   const noexcept;
1180b57cec5SDimitry Andric
1190b57cec5SDimitry Andric    // capacity:
1200b57cec5SDimitry Andric    bool      empty()    const noexcept;
1210b57cec5SDimitry Andric    size_type size()     const noexcept;
1220b57cec5SDimitry Andric    size_type max_size() const noexcept;
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andric    // element access:
1250b57cec5SDimitry Andric    mapped_type& operator[](const key_type& k);
1260b57cec5SDimitry Andric    mapped_type& operator[](key_type&& k);
1270b57cec5SDimitry Andric
1280b57cec5SDimitry Andric          mapped_type& at(const key_type& k);
1290b57cec5SDimitry Andric    const mapped_type& at(const key_type& k) const;
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric    // modifiers:
1320b57cec5SDimitry Andric    template <class... Args>
1330b57cec5SDimitry Andric        pair<iterator, bool> emplace(Args&&... args);
1340b57cec5SDimitry Andric    template <class... Args>
1350b57cec5SDimitry Andric        iterator emplace_hint(const_iterator position, Args&&... args);
1360b57cec5SDimitry Andric    pair<iterator, bool> insert(const value_type& v);
1370b57cec5SDimitry Andric    pair<iterator, bool> insert(      value_type&& v);                                // C++17
1380b57cec5SDimitry Andric    template <class P>
1390b57cec5SDimitry Andric        pair<iterator, bool> insert(P&& p);
1400b57cec5SDimitry Andric    iterator insert(const_iterator position, const value_type& v);
1410b57cec5SDimitry Andric    iterator insert(const_iterator position,       value_type&& v);                   // C++17
1420b57cec5SDimitry Andric    template <class P>
1430b57cec5SDimitry Andric        iterator insert(const_iterator position, P&& p);
1440b57cec5SDimitry Andric    template <class InputIterator>
1450b57cec5SDimitry Andric        void insert(InputIterator first, InputIterator last);
14606c3fb27SDimitry Andric    template<container-compatible-range<value_type> R>
14706c3fb27SDimitry Andric      void insert_range(R&& rg);                                                      // C++23
1480b57cec5SDimitry Andric    void insert(initializer_list<value_type> il);
1490b57cec5SDimitry Andric
1500b57cec5SDimitry Andric    node_type extract(const_iterator position);                                       // C++17
1510b57cec5SDimitry Andric    node_type extract(const key_type& x);                                             // C++17
1520b57cec5SDimitry Andric    insert_return_type insert(node_type&& nh);                                        // C++17
1530b57cec5SDimitry Andric    iterator insert(const_iterator hint, node_type&& nh);                             // C++17
1540b57cec5SDimitry Andric
1550b57cec5SDimitry Andric    template <class... Args>
1560b57cec5SDimitry Andric        pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);          // C++17
1570b57cec5SDimitry Andric    template <class... Args>
1580b57cec5SDimitry Andric        pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);               // C++17
1590b57cec5SDimitry Andric    template <class... Args>
1600b57cec5SDimitry Andric        iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
1610b57cec5SDimitry Andric    template <class... Args>
1620b57cec5SDimitry Andric        iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);      // C++17
1630b57cec5SDimitry Andric    template <class M>
1640b57cec5SDimitry Andric        pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);            // C++17
1650b57cec5SDimitry Andric    template <class M>
1660b57cec5SDimitry Andric        pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);                 // C++17
1670b57cec5SDimitry Andric    template <class M>
1680b57cec5SDimitry Andric        iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);   // C++17
1690b57cec5SDimitry Andric    template <class M>
1700b57cec5SDimitry Andric        iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);        // C++17
1710b57cec5SDimitry Andric
1720b57cec5SDimitry Andric    iterator  erase(const_iterator position);
1730b57cec5SDimitry Andric    iterator  erase(iterator position); // C++14
1740b57cec5SDimitry Andric    size_type erase(const key_type& k);
1750b57cec5SDimitry Andric    iterator  erase(const_iterator first, const_iterator last);
1760b57cec5SDimitry Andric    void clear() noexcept;
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric    template<class C2>
1790b57cec5SDimitry Andric      void merge(map<Key, T, C2, Allocator>& source);         // C++17
1800b57cec5SDimitry Andric    template<class C2>
1810b57cec5SDimitry Andric      void merge(map<Key, T, C2, Allocator>&& source);        // C++17
1820b57cec5SDimitry Andric    template<class C2>
1830b57cec5SDimitry Andric      void merge(multimap<Key, T, C2, Allocator>& source);    // C++17
1840b57cec5SDimitry Andric    template<class C2>
1850b57cec5SDimitry Andric      void merge(multimap<Key, T, C2, Allocator>&& source);   // C++17
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric    void swap(map& m)
1880b57cec5SDimitry Andric        noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
1890b57cec5SDimitry Andric            is_nothrow_swappable<key_compare>::value); // C++17
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andric    // observers:
1920b57cec5SDimitry Andric    allocator_type get_allocator() const noexcept;
1930b57cec5SDimitry Andric    key_compare    key_comp()      const;
1940b57cec5SDimitry Andric    value_compare  value_comp()    const;
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andric    // map operations:
1970b57cec5SDimitry Andric          iterator find(const key_type& k);
1980b57cec5SDimitry Andric    const_iterator find(const key_type& k) const;
1990b57cec5SDimitry Andric    template<typename K>
2000b57cec5SDimitry Andric        iterator find(const K& x);              // C++14
2010b57cec5SDimitry Andric    template<typename K>
2020b57cec5SDimitry Andric        const_iterator find(const K& x) const;  // C++14
203fe6060f1SDimitry Andric
2040b57cec5SDimitry Andric    template<typename K>
2050b57cec5SDimitry Andric      size_type count(const K& x) const;        // C++14
2060b57cec5SDimitry Andric    size_type      count(const key_type& k) const;
207fe6060f1SDimitry Andric
2080b57cec5SDimitry Andric    bool           contains(const key_type& x) const;  // C++20
209fe6060f1SDimitry Andric    template<class K> bool contains(const K& x) const; // C++20
210fe6060f1SDimitry Andric
2110b57cec5SDimitry Andric          iterator lower_bound(const key_type& k);
2120b57cec5SDimitry Andric    const_iterator lower_bound(const key_type& k) const;
2130b57cec5SDimitry Andric    template<typename K>
2140b57cec5SDimitry Andric        iterator lower_bound(const K& x);              // C++14
2150b57cec5SDimitry Andric    template<typename K>
2160b57cec5SDimitry Andric        const_iterator lower_bound(const K& x) const;  // C++14
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric          iterator upper_bound(const key_type& k);
2190b57cec5SDimitry Andric    const_iterator upper_bound(const key_type& k) const;
2200b57cec5SDimitry Andric    template<typename K>
2210b57cec5SDimitry Andric        iterator upper_bound(const K& x);              // C++14
2220b57cec5SDimitry Andric    template<typename K>
2230b57cec5SDimitry Andric        const_iterator upper_bound(const K& x) const;  // C++14
2240b57cec5SDimitry Andric
2250b57cec5SDimitry Andric    pair<iterator,iterator>             equal_range(const key_type& k);
2260b57cec5SDimitry Andric    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
2270b57cec5SDimitry Andric    template<typename K>
2280b57cec5SDimitry Andric        pair<iterator,iterator>             equal_range(const K& x);        // C++14
2290b57cec5SDimitry Andric    template<typename K>
2300b57cec5SDimitry Andric        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
2310b57cec5SDimitry Andric};
2320b57cec5SDimitry Andric
233349cc55cSDimitry Andrictemplate <class InputIterator,
234349cc55cSDimitry Andric      class Compare = less<iter_key_t<InputIterator>>,
235349cc55cSDimitry Andric      class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
236349cc55cSDimitry Andricmap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
237349cc55cSDimitry Andric  -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17
238349cc55cSDimitry Andric
23906c3fb27SDimitry Andrictemplate<ranges::input_range R, class Compare = less<range-key-type<R>,
24006c3fb27SDimitry Andric         class Allocator = allocator<range-to-alloc-type<R>>>
24106c3fb27SDimitry Andric  map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
24206c3fb27SDimitry Andric    -> map<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23
24306c3fb27SDimitry Andric
244349cc55cSDimitry Andrictemplate<class Key, class T, class Compare = less<Key>,
245349cc55cSDimitry Andric    class Allocator = allocator<pair<const Key, T>>>
246349cc55cSDimitry Andricmap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
247349cc55cSDimitry Andric  -> map<Key, T, Compare, Allocator>; // C++17
248349cc55cSDimitry Andric
249349cc55cSDimitry Andrictemplate <class InputIterator, class Allocator>
250349cc55cSDimitry Andricmap(InputIterator, InputIterator, Allocator)
251349cc55cSDimitry Andric  -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, less<iter_key_t<InputIterator>>,
252349cc55cSDimitry Andric    Allocator>; // C++17
253349cc55cSDimitry Andric
25406c3fb27SDimitry Andrictemplate<ranges::input_range R, class Allocator>
25506c3fb27SDimitry Andric  map(from_range_t, R&&, Allocator)
25606c3fb27SDimitry Andric    -> map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23
25706c3fb27SDimitry Andric
258349cc55cSDimitry Andrictemplate<class Key, class T, class Allocator>
259349cc55cSDimitry Andricmap(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>; // C++17
260349cc55cSDimitry Andric
2610b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
2620b57cec5SDimitry Andricbool
2630b57cec5SDimitry Andricoperator==(const map<Key, T, Compare, Allocator>& x,
2640b57cec5SDimitry Andric           const map<Key, T, Compare, Allocator>& y);
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
2670b57cec5SDimitry Andricbool
2680b57cec5SDimitry Andricoperator< (const map<Key, T, Compare, Allocator>& x,
26906c3fb27SDimitry Andric           const map<Key, T, Compare, Allocator>& y);      // removed in C++20
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
2720b57cec5SDimitry Andricbool
2730b57cec5SDimitry Andricoperator!=(const map<Key, T, Compare, Allocator>& x,
27406c3fb27SDimitry Andric           const map<Key, T, Compare, Allocator>& y);      // removed in C++20
2750b57cec5SDimitry Andric
2760b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
2770b57cec5SDimitry Andricbool
2780b57cec5SDimitry Andricoperator> (const map<Key, T, Compare, Allocator>& x,
27906c3fb27SDimitry Andric           const map<Key, T, Compare, Allocator>& y);      // removed in C++20
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
2820b57cec5SDimitry Andricbool
2830b57cec5SDimitry Andricoperator>=(const map<Key, T, Compare, Allocator>& x,
28406c3fb27SDimitry Andric           const map<Key, T, Compare, Allocator>& y);      // removed in C++20
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
2870b57cec5SDimitry Andricbool
2880b57cec5SDimitry Andricoperator<=(const map<Key, T, Compare, Allocator>& x,
28906c3fb27SDimitry Andric           const map<Key, T, Compare, Allocator>& y);      // removed in C++20
29006c3fb27SDimitry Andric
29106c3fb27SDimitry Andrictemplate<class Key, class T, class Compare, class Allocator>
29206c3fb27SDimitry Andric  synth-three-way-result<pair<const Key, T>>
29306c3fb27SDimitry Andric    operator<=>(const map<Key, T, Compare, Allocator>& x,
29406c3fb27SDimitry Andric                const map<Key, T, Compare, Allocator>& y); // since C++20
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andric// specialized algorithms:
2970b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
2980b57cec5SDimitry Andricvoid
2990b57cec5SDimitry Andricswap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
3000b57cec5SDimitry Andric    noexcept(noexcept(x.swap(y)));
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator, class Predicate>
3035ffd83dbSDimitry Andrictypename map<Key, T, Compare, Allocator>::size_type
3045ffd83dbSDimitry Andricerase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20
3050b57cec5SDimitry Andric
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andrictemplate <class Key, class T, class Compare = less<Key>,
3080b57cec5SDimitry Andric          class Allocator = allocator<pair<const Key, T>>>
3090b57cec5SDimitry Andricclass multimap
3100b57cec5SDimitry Andric{
3110b57cec5SDimitry Andricpublic:
3120b57cec5SDimitry Andric    // types:
3130b57cec5SDimitry Andric    typedef Key                                      key_type;
3140b57cec5SDimitry Andric    typedef T                                        mapped_type;
3150b57cec5SDimitry Andric    typedef pair<const key_type,mapped_type>         value_type;
3160b57cec5SDimitry Andric    typedef Compare                                  key_compare;
3170b57cec5SDimitry Andric    typedef Allocator                                allocator_type;
3180b57cec5SDimitry Andric    typedef typename allocator_type::reference       reference;
3190b57cec5SDimitry Andric    typedef typename allocator_type::const_reference const_reference;
3200b57cec5SDimitry Andric    typedef typename allocator_type::size_type       size_type;
3210b57cec5SDimitry Andric    typedef typename allocator_type::difference_type difference_type;
3220b57cec5SDimitry Andric    typedef typename allocator_type::pointer         pointer;
3230b57cec5SDimitry Andric    typedef typename allocator_type::const_pointer   const_pointer;
3240b57cec5SDimitry Andric
3250b57cec5SDimitry Andric    typedef implementation-defined                   iterator;
3260b57cec5SDimitry Andric    typedef implementation-defined                   const_iterator;
3270b57cec5SDimitry Andric    typedef std::reverse_iterator<iterator>          reverse_iterator;
3280b57cec5SDimitry Andric    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
3290b57cec5SDimitry Andric    typedef unspecified                              node_type;              // C++17
3300b57cec5SDimitry Andric
3310b57cec5SDimitry Andric    class value_compare
3320b57cec5SDimitry Andric    {
3330b57cec5SDimitry Andric        friend class multimap;
3340b57cec5SDimitry Andric    protected:
3350b57cec5SDimitry Andric        key_compare comp;
3360b57cec5SDimitry Andric        value_compare(key_compare c);
3370b57cec5SDimitry Andric    public:
338fe6060f1SDimitry Andric        typedef bool result_type;  // deprecated in C++17, removed in C++20
339fe6060f1SDimitry Andric        typedef value_type first_argument_type;  // deprecated in C++17, removed in C++20
340fe6060f1SDimitry Andric        typedef value_type second_argument_type;  // deprecated in C++17, removed in C++20
3410b57cec5SDimitry Andric        bool operator()(const value_type& x, const value_type& y) const;
3420b57cec5SDimitry Andric    };
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andric    // construct/copy/destroy:
3450b57cec5SDimitry Andric    multimap()
3460b57cec5SDimitry Andric        noexcept(
3470b57cec5SDimitry Andric            is_nothrow_default_constructible<allocator_type>::value &&
3480b57cec5SDimitry Andric            is_nothrow_default_constructible<key_compare>::value &&
3490b57cec5SDimitry Andric            is_nothrow_copy_constructible<key_compare>::value);
3500b57cec5SDimitry Andric    explicit multimap(const key_compare& comp);
3510b57cec5SDimitry Andric    multimap(const key_compare& comp, const allocator_type& a);
3520b57cec5SDimitry Andric    template <class InputIterator>
3530b57cec5SDimitry Andric        multimap(InputIterator first, InputIterator last, const key_compare& comp);
3540b57cec5SDimitry Andric    template <class InputIterator>
3550b57cec5SDimitry Andric        multimap(InputIterator first, InputIterator last, const key_compare& comp,
3560b57cec5SDimitry Andric                 const allocator_type& a);
35706c3fb27SDimitry Andric    template<container-compatible-range<value_type> R>
35806c3fb27SDimitry Andric      multimap(from_range_t, R&& rg,
35906c3fb27SDimitry Andric               const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
3600b57cec5SDimitry Andric    multimap(const multimap& m);
3610b57cec5SDimitry Andric    multimap(multimap&& m)
3620b57cec5SDimitry Andric        noexcept(
3630b57cec5SDimitry Andric            is_nothrow_move_constructible<allocator_type>::value &&
3640b57cec5SDimitry Andric            is_nothrow_move_constructible<key_compare>::value);
3650b57cec5SDimitry Andric    explicit multimap(const allocator_type& a);
3660b57cec5SDimitry Andric    multimap(const multimap& m, const allocator_type& a);
3670b57cec5SDimitry Andric    multimap(multimap&& m, const allocator_type& a);
3680b57cec5SDimitry Andric    multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());
3690b57cec5SDimitry Andric    multimap(initializer_list<value_type> il, const key_compare& comp,
3700b57cec5SDimitry Andric             const allocator_type& a);
3710b57cec5SDimitry Andric    template <class InputIterator>
3720b57cec5SDimitry Andric        multimap(InputIterator first, InputIterator last, const allocator_type& a)
3730b57cec5SDimitry Andric            : multimap(first, last, Compare(), a) {} // C++14
37406c3fb27SDimitry Andric    template<container-compatible-range<value_type> R>
37506c3fb27SDimitry Andric      multimap(from_range_t, R&& rg, const Allocator& a))
37606c3fb27SDimitry Andric        : multimap(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
3770b57cec5SDimitry Andric    multimap(initializer_list<value_type> il, const allocator_type& a)
3780b57cec5SDimitry Andric        : multimap(il, Compare(), a) {} // C++14
3790b57cec5SDimitry Andric    ~multimap();
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andric    multimap& operator=(const multimap& m);
3820b57cec5SDimitry Andric    multimap& operator=(multimap&& m)
3830b57cec5SDimitry Andric        noexcept(
3840b57cec5SDimitry Andric            allocator_type::propagate_on_container_move_assignment::value &&
3850b57cec5SDimitry Andric            is_nothrow_move_assignable<allocator_type>::value &&
3860b57cec5SDimitry Andric            is_nothrow_move_assignable<key_compare>::value);
3870b57cec5SDimitry Andric    multimap& operator=(initializer_list<value_type> il);
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andric    // iterators:
3900b57cec5SDimitry Andric          iterator begin() noexcept;
3910b57cec5SDimitry Andric    const_iterator begin() const noexcept;
3920b57cec5SDimitry Andric          iterator end() noexcept;
3930b57cec5SDimitry Andric    const_iterator end()   const noexcept;
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andric          reverse_iterator rbegin() noexcept;
3960b57cec5SDimitry Andric    const_reverse_iterator rbegin() const noexcept;
3970b57cec5SDimitry Andric          reverse_iterator rend() noexcept;
3980b57cec5SDimitry Andric    const_reverse_iterator rend()   const noexcept;
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric    const_iterator         cbegin()  const noexcept;
4010b57cec5SDimitry Andric    const_iterator         cend()    const noexcept;
4020b57cec5SDimitry Andric    const_reverse_iterator crbegin() const noexcept;
4030b57cec5SDimitry Andric    const_reverse_iterator crend()   const noexcept;
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric    // capacity:
4060b57cec5SDimitry Andric    bool      empty()    const noexcept;
4070b57cec5SDimitry Andric    size_type size()     const noexcept;
4080b57cec5SDimitry Andric    size_type max_size() const noexcept;
4090b57cec5SDimitry Andric
4100b57cec5SDimitry Andric    // modifiers:
4110b57cec5SDimitry Andric    template <class... Args>
4120b57cec5SDimitry Andric        iterator emplace(Args&&... args);
4130b57cec5SDimitry Andric    template <class... Args>
4140b57cec5SDimitry Andric        iterator emplace_hint(const_iterator position, Args&&... args);
4150b57cec5SDimitry Andric    iterator insert(const value_type& v);
4160b57cec5SDimitry Andric    iterator insert(      value_type&& v);                                            // C++17
4170b57cec5SDimitry Andric    template <class P>
4180b57cec5SDimitry Andric        iterator insert(P&& p);
4190b57cec5SDimitry Andric    iterator insert(const_iterator position, const value_type& v);
4200b57cec5SDimitry Andric    iterator insert(const_iterator position,       value_type&& v);                   // C++17
4210b57cec5SDimitry Andric    template <class P>
4220b57cec5SDimitry Andric        iterator insert(const_iterator position, P&& p);
4230b57cec5SDimitry Andric    template <class InputIterator>
4240b57cec5SDimitry Andric        void insert(InputIterator first, InputIterator last);
42506c3fb27SDimitry Andric    template<container-compatible-range<value_type> R>
42606c3fb27SDimitry Andric      void insert_range(R&& rg);                                                      // C++23
4270b57cec5SDimitry Andric    void insert(initializer_list<value_type> il);
4280b57cec5SDimitry Andric
4290b57cec5SDimitry Andric    node_type extract(const_iterator position);                                       // C++17
4300b57cec5SDimitry Andric    node_type extract(const key_type& x);                                             // C++17
4310b57cec5SDimitry Andric    iterator insert(node_type&& nh);                                                  // C++17
4320b57cec5SDimitry Andric    iterator insert(const_iterator hint, node_type&& nh);                             // C++17
4330b57cec5SDimitry Andric
4340b57cec5SDimitry Andric    iterator  erase(const_iterator position);
4350b57cec5SDimitry Andric    iterator  erase(iterator position); // C++14
4360b57cec5SDimitry Andric    size_type erase(const key_type& k);
4370b57cec5SDimitry Andric    iterator  erase(const_iterator first, const_iterator last);
4380b57cec5SDimitry Andric    void clear() noexcept;
4390b57cec5SDimitry Andric
4400b57cec5SDimitry Andric    template<class C2>
4410b57cec5SDimitry Andric      void merge(multimap<Key, T, C2, Allocator>& source);    // C++17
4420b57cec5SDimitry Andric    template<class C2>
4430b57cec5SDimitry Andric      void merge(multimap<Key, T, C2, Allocator>&& source);   // C++17
4440b57cec5SDimitry Andric    template<class C2>
4450b57cec5SDimitry Andric      void merge(map<Key, T, C2, Allocator>& source);         // C++17
4460b57cec5SDimitry Andric    template<class C2>
4470b57cec5SDimitry Andric      void merge(map<Key, T, C2, Allocator>&& source);        // C++17
4480b57cec5SDimitry Andric
4490b57cec5SDimitry Andric    void swap(multimap& m)
4500b57cec5SDimitry Andric        noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
4510b57cec5SDimitry Andric            is_nothrow_swappable<key_compare>::value); // C++17
4520b57cec5SDimitry Andric
4530b57cec5SDimitry Andric    // observers:
4540b57cec5SDimitry Andric    allocator_type get_allocator() const noexcept;
4550b57cec5SDimitry Andric    key_compare    key_comp()      const;
4560b57cec5SDimitry Andric    value_compare  value_comp()    const;
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andric    // map operations:
4590b57cec5SDimitry Andric          iterator find(const key_type& k);
4600b57cec5SDimitry Andric    const_iterator find(const key_type& k) const;
4610b57cec5SDimitry Andric    template<typename K>
4620b57cec5SDimitry Andric        iterator find(const K& x);              // C++14
4630b57cec5SDimitry Andric    template<typename K>
4640b57cec5SDimitry Andric        const_iterator find(const K& x) const;  // C++14
465fe6060f1SDimitry Andric
4660b57cec5SDimitry Andric    template<typename K>
4670b57cec5SDimitry Andric      size_type count(const K& x) const;        // C++14
4680b57cec5SDimitry Andric    size_type      count(const key_type& k) const;
469fe6060f1SDimitry Andric
4700b57cec5SDimitry Andric    bool           contains(const key_type& x) const;  // C++20
471fe6060f1SDimitry Andric    template<class K> bool contains(const K& x) const; // C++20
472fe6060f1SDimitry Andric
4730b57cec5SDimitry Andric          iterator lower_bound(const key_type& k);
4740b57cec5SDimitry Andric    const_iterator lower_bound(const key_type& k) const;
4750b57cec5SDimitry Andric    template<typename K>
4760b57cec5SDimitry Andric        iterator lower_bound(const K& x);              // C++14
4770b57cec5SDimitry Andric    template<typename K>
4780b57cec5SDimitry Andric        const_iterator lower_bound(const K& x) const;  // C++14
4790b57cec5SDimitry Andric
4800b57cec5SDimitry Andric          iterator upper_bound(const key_type& k);
4810b57cec5SDimitry Andric    const_iterator upper_bound(const key_type& k) const;
4820b57cec5SDimitry Andric    template<typename K>
4830b57cec5SDimitry Andric        iterator upper_bound(const K& x);              // C++14
4840b57cec5SDimitry Andric    template<typename K>
4850b57cec5SDimitry Andric        const_iterator upper_bound(const K& x) const;  // C++14
4860b57cec5SDimitry Andric
4870b57cec5SDimitry Andric    pair<iterator,iterator>             equal_range(const key_type& k);
4880b57cec5SDimitry Andric    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
4890b57cec5SDimitry Andric    template<typename K>
4900b57cec5SDimitry Andric        pair<iterator,iterator>             equal_range(const K& x);        // C++14
4910b57cec5SDimitry Andric    template<typename K>
4920b57cec5SDimitry Andric        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
4930b57cec5SDimitry Andric};
4940b57cec5SDimitry Andric
495349cc55cSDimitry Andrictemplate <class InputIterator,
496349cc55cSDimitry Andric      class Compare = less<iter_key_t<InputIterator>>,
497349cc55cSDimitry Andric      class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
498349cc55cSDimitry Andricmultimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
499349cc55cSDimitry Andric  -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17
500349cc55cSDimitry Andric
50106c3fb27SDimitry Andrictemplate<ranges::input_range R, class Compare = less<range-key-type<R>>,
50206c3fb27SDimitry Andric          class Allocator = allocator<range-to-alloc-type<R>>>
50306c3fb27SDimitry Andric  multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
50406c3fb27SDimitry Andric    -> multimap<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23
50506c3fb27SDimitry Andric
506349cc55cSDimitry Andrictemplate<class Key, class T, class Compare = less<Key>,
507349cc55cSDimitry Andric    class Allocator = allocator<pair<const Key, T>>>
508349cc55cSDimitry Andricmultimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
509349cc55cSDimitry Andric  -> multimap<Key, T, Compare, Allocator>; // C++17
510349cc55cSDimitry Andric
511349cc55cSDimitry Andrictemplate <class InputIterator, class Allocator>
512349cc55cSDimitry Andricmultimap(InputIterator, InputIterator, Allocator)
513349cc55cSDimitry Andric  -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
514349cc55cSDimitry Andric    less<iter_key_t<InputIterator>>, Allocator>; // C++17
515349cc55cSDimitry Andric
51606c3fb27SDimitry Andrictemplate<ranges::input_range R, class Allocator>
51706c3fb27SDimitry Andric  multimap(from_range_t, R&&, Allocator)
51806c3fb27SDimitry Andric    -> multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23
51906c3fb27SDimitry Andric
520349cc55cSDimitry Andrictemplate<class Key, class T, class Allocator>
521349cc55cSDimitry Andricmultimap(initializer_list<pair<const Key, T>>, Allocator)
522349cc55cSDimitry Andric  -> multimap<Key, T, less<Key>, Allocator>; // C++17
523349cc55cSDimitry Andric
5240b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
5250b57cec5SDimitry Andricbool
5260b57cec5SDimitry Andricoperator==(const multimap<Key, T, Compare, Allocator>& x,
5270b57cec5SDimitry Andric           const multimap<Key, T, Compare, Allocator>& y);
5280b57cec5SDimitry Andric
5290b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
5300b57cec5SDimitry Andricbool
5310b57cec5SDimitry Andricoperator< (const multimap<Key, T, Compare, Allocator>& x,
53206c3fb27SDimitry Andric           const multimap<Key, T, Compare, Allocator>& y);      // removed in C++20
5330b57cec5SDimitry Andric
5340b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
5350b57cec5SDimitry Andricbool
5360b57cec5SDimitry Andricoperator!=(const multimap<Key, T, Compare, Allocator>& x,
53706c3fb27SDimitry Andric           const multimap<Key, T, Compare, Allocator>& y);      // removed in C++20
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
5400b57cec5SDimitry Andricbool
5410b57cec5SDimitry Andricoperator> (const multimap<Key, T, Compare, Allocator>& x,
54206c3fb27SDimitry Andric           const multimap<Key, T, Compare, Allocator>& y);      // removed in C++20
5430b57cec5SDimitry Andric
5440b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
5450b57cec5SDimitry Andricbool
5460b57cec5SDimitry Andricoperator>=(const multimap<Key, T, Compare, Allocator>& x,
54706c3fb27SDimitry Andric           const multimap<Key, T, Compare, Allocator>& y);      // removed in C++20
5480b57cec5SDimitry Andric
5490b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
5500b57cec5SDimitry Andricbool
5510b57cec5SDimitry Andricoperator<=(const multimap<Key, T, Compare, Allocator>& x,
55206c3fb27SDimitry Andric           const multimap<Key, T, Compare, Allocator>& y);      // removed in C++20
55306c3fb27SDimitry Andric
55406c3fb27SDimitry Andrictemplate<class Key, class T, class Compare, class Allocator>
55506c3fb27SDimitry Andric  synth-three-way-result<pair<const Key, T>>
55606c3fb27SDimitry Andric    operator<=>(const multimap<Key, T, Compare, Allocator>& x,
55706c3fb27SDimitry Andric                const multimap<Key, T, Compare, Allocator>& y); // since c++20
5580b57cec5SDimitry Andric
5590b57cec5SDimitry Andric// specialized algorithms:
5600b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator>
5610b57cec5SDimitry Andricvoid
5620b57cec5SDimitry Andricswap(multimap<Key, T, Compare, Allocator>& x,
5630b57cec5SDimitry Andric     multimap<Key, T, Compare, Allocator>& y)
5640b57cec5SDimitry Andric    noexcept(noexcept(x.swap(y)));
5650b57cec5SDimitry Andric
5660b57cec5SDimitry Andrictemplate <class Key, class T, class Compare, class Allocator, class Predicate>
5675ffd83dbSDimitry Andrictypename multimap<Key, T, Compare, Allocator>::size_type
5685ffd83dbSDimitry Andricerase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20
5690b57cec5SDimitry Andric
5700b57cec5SDimitry Andric}  // std
5710b57cec5SDimitry Andric
5720b57cec5SDimitry Andric*/
5730b57cec5SDimitry Andric
57481ad6265SDimitry Andric#include <__algorithm/equal.h>
57581ad6265SDimitry Andric#include <__algorithm/lexicographical_compare.h>
57606c3fb27SDimitry Andric#include <__algorithm/lexicographical_compare_three_way.h>
577*0fca6ea1SDimitry Andric#include <__assert>
5780b57cec5SDimitry Andric#include <__config>
57981ad6265SDimitry Andric#include <__functional/binary_function.h>
580fe6060f1SDimitry Andric#include <__functional/is_transparent.h>
58181ad6265SDimitry Andric#include <__functional/operations.h>
58281ad6265SDimitry Andric#include <__iterator/erase_if_container.h>
583349cc55cSDimitry Andric#include <__iterator/iterator_traits.h>
58406c3fb27SDimitry Andric#include <__iterator/ranges_iterator_traits.h>
58581ad6265SDimitry Andric#include <__iterator/reverse_iterator.h>
58606c3fb27SDimitry Andric#include <__memory/addressof.h>
587bdd1243dSDimitry Andric#include <__memory/allocator.h>
588bdd1243dSDimitry Andric#include <__memory_resource/polymorphic_allocator.h>
5890b57cec5SDimitry Andric#include <__node_handle>
59006c3fb27SDimitry Andric#include <__ranges/concepts.h>
59106c3fb27SDimitry Andric#include <__ranges/container_compatible_range.h>
59206c3fb27SDimitry Andric#include <__ranges/from_range.h>
593fe6060f1SDimitry Andric#include <__tree>
594bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h>
595fe6060f1SDimitry Andric#include <__utility/forward.h>
596bdd1243dSDimitry Andric#include <__utility/piecewise_construct.h>
59781ad6265SDimitry Andric#include <__utility/swap.h>
5985f757f3fSDimitry Andric#include <stdexcept>
599bdd1243dSDimitry Andric#include <tuple>
6000b57cec5SDimitry Andric#include <version>
6010b57cec5SDimitry Andric
60281ad6265SDimitry Andric// standard-mandated includes
60381ad6265SDimitry Andric
60481ad6265SDimitry Andric// [iterator.range]
60581ad6265SDimitry Andric#include <__iterator/access.h>
60681ad6265SDimitry Andric#include <__iterator/data.h>
60781ad6265SDimitry Andric#include <__iterator/empty.h>
60881ad6265SDimitry Andric#include <__iterator/reverse_access.h>
60981ad6265SDimitry Andric#include <__iterator/size.h>
61081ad6265SDimitry Andric
61181ad6265SDimitry Andric// [associative.map.syn]
61281ad6265SDimitry Andric#include <compare>
61381ad6265SDimitry Andric#include <initializer_list>
61481ad6265SDimitry Andric
6150b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6160b57cec5SDimitry Andric#  pragma GCC system_header
6170b57cec5SDimitry Andric#endif
6180b57cec5SDimitry Andric
619b3edf446SDimitry Andric_LIBCPP_PUSH_MACROS
620b3edf446SDimitry Andric#include <__undef_macros>
621b3edf446SDimitry Andric
6220b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
6230b57cec5SDimitry Andric
624cb14a3feSDimitry Andrictemplate <class _Key,
625cb14a3feSDimitry Andric          class _CP,
626cb14a3feSDimitry Andric          class _Compare,
6270b57cec5SDimitry Andric          bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
628cb14a3feSDimitry Andricclass __map_value_compare : private _Compare {
6290b57cec5SDimitry Andricpublic:
630cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_value_compare() _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
6310b57cec5SDimitry Andric      : _Compare() {}
632cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_value_compare(_Compare __c) _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
633753f127fSDimitry Andric      : _Compare(__c) {}
634cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return *this; }
635cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const {
636cb14a3feSDimitry Andric    return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y.__get_value().first);
637cb14a3feSDimitry Andric  }
638cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const {
639cb14a3feSDimitry Andric    return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);
640cb14a3feSDimitry Andric  }
641cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const {
642cb14a3feSDimitry Andric    return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);
643cb14a3feSDimitry Andric  }
644*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) {
6455f757f3fSDimitry Andric    using std::swap;
6460b57cec5SDimitry Andric    swap(static_cast<_Compare&>(*this), static_cast<_Compare&>(__y));
6470b57cec5SDimitry Andric  }
6480b57cec5SDimitry Andric
64906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
6500b57cec5SDimitry Andric  template <typename _K2>
651cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const {
652cb14a3feSDimitry Andric    return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);
653cb14a3feSDimitry Andric  }
6540b57cec5SDimitry Andric
6550b57cec5SDimitry Andric  template <typename _K2>
656cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const {
657cb14a3feSDimitry Andric    return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);
658cb14a3feSDimitry Andric  }
6590b57cec5SDimitry Andric#endif
6600b57cec5SDimitry Andric};
6610b57cec5SDimitry Andric
6620b57cec5SDimitry Andrictemplate <class _Key, class _CP, class _Compare>
663cb14a3feSDimitry Andricclass __map_value_compare<_Key, _CP, _Compare, false> {
664bdd1243dSDimitry Andric  _Compare __comp_;
6650b57cec5SDimitry Andric
6660b57cec5SDimitry Andricpublic:
667cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_value_compare() _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
668bdd1243dSDimitry Andric      : __comp_() {}
669cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_value_compare(_Compare __c) _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
670bdd1243dSDimitry Andric      : __comp_(__c) {}
671cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return __comp_; }
6720b57cec5SDimitry Andric
673cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const {
674cb14a3feSDimitry Andric    return __comp_(__x.__get_value().first, __y.__get_value().first);
675cb14a3feSDimitry Andric  }
676cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const {
677cb14a3feSDimitry Andric    return __comp_(__x.__get_value().first, __y);
678cb14a3feSDimitry Andric  }
679cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const {
680cb14a3feSDimitry Andric    return __comp_(__x, __y.__get_value().first);
681cb14a3feSDimitry Andric  }
682*0fca6ea1SDimitry Andric  void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) {
6835f757f3fSDimitry Andric    using std::swap;
684bdd1243dSDimitry Andric    swap(__comp_, __y.__comp_);
6850b57cec5SDimitry Andric  }
6860b57cec5SDimitry Andric
68706c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
6880b57cec5SDimitry Andric  template <typename _K2>
689cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const {
690cb14a3feSDimitry Andric    return __comp_(__x, __y.__get_value().first);
691cb14a3feSDimitry Andric  }
6920b57cec5SDimitry Andric
6930b57cec5SDimitry Andric  template <typename _K2>
694cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const {
695cb14a3feSDimitry Andric    return __comp_(__x.__get_value().first, __y);
696cb14a3feSDimitry Andric  }
6970b57cec5SDimitry Andric#endif
6980b57cec5SDimitry Andric};
6990b57cec5SDimitry Andric
7000b57cec5SDimitry Andrictemplate <class _Key, class _CP, class _Compare, bool __b>
701cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
702cb14a3feSDimitry Andricswap(__map_value_compare<_Key, _CP, _Compare, __b>& __x, __map_value_compare<_Key, _CP, _Compare, __b>& __y)
703cb14a3feSDimitry Andric    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
7040b57cec5SDimitry Andric  __x.swap(__y);
7050b57cec5SDimitry Andric}
7060b57cec5SDimitry Andric
7070b57cec5SDimitry Andrictemplate <class _Allocator>
708cb14a3feSDimitry Andricclass __map_node_destructor {
7090b57cec5SDimitry Andric  typedef _Allocator allocator_type;
7100b57cec5SDimitry Andric  typedef allocator_traits<allocator_type> __alloc_traits;
7110b57cec5SDimitry Andric
7120b57cec5SDimitry Andricpublic:
7130b57cec5SDimitry Andric  typedef typename __alloc_traits::pointer pointer;
7140b57cec5SDimitry Andric
7150b57cec5SDimitry Andricprivate:
7160b57cec5SDimitry Andric  allocator_type& __na_;
7170b57cec5SDimitry Andric
7180b57cec5SDimitry Andricpublic:
7190b57cec5SDimitry Andric  bool __first_constructed;
7200b57cec5SDimitry Andric  bool __second_constructed;
7210b57cec5SDimitry Andric
722cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT
7230b57cec5SDimitry Andric      : __na_(__na),
7240b57cec5SDimitry Andric        __first_constructed(false),
725cb14a3feSDimitry Andric        __second_constructed(false) {}
7260b57cec5SDimitry Andric
7270b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
728cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_node_destructor(__tree_node_destructor<allocator_type>&& __x) _NOEXCEPT
7290b57cec5SDimitry Andric      : __na_(__x.__na_),
7300b57cec5SDimitry Andric        __first_constructed(__x.__value_constructed),
731cb14a3feSDimitry Andric        __second_constructed(__x.__value_constructed) {
7320b57cec5SDimitry Andric    __x.__value_constructed = false;
7330b57cec5SDimitry Andric  }
7340b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
7350b57cec5SDimitry Andric
736*0fca6ea1SDimitry Andric  __map_node_destructor& operator=(const __map_node_destructor&) = delete;
737*0fca6ea1SDimitry Andric
738cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
7390b57cec5SDimitry Andric    if (__second_constructed)
7405f757f3fSDimitry Andric      __alloc_traits::destroy(__na_, std::addressof(__p->__value_.__get_value().second));
7410b57cec5SDimitry Andric    if (__first_constructed)
7425f757f3fSDimitry Andric      __alloc_traits::destroy(__na_, std::addressof(__p->__value_.__get_value().first));
7430b57cec5SDimitry Andric    if (__p)
7440b57cec5SDimitry Andric      __alloc_traits::deallocate(__na_, __p, 1);
7450b57cec5SDimitry Andric  }
7460b57cec5SDimitry Andric};
7470b57cec5SDimitry Andric
7480b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
7490b57cec5SDimitry Andricclass map;
7500b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
7510b57cec5SDimitry Andricclass multimap;
752cb14a3feSDimitry Andrictemplate <class _TreeIterator>
753cb14a3feSDimitry Andricclass __map_const_iterator;
7540b57cec5SDimitry Andric
7550b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
7560b57cec5SDimitry Andric
7570b57cec5SDimitry Andrictemplate <class _Key, class _Tp>
758cb14a3feSDimitry Andricstruct _LIBCPP_STANDALONE_DEBUG __value_type {
7590b57cec5SDimitry Andric  typedef _Key key_type;
7600b57cec5SDimitry Andric  typedef _Tp mapped_type;
7610b57cec5SDimitry Andric  typedef pair<const key_type, mapped_type> value_type;
7620b57cec5SDimitry Andric  typedef pair<key_type&, mapped_type&> __nc_ref_pair_type;
7630b57cec5SDimitry Andric  typedef pair<key_type&&, mapped_type&&> __nc_rref_pair_type;
7640b57cec5SDimitry Andric
7650b57cec5SDimitry Andricprivate:
766bdd1243dSDimitry Andric  value_type __cc_;
7670b57cec5SDimitry Andric
7680b57cec5SDimitry Andricpublic:
769cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI value_type& __get_value() {
77006c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
7715f757f3fSDimitry Andric    return *std::launder(std::addressof(__cc_));
7720b57cec5SDimitry Andric#  else
773bdd1243dSDimitry Andric    return __cc_;
7740b57cec5SDimitry Andric#  endif
7750b57cec5SDimitry Andric  }
7760b57cec5SDimitry Andric
777cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const value_type& __get_value() const {
77806c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
7795f757f3fSDimitry Andric    return *std::launder(std::addressof(__cc_));
7800b57cec5SDimitry Andric#  else
781bdd1243dSDimitry Andric    return __cc_;
7820b57cec5SDimitry Andric#  endif
7830b57cec5SDimitry Andric  }
7840b57cec5SDimitry Andric
785cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __nc_ref_pair_type __ref() {
7860b57cec5SDimitry Andric    value_type& __v = __get_value();
7870b57cec5SDimitry Andric    return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second);
7880b57cec5SDimitry Andric  }
7890b57cec5SDimitry Andric
790cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __nc_rref_pair_type __move() {
7910b57cec5SDimitry Andric    value_type& __v = __get_value();
792cb14a3feSDimitry Andric    return __nc_rref_pair_type(std::move(const_cast<key_type&>(__v.first)), std::move(__v.second));
7930b57cec5SDimitry Andric  }
7940b57cec5SDimitry Andric
795cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __value_type& operator=(const __value_type& __v) {
7960b57cec5SDimitry Andric    __ref() = __v.__get_value();
7970b57cec5SDimitry Andric    return *this;
7980b57cec5SDimitry Andric  }
7990b57cec5SDimitry Andric
800cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __value_type& operator=(__value_type&& __v) {
8010b57cec5SDimitry Andric    __ref() = __v.__move();
8020b57cec5SDimitry Andric    return *this;
8030b57cec5SDimitry Andric  }
8040b57cec5SDimitry Andric
805*0fca6ea1SDimitry Andric  template <class _ValueTp, __enable_if_t<__is_same_uncvref<_ValueTp, value_type>::value, int> = 0>
806cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __value_type& operator=(_ValueTp&& __v) {
8075f757f3fSDimitry Andric    __ref() = std::forward<_ValueTp>(__v);
8080b57cec5SDimitry Andric    return *this;
8090b57cec5SDimitry Andric  }
8100b57cec5SDimitry Andric
811349cc55cSDimitry Andric  __value_type()                    = delete;
812349cc55cSDimitry Andric  ~__value_type()                   = delete;
813349cc55cSDimitry Andric  __value_type(const __value_type&) = delete;
814349cc55cSDimitry Andric  __value_type(__value_type&&)      = delete;
8150b57cec5SDimitry Andric};
8160b57cec5SDimitry Andric
8170b57cec5SDimitry Andric#else
8180b57cec5SDimitry Andric
8190b57cec5SDimitry Andrictemplate <class _Key, class _Tp>
820cb14a3feSDimitry Andricstruct __value_type {
8210b57cec5SDimitry Andric  typedef _Key key_type;
8220b57cec5SDimitry Andric  typedef _Tp mapped_type;
8230b57cec5SDimitry Andric  typedef pair<const key_type, mapped_type> value_type;
8240b57cec5SDimitry Andric
8250b57cec5SDimitry Andricprivate:
826bdd1243dSDimitry Andric  value_type __cc_;
8270b57cec5SDimitry Andric
8280b57cec5SDimitry Andricpublic:
829cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI value_type& __get_value() { return __cc_; }
830cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const value_type& __get_value() const { return __cc_; }
8310b57cec5SDimitry Andric
832*0fca6ea1SDimitry Andric  __value_type()                               = delete;
833*0fca6ea1SDimitry Andric  __value_type(__value_type const&)            = delete;
834*0fca6ea1SDimitry Andric  __value_type& operator=(__value_type const&) = delete;
835*0fca6ea1SDimitry Andric  ~__value_type()                              = delete;
8360b57cec5SDimitry Andric};
8370b57cec5SDimitry Andric
8380b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
8390b57cec5SDimitry Andric
8400b57cec5SDimitry Andrictemplate <class _Tp>
8410b57cec5SDimitry Andricstruct __extract_key_value_types;
8420b57cec5SDimitry Andric
8430b57cec5SDimitry Andrictemplate <class _Key, class _Tp>
844cb14a3feSDimitry Andricstruct __extract_key_value_types<__value_type<_Key, _Tp> > {
8450b57cec5SDimitry Andric  typedef _Key const __key_type;
8460b57cec5SDimitry Andric  typedef _Tp __mapped_type;
8470b57cec5SDimitry Andric};
8480b57cec5SDimitry Andric
8490b57cec5SDimitry Andrictemplate <class _TreeIterator>
850cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __map_iterator {
8510b57cec5SDimitry Andric  typedef typename _TreeIterator::_NodeTypes _NodeTypes;
8520b57cec5SDimitry Andric  typedef typename _TreeIterator::__pointer_traits __pointer_traits;
8530b57cec5SDimitry Andric
8540b57cec5SDimitry Andric  _TreeIterator __i_;
8550b57cec5SDimitry Andric
8560b57cec5SDimitry Andricpublic:
8570b57cec5SDimitry Andric  typedef bidirectional_iterator_tag iterator_category;
8580b57cec5SDimitry Andric  typedef typename _NodeTypes::__map_value_type value_type;
8590b57cec5SDimitry Andric  typedef typename _TreeIterator::difference_type difference_type;
8600b57cec5SDimitry Andric  typedef value_type& reference;
8610b57cec5SDimitry Andric  typedef typename _NodeTypes::__map_value_type_pointer pointer;
8620b57cec5SDimitry Andric
863cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_iterator() _NOEXCEPT {}
8640b57cec5SDimitry Andric
865cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
8660b57cec5SDimitry Andric
867cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __i_->__get_value(); }
868cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__i_->__get_value()); }
8690b57cec5SDimitry Andric
870cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_iterator& operator++() {
871cb14a3feSDimitry Andric    ++__i_;
872cb14a3feSDimitry Andric    return *this;
873cb14a3feSDimitry Andric  }
874cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_iterator operator++(int) {
8750b57cec5SDimitry Andric    __map_iterator __t(*this);
8760b57cec5SDimitry Andric    ++(*this);
8770b57cec5SDimitry Andric    return __t;
8780b57cec5SDimitry Andric  }
8790b57cec5SDimitry Andric
880cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_iterator& operator--() {
881cb14a3feSDimitry Andric    --__i_;
882cb14a3feSDimitry Andric    return *this;
883cb14a3feSDimitry Andric  }
884cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_iterator operator--(int) {
8850b57cec5SDimitry Andric    __map_iterator __t(*this);
8860b57cec5SDimitry Andric    --(*this);
8870b57cec5SDimitry Andric    return __t;
8880b57cec5SDimitry Andric  }
8890b57cec5SDimitry Andric
890cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __map_iterator& __x, const __map_iterator& __y) {
891cb14a3feSDimitry Andric    return __x.__i_ == __y.__i_;
892cb14a3feSDimitry Andric  }
893cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __map_iterator& __x, const __map_iterator& __y) {
894cb14a3feSDimitry Andric    return __x.__i_ != __y.__i_;
895cb14a3feSDimitry Andric  }
8960b57cec5SDimitry Andric
897cb14a3feSDimitry Andric  template <class, class, class, class>
898cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS map;
899cb14a3feSDimitry Andric  template <class, class, class, class>
900cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS multimap;
901cb14a3feSDimitry Andric  template <class>
902cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
9030b57cec5SDimitry Andric};
9040b57cec5SDimitry Andric
9050b57cec5SDimitry Andrictemplate <class _TreeIterator>
906cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __map_const_iterator {
9070b57cec5SDimitry Andric  typedef typename _TreeIterator::_NodeTypes _NodeTypes;
9080b57cec5SDimitry Andric  typedef typename _TreeIterator::__pointer_traits __pointer_traits;
9090b57cec5SDimitry Andric
9100b57cec5SDimitry Andric  _TreeIterator __i_;
9110b57cec5SDimitry Andric
9120b57cec5SDimitry Andricpublic:
9130b57cec5SDimitry Andric  typedef bidirectional_iterator_tag iterator_category;
9140b57cec5SDimitry Andric  typedef typename _NodeTypes::__map_value_type value_type;
9150b57cec5SDimitry Andric  typedef typename _TreeIterator::difference_type difference_type;
9160b57cec5SDimitry Andric  typedef const value_type& reference;
9170b57cec5SDimitry Andric  typedef typename _NodeTypes::__const_map_value_type_pointer pointer;
9180b57cec5SDimitry Andric
919cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_const_iterator() _NOEXCEPT {}
9200b57cec5SDimitry Andric
921cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
9225f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
923cb14a3feSDimitry Andric  __map_const_iterator(__map_iterator< typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT : __i_(__i.__i_) {}
9240b57cec5SDimitry Andric
925cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __i_->__get_value(); }
926cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__i_->__get_value()); }
9270b57cec5SDimitry Andric
928cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_const_iterator& operator++() {
929cb14a3feSDimitry Andric    ++__i_;
930cb14a3feSDimitry Andric    return *this;
931cb14a3feSDimitry Andric  }
932cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_const_iterator operator++(int) {
9330b57cec5SDimitry Andric    __map_const_iterator __t(*this);
9340b57cec5SDimitry Andric    ++(*this);
9350b57cec5SDimitry Andric    return __t;
9360b57cec5SDimitry Andric  }
9370b57cec5SDimitry Andric
938cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_const_iterator& operator--() {
939cb14a3feSDimitry Andric    --__i_;
940cb14a3feSDimitry Andric    return *this;
941cb14a3feSDimitry Andric  }
942cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __map_const_iterator operator--(int) {
9430b57cec5SDimitry Andric    __map_const_iterator __t(*this);
9440b57cec5SDimitry Andric    --(*this);
9450b57cec5SDimitry Andric    return __t;
9460b57cec5SDimitry Andric  }
9470b57cec5SDimitry Andric
948cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y) {
949cb14a3feSDimitry Andric    return __x.__i_ == __y.__i_;
950cb14a3feSDimitry Andric  }
951cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y) {
952cb14a3feSDimitry Andric    return __x.__i_ != __y.__i_;
953cb14a3feSDimitry Andric  }
9540b57cec5SDimitry Andric
955cb14a3feSDimitry Andric  template <class, class, class, class>
956cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS map;
957cb14a3feSDimitry Andric  template <class, class, class, class>
958cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS multimap;
959cb14a3feSDimitry Andric  template <class, class, class>
960cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator;
9610b57cec5SDimitry Andric};
9620b57cec5SDimitry Andric
963cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > >
964cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS map {
9650b57cec5SDimitry Andricpublic:
9660b57cec5SDimitry Andric  // types:
9670b57cec5SDimitry Andric  typedef _Key key_type;
9680b57cec5SDimitry Andric  typedef _Tp mapped_type;
9690b57cec5SDimitry Andric  typedef pair<const key_type, mapped_type> value_type;
97081ad6265SDimitry Andric  typedef __type_identity_t<_Compare> key_compare;
97181ad6265SDimitry Andric  typedef __type_identity_t<_Allocator> allocator_type;
9720b57cec5SDimitry Andric  typedef value_type& reference;
9730b57cec5SDimitry Andric  typedef const value_type& const_reference;
9740b57cec5SDimitry Andric
975*0fca6ea1SDimitry Andric  static_assert(is_same<typename allocator_type::value_type, value_type>::value,
9760b57cec5SDimitry Andric                "Allocator::value_type must be same type as value_type");
9770b57cec5SDimitry Andric
978cb14a3feSDimitry Andric  class _LIBCPP_TEMPLATE_VIS value_compare : public __binary_function<value_type, value_type, bool> {
9790b57cec5SDimitry Andric    friend class map;
980cb14a3feSDimitry Andric
9810b57cec5SDimitry Andric  protected:
9820b57cec5SDimitry Andric    key_compare comp;
9830b57cec5SDimitry Andric
9845f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : comp(__c) {}
985cb14a3feSDimitry Andric
9860b57cec5SDimitry Andric  public:
987cb14a3feSDimitry Andric    _LIBCPP_HIDE_FROM_ABI bool operator()(const value_type& __x, const value_type& __y) const {
988cb14a3feSDimitry Andric      return comp(__x.first, __y.first);
989cb14a3feSDimitry Andric    }
9900b57cec5SDimitry Andric  };
9910b57cec5SDimitry Andric
9920b57cec5SDimitry Andricprivate:
9935f757f3fSDimitry Andric  typedef std::__value_type<key_type, mapped_type> __value_type;
9940b57cec5SDimitry Andric  typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
995bdd1243dSDimitry Andric  typedef __rebind_alloc<allocator_traits<allocator_type>, __value_type> __allocator_type;
9960b57cec5SDimitry Andric  typedef __tree<__value_type, __vc, __allocator_type> __base;
9970b57cec5SDimitry Andric  typedef typename __base::__node_traits __node_traits;
9980b57cec5SDimitry Andric  typedef allocator_traits<allocator_type> __alloc_traits;
9990b57cec5SDimitry Andric
1000*0fca6ea1SDimitry Andric  static_assert(__check_valid_allocator<allocator_type>::value, "");
1001bdd1243dSDimitry Andric
10020b57cec5SDimitry Andric  __base __tree_;
10030b57cec5SDimitry Andric
10040b57cec5SDimitry Andricpublic:
10050b57cec5SDimitry Andric  typedef typename __alloc_traits::pointer pointer;
10060b57cec5SDimitry Andric  typedef typename __alloc_traits::const_pointer const_pointer;
10070b57cec5SDimitry Andric  typedef typename __alloc_traits::size_type size_type;
10080b57cec5SDimitry Andric  typedef typename __alloc_traits::difference_type difference_type;
10090b57cec5SDimitry Andric  typedef __map_iterator<typename __base::iterator> iterator;
10100b57cec5SDimitry Andric  typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
10115f757f3fSDimitry Andric  typedef std::reverse_iterator<iterator> reverse_iterator;
10125f757f3fSDimitry Andric  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
10130b57cec5SDimitry Andric
101406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
10150b57cec5SDimitry Andric  typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
10160b57cec5SDimitry Andric  typedef __insert_return_type<iterator, node_type> insert_return_type;
10170b57cec5SDimitry Andric#endif
10180b57cec5SDimitry Andric
10190b57cec5SDimitry Andric  template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
10200b57cec5SDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS map;
10210b57cec5SDimitry Andric  template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
10220b57cec5SDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS multimap;
10230b57cec5SDimitry Andric
1024cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map() _NOEXCEPT_(
1025cb14a3feSDimitry Andric      is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&
10260b57cec5SDimitry Andric          is_nothrow_copy_constructible<key_compare>::value)
10270b57cec5SDimitry Andric      : __tree_(__vc(key_compare())) {}
10280b57cec5SDimitry Andric
1029cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit map(const key_compare& __comp) _NOEXCEPT_(
1030cb14a3feSDimitry Andric      is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_copy_constructible<key_compare>::value)
10310b57cec5SDimitry Andric      : __tree_(__vc(__comp)) {}
10320b57cec5SDimitry Andric
1033cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit map(const key_compare& __comp, const allocator_type& __a)
10340b57cec5SDimitry Andric      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}
10350b57cec5SDimitry Andric
10360b57cec5SDimitry Andric  template <class _InputIterator>
1037cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map(_InputIterator __f, _InputIterator __l, const key_compare& __comp = key_compare())
1038cb14a3feSDimitry Andric      : __tree_(__vc(__comp)) {
10390b57cec5SDimitry Andric    insert(__f, __l);
10400b57cec5SDimitry Andric  }
10410b57cec5SDimitry Andric
10420b57cec5SDimitry Andric  template <class _InputIterator>
10435f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
1044cb14a3feSDimitry Andric  map(_InputIterator __f, _InputIterator __l, const key_compare& __comp, const allocator_type& __a)
1045cb14a3feSDimitry Andric      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
10460b57cec5SDimitry Andric    insert(__f, __l);
10470b57cec5SDimitry Andric  }
10480b57cec5SDimitry Andric
104906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
105006c3fb27SDimitry Andric  template <_ContainerCompatibleRange<value_type> _Range>
105106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI
1052cb14a3feSDimitry Andric  map(from_range_t,
1053cb14a3feSDimitry Andric      _Range&& __range,
1054cb14a3feSDimitry Andric      const key_compare& __comp = key_compare(),
105506c3fb27SDimitry Andric      const allocator_type& __a = allocator_type())
105606c3fb27SDimitry Andric      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
105706c3fb27SDimitry Andric    insert_range(std::forward<_Range>(__range));
105806c3fb27SDimitry Andric  }
105906c3fb27SDimitry Andric#endif
106006c3fb27SDimitry Andric
106106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
10620b57cec5SDimitry Andric  template <class _InputIterator>
1063cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
10640b57cec5SDimitry Andric      : map(__f, __l, key_compare(), __a) {}
10650b57cec5SDimitry Andric#endif
10660b57cec5SDimitry Andric
106706c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
106806c3fb27SDimitry Andric  template <_ContainerCompatibleRange<value_type> _Range>
1069cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map(from_range_t, _Range&& __range, const allocator_type& __a)
107006c3fb27SDimitry Andric      : map(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
107106c3fb27SDimitry Andric#endif
107206c3fb27SDimitry Andric
1073cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map(const map& __m) : __tree_(__m.__tree_) { insert(__m.begin(), __m.end()); }
10740b57cec5SDimitry Andric
1075cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map& operator=(const map& __m) {
10760b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10770b57cec5SDimitry Andric    __tree_ = __m.__tree_;
10780b57cec5SDimitry Andric#else
10795f757f3fSDimitry Andric    if (this != std::addressof(__m)) {
10800b57cec5SDimitry Andric      __tree_.clear();
10810b57cec5SDimitry Andric      __tree_.value_comp() = __m.__tree_.value_comp();
10820b57cec5SDimitry Andric      __tree_.__copy_assign_alloc(__m.__tree_);
10830b57cec5SDimitry Andric      insert(__m.begin(), __m.end());
10840b57cec5SDimitry Andric    }
10850b57cec5SDimitry Andric#endif
10860b57cec5SDimitry Andric    return *this;
10870b57cec5SDimitry Andric  }
10880b57cec5SDimitry Andric
10890b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10900b57cec5SDimitry Andric
1091*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI map(map&& __m) noexcept(is_nothrow_move_constructible<__base>::value)
1092cb14a3feSDimitry Andric      : __tree_(std::move(__m.__tree_)) {}
10930b57cec5SDimitry Andric
109406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a);
10950b57cec5SDimitry Andric
1096*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI map& operator=(map&& __m) noexcept(is_nothrow_move_assignable<__base>::value) {
10975f757f3fSDimitry Andric    __tree_ = std::move(__m.__tree_);
10980b57cec5SDimitry Andric    return *this;
10990b57cec5SDimitry Andric  }
11000b57cec5SDimitry Andric
1101cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
1102cb14a3feSDimitry Andric      : __tree_(__vc(__comp)) {
11030b57cec5SDimitry Andric    insert(__il.begin(), __il.end());
11040b57cec5SDimitry Andric  }
11050b57cec5SDimitry Andric
1106cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
1107cb14a3feSDimitry Andric      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
11080b57cec5SDimitry Andric    insert(__il.begin(), __il.end());
11090b57cec5SDimitry Andric  }
11100b57cec5SDimitry Andric
111106c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 14
1112cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const allocator_type& __a)
11130b57cec5SDimitry Andric      : map(__il, key_compare(), __a) {}
11140b57cec5SDimitry Andric#  endif
11150b57cec5SDimitry Andric
1116cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map& operator=(initializer_list<value_type> __il) {
11170b57cec5SDimitry Andric    __tree_.__assign_unique(__il.begin(), __il.end());
11180b57cec5SDimitry Andric    return *this;
11190b57cec5SDimitry Andric  }
11200b57cec5SDimitry Andric
11210b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
11220b57cec5SDimitry Andric
1123cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit map(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {}
11240b57cec5SDimitry Andric
1125cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI map(const map& __m, const allocator_type& __a)
1126cb14a3feSDimitry Andric      : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) {
11270b57cec5SDimitry Andric    insert(__m.begin(), __m.end());
11280b57cec5SDimitry Andric  }
11290b57cec5SDimitry Andric
1130cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~map() { static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
11310b57cec5SDimitry Andric
1132cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1133cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1134cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1135cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
11360b57cec5SDimitry Andric
1137cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1138cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
1139cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1140cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
11410b57cec5SDimitry Andric
1142cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1143cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1144cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1145cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
11460b57cec5SDimitry Andric
1147*0fca6ea1SDimitry Andric  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
1148cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1149cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
11500b57cec5SDimitry Andric
115106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
11520b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
115306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
11540b57cec5SDimitry Andric#endif
11550b57cec5SDimitry Andric
115606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
115706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
11580b57cec5SDimitry Andric
1159cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(__tree_.__alloc()); }
1160cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }
1161cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__tree_.value_comp().key_comp()); }
11620b57cec5SDimitry Andric
11630b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
11640b57cec5SDimitry Andric  template <class... _Args>
1165cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> emplace(_Args&&... __args) {
11665f757f3fSDimitry Andric    return __tree_.__emplace_unique(std::forward<_Args>(__args)...);
11670b57cec5SDimitry Andric  }
11680b57cec5SDimitry Andric
11690b57cec5SDimitry Andric  template <class... _Args>
1170cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
11715f757f3fSDimitry Andric    return __tree_.__emplace_hint_unique(__p.__i_, std::forward<_Args>(__args)...);
11720b57cec5SDimitry Andric  }
11730b57cec5SDimitry Andric
1174*0fca6ea1SDimitry Andric  template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
1175cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(_Pp&& __p) {
1176cb14a3feSDimitry Andric    return __tree_.__insert_unique(std::forward<_Pp>(__p));
1177cb14a3feSDimitry Andric  }
11780b57cec5SDimitry Andric
1179*0fca6ea1SDimitry Andric  template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
1180cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, _Pp&& __p) {
1181cb14a3feSDimitry Andric    return __tree_.__insert_unique(__pos.__i_, std::forward<_Pp>(__p));
1182cb14a3feSDimitry Andric  }
11830b57cec5SDimitry Andric
11840b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
11850b57cec5SDimitry Andric
1186cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__insert_unique(__v); }
11870b57cec5SDimitry Andric
1188cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
1189cb14a3feSDimitry Andric    return __tree_.__insert_unique(__p.__i_, __v);
1190cb14a3feSDimitry Andric  }
11910b57cec5SDimitry Andric
11920b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1193cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(value_type&& __v) {
1194cb14a3feSDimitry Andric    return __tree_.__insert_unique(std::move(__v));
1195cb14a3feSDimitry Andric  }
11960b57cec5SDimitry Andric
1197cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
1198cb14a3feSDimitry Andric    return __tree_.__insert_unique(__p.__i_, std::move(__v));
1199cb14a3feSDimitry Andric  }
12000b57cec5SDimitry Andric
1201cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
12020b57cec5SDimitry Andric#endif
12030b57cec5SDimitry Andric
12040b57cec5SDimitry Andric  template <class _InputIterator>
1205cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
12060b57cec5SDimitry Andric    for (const_iterator __e = cend(); __f != __l; ++__f)
12070b57cec5SDimitry Andric      insert(__e.__i_, *__f);
12080b57cec5SDimitry Andric  }
12090b57cec5SDimitry Andric
121006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
121106c3fb27SDimitry Andric  template <_ContainerCompatibleRange<value_type> _Range>
1212cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
121306c3fb27SDimitry Andric    const_iterator __end = cend();
121406c3fb27SDimitry Andric    for (auto&& __element : __range) {
121506c3fb27SDimitry Andric      insert(__end.__i_, std::forward<decltype(__element)>(__element));
121606c3fb27SDimitry Andric    }
121706c3fb27SDimitry Andric  }
121806c3fb27SDimitry Andric#endif
121906c3fb27SDimitry Andric
122006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
12210b57cec5SDimitry Andric
12220b57cec5SDimitry Andric  template <class... _Args>
1223cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) {
1224cb14a3feSDimitry Andric    return __tree_.__emplace_unique_key_args(
1225cb14a3feSDimitry Andric        __k,
12265f757f3fSDimitry Andric        std::piecewise_construct,
12275f757f3fSDimitry Andric        std::forward_as_tuple(__k),
12285f757f3fSDimitry Andric        std::forward_as_tuple(std::forward<_Args>(__args)...));
12290b57cec5SDimitry Andric  }
12300b57cec5SDimitry Andric
12310b57cec5SDimitry Andric  template <class... _Args>
1232cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) {
1233cb14a3feSDimitry Andric    return __tree_.__emplace_unique_key_args(
1234cb14a3feSDimitry Andric        __k,
12355f757f3fSDimitry Andric        std::piecewise_construct,
12365f757f3fSDimitry Andric        std::forward_as_tuple(std::move(__k)),
12375f757f3fSDimitry Andric        std::forward_as_tuple(std::forward<_Args>(__args)...));
12380b57cec5SDimitry Andric  }
12390b57cec5SDimitry Andric
12400b57cec5SDimitry Andric  template <class... _Args>
1241cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) {
1242cb14a3feSDimitry Andric    return __tree_
1243cb14a3feSDimitry Andric        .__emplace_hint_unique_key_args(
1244cb14a3feSDimitry Andric            __h.__i_,
1245cb14a3feSDimitry Andric            __k,
12465f757f3fSDimitry Andric            std::piecewise_construct,
12475f757f3fSDimitry Andric            std::forward_as_tuple(__k),
1248cb14a3feSDimitry Andric            std::forward_as_tuple(std::forward<_Args>(__args)...))
1249cb14a3feSDimitry Andric        .first;
12500b57cec5SDimitry Andric  }
12510b57cec5SDimitry Andric
12520b57cec5SDimitry Andric  template <class... _Args>
1253cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) {
1254cb14a3feSDimitry Andric    return __tree_
1255cb14a3feSDimitry Andric        .__emplace_hint_unique_key_args(
1256cb14a3feSDimitry Andric            __h.__i_,
1257cb14a3feSDimitry Andric            __k,
12585f757f3fSDimitry Andric            std::piecewise_construct,
12595f757f3fSDimitry Andric            std::forward_as_tuple(std::move(__k)),
1260cb14a3feSDimitry Andric            std::forward_as_tuple(std::forward<_Args>(__args)...))
1261cb14a3feSDimitry Andric        .first;
12620b57cec5SDimitry Andric  }
12630b57cec5SDimitry Andric
12640b57cec5SDimitry Andric  template <class _Vp>
1265cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v) {
12660b57cec5SDimitry Andric    iterator __p = lower_bound(__k);
1267cb14a3feSDimitry Andric    if (__p != end() && !key_comp()(__k, __p->first)) {
12685f757f3fSDimitry Andric      __p->second = std::forward<_Vp>(__v);
12695f757f3fSDimitry Andric      return std::make_pair(__p, false);
12700b57cec5SDimitry Andric    }
12715f757f3fSDimitry Andric    return std::make_pair(emplace_hint(__p, __k, std::forward<_Vp>(__v)), true);
12720b57cec5SDimitry Andric  }
12730b57cec5SDimitry Andric
12740b57cec5SDimitry Andric  template <class _Vp>
1275cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v) {
12760b57cec5SDimitry Andric    iterator __p = lower_bound(__k);
1277cb14a3feSDimitry Andric    if (__p != end() && !key_comp()(__k, __p->first)) {
12785f757f3fSDimitry Andric      __p->second = std::forward<_Vp>(__v);
12795f757f3fSDimitry Andric      return std::make_pair(__p, false);
12800b57cec5SDimitry Andric    }
12815f757f3fSDimitry Andric    return std::make_pair(emplace_hint(__p, std::move(__k), std::forward<_Vp>(__v)), true);
12820b57cec5SDimitry Andric  }
12830b57cec5SDimitry Andric
12840b57cec5SDimitry Andric  template <class _Vp>
1285cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v) {
1286cb14a3feSDimitry Andric    auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, __k, std::forward<_Vp>(__v));
1287e8d8bef9SDimitry Andric
1288e8d8bef9SDimitry Andric    if (!__inserted)
12895f757f3fSDimitry Andric      __r->__get_value().second = std::forward<_Vp>(__v);
1290e8d8bef9SDimitry Andric
1291e8d8bef9SDimitry Andric    return __r;
12920b57cec5SDimitry Andric  }
12930b57cec5SDimitry Andric
12940b57cec5SDimitry Andric  template <class _Vp>
1295cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v) {
1296cb14a3feSDimitry Andric    auto [__r, __inserted] =
1297cb14a3feSDimitry Andric        __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, std::move(__k), std::forward<_Vp>(__v));
1298e8d8bef9SDimitry Andric
1299e8d8bef9SDimitry Andric    if (!__inserted)
13005f757f3fSDimitry Andric      __r->__get_value().second = std::forward<_Vp>(__v);
1301e8d8bef9SDimitry Andric
1302e8d8bef9SDimitry Andric    return __r;
13030b57cec5SDimitry Andric  }
13040b57cec5SDimitry Andric
130506c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 17
13060b57cec5SDimitry Andric
1307cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p.__i_); }
1308cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __p) { return __tree_.erase(__p.__i_); }
1309cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_unique(__k); }
1310cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) {
1311cb14a3feSDimitry Andric    return __tree_.erase(__f.__i_, __l.__i_);
1312cb14a3feSDimitry Andric  }
1313cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }
13140b57cec5SDimitry Andric
131506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
1316cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI insert_return_type insert(node_type&& __nh) {
131706c3fb27SDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
13180b57cec5SDimitry Andric                                        "node_type with incompatible allocator passed to map::insert()");
1319cb14a3feSDimitry Andric    return __tree_.template __node_handle_insert_unique< node_type, insert_return_type>(std::move(__nh));
13200b57cec5SDimitry Andric  }
1321cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {
132206c3fb27SDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
13230b57cec5SDimitry Andric                                        "node_type with incompatible allocator passed to map::insert()");
1324cb14a3feSDimitry Andric    return __tree_.template __node_handle_insert_unique<node_type>(__hint.__i_, std::move(__nh));
13250b57cec5SDimitry Andric  }
1326cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
13270b57cec5SDimitry Andric    return __tree_.template __node_handle_extract<node_type>(__key);
13280b57cec5SDimitry Andric  }
1329cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
13300b57cec5SDimitry Andric    return __tree_.template __node_handle_extract<node_type>(__it.__i_);
13310b57cec5SDimitry Andric  }
13320b57cec5SDimitry Andric  template <class _Compare2>
1333cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) {
1334cb14a3feSDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1335cb14a3feSDimitry Andric        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
13360b57cec5SDimitry Andric    __tree_.__node_handle_merge_unique(__source.__tree_);
13370b57cec5SDimitry Andric  }
13380b57cec5SDimitry Andric  template <class _Compare2>
1339cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) {
1340cb14a3feSDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1341cb14a3feSDimitry Andric        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
13420b57cec5SDimitry Andric    __tree_.__node_handle_merge_unique(__source.__tree_);
13430b57cec5SDimitry Andric  }
13440b57cec5SDimitry Andric  template <class _Compare2>
1345cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) {
1346cb14a3feSDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1347cb14a3feSDimitry Andric        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
13480b57cec5SDimitry Andric    __tree_.__node_handle_merge_unique(__source.__tree_);
13490b57cec5SDimitry Andric  }
13500b57cec5SDimitry Andric  template <class _Compare2>
1351cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) {
1352cb14a3feSDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1353cb14a3feSDimitry Andric        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
13540b57cec5SDimitry Andric    __tree_.__node_handle_merge_unique(__source.__tree_);
13550b57cec5SDimitry Andric  }
13560b57cec5SDimitry Andric#endif
13570b57cec5SDimitry Andric
1358*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(map& __m) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) { __tree_.swap(__m.__tree_); }
13590b57cec5SDimitry Andric
1360cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1361cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
136206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
1363*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1364cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1365cb14a3feSDimitry Andric    return __tree_.find(__k);
1366cb14a3feSDimitry Andric  }
1367*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1368cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1369cb14a3feSDimitry Andric    return __tree_.find(__k);
1370cb14a3feSDimitry Andric  }
13710b57cec5SDimitry Andric#endif
13720b57cec5SDimitry Andric
1373cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_unique(__k); }
137406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
1375*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1376cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1377cb14a3feSDimitry Andric    return __tree_.__count_multi(__k);
1378cb14a3feSDimitry Andric  }
13790b57cec5SDimitry Andric#endif
13800b57cec5SDimitry Andric
138106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20
1382cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1383*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1384cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1385cb14a3feSDimitry Andric    return find(__k) != end();
1386cb14a3feSDimitry Andric  }
138706c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20
13880b57cec5SDimitry Andric
1389cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
1390cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
139106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
1392*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1393cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1394cb14a3feSDimitry Andric    return __tree_.lower_bound(__k);
1395cb14a3feSDimitry Andric  }
13960b57cec5SDimitry Andric
1397*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1398cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1399cb14a3feSDimitry Andric    return __tree_.lower_bound(__k);
1400cb14a3feSDimitry Andric  }
14010b57cec5SDimitry Andric#endif
14020b57cec5SDimitry Andric
1403cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
1404cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
140506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
1406*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1407cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1408cb14a3feSDimitry Andric    return __tree_.upper_bound(__k);
1409cb14a3feSDimitry Andric  }
1410*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1411cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1412cb14a3feSDimitry Andric    return __tree_.upper_bound(__k);
1413cb14a3feSDimitry Andric  }
14140b57cec5SDimitry Andric#endif
14150b57cec5SDimitry Andric
1416cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
1417cb14a3feSDimitry Andric    return __tree_.__equal_range_unique(__k);
1418cb14a3feSDimitry Andric  }
1419cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
1420cb14a3feSDimitry Andric    return __tree_.__equal_range_unique(__k);
1421cb14a3feSDimitry Andric  }
142206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
1423*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1424cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
1425cb14a3feSDimitry Andric    return __tree_.__equal_range_multi(__k);
1426cb14a3feSDimitry Andric  }
1427*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1428cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
1429cb14a3feSDimitry Andric    return __tree_.__equal_range_multi(__k);
1430cb14a3feSDimitry Andric  }
14310b57cec5SDimitry Andric#endif
14320b57cec5SDimitry Andric
14330b57cec5SDimitry Andricprivate:
14340b57cec5SDimitry Andric  typedef typename __base::__node __node;
14350b57cec5SDimitry Andric  typedef typename __base::__node_allocator __node_allocator;
14360b57cec5SDimitry Andric  typedef typename __base::__node_pointer __node_pointer;
14370b57cec5SDimitry Andric  typedef typename __base::__node_base_pointer __node_base_pointer;
14380b57cec5SDimitry Andric  typedef typename __base::__parent_pointer __parent_pointer;
14390b57cec5SDimitry Andric
14400b57cec5SDimitry Andric  typedef __map_node_destructor<__node_allocator> _Dp;
14410b57cec5SDimitry Andric  typedef unique_ptr<__node, _Dp> __node_holder;
14420b57cec5SDimitry Andric
14430b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
144406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_with_key(const key_type& __k);
14450b57cec5SDimitry Andric#endif
14460b57cec5SDimitry Andric};
14470b57cec5SDimitry Andric
1448349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17
1449cb14a3feSDimitry Andrictemplate <class _InputIterator,
1450cb14a3feSDimitry Andric          class _Compare   = less<__iter_key_type<_InputIterator>>,
14510b57cec5SDimitry Andric          class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
145206c3fb27SDimitry Andric          class            = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1453349cc55cSDimitry Andric          class            = enable_if_t<!__is_allocator<_Compare>::value, void>,
1454349cc55cSDimitry Andric          class            = enable_if_t<__is_allocator<_Allocator>::value, void>>
14550b57cec5SDimitry Andricmap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
14560b57cec5SDimitry Andric    -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
14570b57cec5SDimitry Andric
145806c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 23
1459cb14a3feSDimitry Andrictemplate <ranges::input_range _Range,
1460cb14a3feSDimitry Andric          class _Compare   = less<__range_key_type<_Range>>,
146106c3fb27SDimitry Andric          class _Allocator = allocator<__range_to_alloc_type<_Range>>,
146206c3fb27SDimitry Andric          class            = enable_if_t<!__is_allocator<_Compare>::value, void>,
146306c3fb27SDimitry Andric          class            = enable_if_t<__is_allocator<_Allocator>::value, void>>
146406c3fb27SDimitry Andricmap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
146506c3fb27SDimitry Andric    -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
146606c3fb27SDimitry Andric#  endif
146706c3fb27SDimitry Andric
1468cb14a3feSDimitry Andrictemplate <class _Key,
1469cb14a3feSDimitry Andric          class _Tp,
1470cb14a3feSDimitry Andric          class _Compare   = less<remove_const_t<_Key>>,
14710b57cec5SDimitry Andric          class _Allocator = allocator<pair<const _Key, _Tp>>,
1472349cc55cSDimitry Andric          class            = enable_if_t<!__is_allocator<_Compare>::value, void>,
1473349cc55cSDimitry Andric          class            = enable_if_t<__is_allocator<_Allocator>::value, void>>
1474*0fca6ea1SDimitry Andricmap(initializer_list<pair<_Key, _Tp>>,
1475*0fca6ea1SDimitry Andric    _Compare   = _Compare(),
1476*0fca6ea1SDimitry Andric    _Allocator = _Allocator()) -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
14770b57cec5SDimitry Andric
1478cb14a3feSDimitry Andrictemplate <class _InputIterator,
1479cb14a3feSDimitry Andric          class _Allocator,
148006c3fb27SDimitry Andric          class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
1481349cc55cSDimitry Andric          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
14820b57cec5SDimitry Andricmap(_InputIterator, _InputIterator, _Allocator)
1483cb14a3feSDimitry Andric    -> map<__iter_key_type<_InputIterator>,
1484cb14a3feSDimitry Andric           __iter_mapped_type<_InputIterator>,
1485cb14a3feSDimitry Andric           less<__iter_key_type<_InputIterator>>,
1486cb14a3feSDimitry Andric           _Allocator>;
14870b57cec5SDimitry Andric
148806c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 23
1489cb14a3feSDimitry Andrictemplate <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
149006c3fb27SDimitry Andricmap(from_range_t, _Range&&, _Allocator)
149106c3fb27SDimitry Andric    -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
149206c3fb27SDimitry Andric#  endif
149306c3fb27SDimitry Andric
1494cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
1495*0fca6ea1SDimitry Andricmap(initializer_list<pair<_Key, _Tp>>,
1496*0fca6ea1SDimitry Andric    _Allocator) -> map<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
14970b57cec5SDimitry Andric#endif
14980b57cec5SDimitry Andric
14990b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
15000b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
15010b57cec5SDimitry Andricmap<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
1502cb14a3feSDimitry Andric    : __tree_(std::move(__m.__tree_), typename __base::allocator_type(__a)) {
1503cb14a3feSDimitry Andric  if (__a != __m.get_allocator()) {
15040b57cec5SDimitry Andric    const_iterator __e = cend();
15050b57cec5SDimitry Andric    while (!__m.empty())
1506cb14a3feSDimitry Andric      __tree_.__insert_unique(__e.__i_, __m.__tree_.remove(__m.begin().__i_)->__value_.__move());
15070b57cec5SDimitry Andric  }
15080b57cec5SDimitry Andric}
15090b57cec5SDimitry Andric
15100b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1511cb14a3feSDimitry Andric_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
1512cb14a3feSDimitry Andric  return __tree_
1513cb14a3feSDimitry Andric      .__emplace_unique_key_args(__k, std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple())
1514cb14a3feSDimitry Andric      .first->__get_value()
1515cb14a3feSDimitry Andric      .second;
15160b57cec5SDimitry Andric}
15170b57cec5SDimitry Andric
15180b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1519cb14a3feSDimitry Andric_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) {
15205f757f3fSDimitry Andric  // TODO investigate this clang-tidy warning.
1521cb14a3feSDimitry Andric  // NOLINTBEGIN(bugprone-use-after-move)
1522cb14a3feSDimitry Andric  return __tree_
1523cb14a3feSDimitry Andric      .__emplace_unique_key_args(
1524cb14a3feSDimitry Andric          __k, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple())
1525cb14a3feSDimitry Andric      .first->__get_value()
1526cb14a3feSDimitry Andric      .second;
1527cb14a3feSDimitry Andric  // NOLINTEND(bugprone-use-after-move)
15280b57cec5SDimitry Andric}
15290b57cec5SDimitry Andric
15300b57cec5SDimitry Andric#else // _LIBCPP_CXX03_LANG
15310b57cec5SDimitry Andric
15320b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
15330b57cec5SDimitry Andrictypename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1534cb14a3feSDimitry Andricmap<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k) {
15350b57cec5SDimitry Andric  __node_allocator& __na = __tree_.__node_alloc();
15360b57cec5SDimitry Andric  __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
15375f757f3fSDimitry Andric  __node_traits::construct(__na, std::addressof(__h->__value_.__get_value().first), __k);
15380b57cec5SDimitry Andric  __h.get_deleter().__first_constructed = true;
15395f757f3fSDimitry Andric  __node_traits::construct(__na, std::addressof(__h->__value_.__get_value().second));
15400b57cec5SDimitry Andric  __h.get_deleter().__second_constructed = true;
1541e8d8bef9SDimitry Andric  return __h;
15420b57cec5SDimitry Andric}
15430b57cec5SDimitry Andric
15440b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1545cb14a3feSDimitry Andric_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
15460b57cec5SDimitry Andric  __parent_pointer __parent;
15470b57cec5SDimitry Andric  __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
15480b57cec5SDimitry Andric  __node_pointer __r           = static_cast<__node_pointer>(__child);
1549cb14a3feSDimitry Andric  if (__child == nullptr) {
15500b57cec5SDimitry Andric    __node_holder __h = __construct_node_with_key(__k);
15510b57cec5SDimitry Andric    __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
15520b57cec5SDimitry Andric    __r = __h.release();
15530b57cec5SDimitry Andric  }
15540b57cec5SDimitry Andric  return __r->__value_.__get_value().second;
15550b57cec5SDimitry Andric}
15560b57cec5SDimitry Andric
15570b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
15580b57cec5SDimitry Andric
15590b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1560cb14a3feSDimitry Andric_Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) {
15610b57cec5SDimitry Andric  __parent_pointer __parent;
15620b57cec5SDimitry Andric  __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
15630b57cec5SDimitry Andric  if (__child == nullptr)
15640b57cec5SDimitry Andric    __throw_out_of_range("map::at:  key not found");
15650b57cec5SDimitry Andric  return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
15660b57cec5SDimitry Andric}
15670b57cec5SDimitry Andric
15680b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1569cb14a3feSDimitry Andricconst _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const {
15700b57cec5SDimitry Andric  __parent_pointer __parent;
15710b57cec5SDimitry Andric  __node_base_pointer __child = __tree_.__find_equal(__parent, __k);
15720b57cec5SDimitry Andric  if (__child == nullptr)
15730b57cec5SDimitry Andric    __throw_out_of_range("map::at:  key not found");
15740b57cec5SDimitry Andric  return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
15750b57cec5SDimitry Andric}
15760b57cec5SDimitry Andric
15770b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1578cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1579cb14a3feSDimitry Andricoperator==(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
15805f757f3fSDimitry Andric  return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
15810b57cec5SDimitry Andric}
15820b57cec5SDimitry Andric
158306c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17
158406c3fb27SDimitry Andric
15850b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1586cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1587cb14a3feSDimitry Andricoperator<(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
15885f757f3fSDimitry Andric  return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
15890b57cec5SDimitry Andric}
15900b57cec5SDimitry Andric
15910b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1592cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1593cb14a3feSDimitry Andricoperator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
15940b57cec5SDimitry Andric  return !(__x == __y);
15950b57cec5SDimitry Andric}
15960b57cec5SDimitry Andric
15970b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1598cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1599cb14a3feSDimitry Andricoperator>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
16000b57cec5SDimitry Andric  return __y < __x;
16010b57cec5SDimitry Andric}
16020b57cec5SDimitry Andric
16030b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1604cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1605cb14a3feSDimitry Andricoperator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
16060b57cec5SDimitry Andric  return !(__x < __y);
16070b57cec5SDimitry Andric}
16080b57cec5SDimitry Andric
16090b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1610cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1611cb14a3feSDimitry Andricoperator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
16120b57cec5SDimitry Andric  return !(__y < __x);
16130b57cec5SDimitry Andric}
16140b57cec5SDimitry Andric
161506c3fb27SDimitry Andric#else // #if _LIBCPP_STD_VER <= 17
161606c3fb27SDimitry Andric
161706c3fb27SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
161806c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
161906c3fb27SDimitry Andricoperator<=>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
1620*0fca6ea1SDimitry Andric  return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
162106c3fb27SDimitry Andric}
162206c3fb27SDimitry Andric
162306c3fb27SDimitry Andric#endif // #if _LIBCPP_STD_VER <= 17
162406c3fb27SDimitry Andric
16250b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
1626cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
1627cb14a3feSDimitry Andricswap(map<_Key, _Tp, _Compare, _Allocator>& __x, map<_Key, _Tp, _Compare, _Allocator>& __y)
1628cb14a3feSDimitry Andric    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
16290b57cec5SDimitry Andric  __x.swap(__y);
16300b57cec5SDimitry Andric}
16310b57cec5SDimitry Andric
163206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20
1633cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
1634cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename map<_Key, _Tp, _Compare, _Allocator>::size_type
16355ffd83dbSDimitry Andricerase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
16365f757f3fSDimitry Andric  return std::__libcpp_erase_if_container(__c, __pred);
16375ffd83dbSDimitry Andric}
16380b57cec5SDimitry Andric#endif
16390b57cec5SDimitry Andric
1640cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > >
1641cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS multimap {
16420b57cec5SDimitry Andricpublic:
16430b57cec5SDimitry Andric  // types:
16440b57cec5SDimitry Andric  typedef _Key key_type;
16450b57cec5SDimitry Andric  typedef _Tp mapped_type;
16460b57cec5SDimitry Andric  typedef pair<const key_type, mapped_type> value_type;
164781ad6265SDimitry Andric  typedef __type_identity_t<_Compare> key_compare;
164881ad6265SDimitry Andric  typedef __type_identity_t<_Allocator> allocator_type;
16490b57cec5SDimitry Andric  typedef value_type& reference;
16500b57cec5SDimitry Andric  typedef const value_type& const_reference;
16510b57cec5SDimitry Andric
1652*0fca6ea1SDimitry Andric  static_assert(__check_valid_allocator<allocator_type>::value, "");
1653*0fca6ea1SDimitry Andric  static_assert(is_same<typename allocator_type::value_type, value_type>::value,
16540b57cec5SDimitry Andric                "Allocator::value_type must be same type as value_type");
16550b57cec5SDimitry Andric
1656cb14a3feSDimitry Andric  class _LIBCPP_TEMPLATE_VIS value_compare : public __binary_function<value_type, value_type, bool> {
16570b57cec5SDimitry Andric    friend class multimap;
1658cb14a3feSDimitry Andric
16590b57cec5SDimitry Andric  protected:
16600b57cec5SDimitry Andric    key_compare comp;
16610b57cec5SDimitry Andric
1662cb14a3feSDimitry Andric    _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : comp(__c) {}
1663cb14a3feSDimitry Andric
16640b57cec5SDimitry Andric  public:
1665cb14a3feSDimitry Andric    _LIBCPP_HIDE_FROM_ABI bool operator()(const value_type& __x, const value_type& __y) const {
1666cb14a3feSDimitry Andric      return comp(__x.first, __y.first);
1667cb14a3feSDimitry Andric    }
16680b57cec5SDimitry Andric  };
16690b57cec5SDimitry Andric
16700b57cec5SDimitry Andricprivate:
16715f757f3fSDimitry Andric  typedef std::__value_type<key_type, mapped_type> __value_type;
16720b57cec5SDimitry Andric  typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
1673bdd1243dSDimitry Andric  typedef __rebind_alloc<allocator_traits<allocator_type>, __value_type> __allocator_type;
16740b57cec5SDimitry Andric  typedef __tree<__value_type, __vc, __allocator_type> __base;
16750b57cec5SDimitry Andric  typedef typename __base::__node_traits __node_traits;
16760b57cec5SDimitry Andric  typedef allocator_traits<allocator_type> __alloc_traits;
16770b57cec5SDimitry Andric
16780b57cec5SDimitry Andric  __base __tree_;
16790b57cec5SDimitry Andric
16800b57cec5SDimitry Andricpublic:
16810b57cec5SDimitry Andric  typedef typename __alloc_traits::pointer pointer;
16820b57cec5SDimitry Andric  typedef typename __alloc_traits::const_pointer const_pointer;
16830b57cec5SDimitry Andric  typedef typename __alloc_traits::size_type size_type;
16840b57cec5SDimitry Andric  typedef typename __alloc_traits::difference_type difference_type;
16850b57cec5SDimitry Andric  typedef __map_iterator<typename __base::iterator> iterator;
16860b57cec5SDimitry Andric  typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
16875f757f3fSDimitry Andric  typedef std::reverse_iterator<iterator> reverse_iterator;
16885f757f3fSDimitry Andric  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
16890b57cec5SDimitry Andric
169006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
16910b57cec5SDimitry Andric  typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
16920b57cec5SDimitry Andric#endif
16930b57cec5SDimitry Andric
16940b57cec5SDimitry Andric  template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
16950b57cec5SDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS map;
16960b57cec5SDimitry Andric  template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
16970b57cec5SDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS multimap;
16980b57cec5SDimitry Andric
1699cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap() _NOEXCEPT_(
1700cb14a3feSDimitry Andric      is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&
17010b57cec5SDimitry Andric          is_nothrow_copy_constructible<key_compare>::value)
17020b57cec5SDimitry Andric      : __tree_(__vc(key_compare())) {}
17030b57cec5SDimitry Andric
1704cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit multimap(const key_compare& __comp) _NOEXCEPT_(
1705cb14a3feSDimitry Andric      is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_copy_constructible<key_compare>::value)
17060b57cec5SDimitry Andric      : __tree_(__vc(__comp)) {}
17070b57cec5SDimitry Andric
1708cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit multimap(const key_compare& __comp, const allocator_type& __a)
17090b57cec5SDimitry Andric      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}
17100b57cec5SDimitry Andric
17110b57cec5SDimitry Andric  template <class _InputIterator>
1712cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap(_InputIterator __f, _InputIterator __l, const key_compare& __comp = key_compare())
1713cb14a3feSDimitry Andric      : __tree_(__vc(__comp)) {
17140b57cec5SDimitry Andric    insert(__f, __l);
17150b57cec5SDimitry Andric  }
17160b57cec5SDimitry Andric
17170b57cec5SDimitry Andric  template <class _InputIterator>
17185f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
1719cb14a3feSDimitry Andric  multimap(_InputIterator __f, _InputIterator __l, const key_compare& __comp, const allocator_type& __a)
1720cb14a3feSDimitry Andric      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
17210b57cec5SDimitry Andric    insert(__f, __l);
17220b57cec5SDimitry Andric  }
17230b57cec5SDimitry Andric
172406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
172506c3fb27SDimitry Andric  template <_ContainerCompatibleRange<value_type> _Range>
172606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI
1727cb14a3feSDimitry Andric  multimap(from_range_t,
1728cb14a3feSDimitry Andric           _Range&& __range,
1729cb14a3feSDimitry Andric           const key_compare& __comp = key_compare(),
173006c3fb27SDimitry Andric           const allocator_type& __a = allocator_type())
173106c3fb27SDimitry Andric      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
173206c3fb27SDimitry Andric    insert_range(std::forward<_Range>(__range));
173306c3fb27SDimitry Andric  }
173406c3fb27SDimitry Andric#endif
173506c3fb27SDimitry Andric
173606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
17370b57cec5SDimitry Andric  template <class _InputIterator>
1738cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
17390b57cec5SDimitry Andric      : multimap(__f, __l, key_compare(), __a) {}
17400b57cec5SDimitry Andric#endif
17410b57cec5SDimitry Andric
174206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
174306c3fb27SDimitry Andric  template <_ContainerCompatibleRange<value_type> _Range>
1744cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap(from_range_t, _Range&& __range, const allocator_type& __a)
174506c3fb27SDimitry Andric      : multimap(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
174606c3fb27SDimitry Andric#endif
174706c3fb27SDimitry Andric
1748cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m)
17490b57cec5SDimitry Andric      : __tree_(__m.__tree_.value_comp(),
1750cb14a3feSDimitry Andric                __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc())) {
17510b57cec5SDimitry Andric    insert(__m.begin(), __m.end());
17520b57cec5SDimitry Andric  }
17530b57cec5SDimitry Andric
1754cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap& operator=(const multimap& __m) {
17550b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
17560b57cec5SDimitry Andric    __tree_ = __m.__tree_;
17570b57cec5SDimitry Andric#else
17585f757f3fSDimitry Andric    if (this != std::addressof(__m)) {
17590b57cec5SDimitry Andric      __tree_.clear();
17600b57cec5SDimitry Andric      __tree_.value_comp() = __m.__tree_.value_comp();
17610b57cec5SDimitry Andric      __tree_.__copy_assign_alloc(__m.__tree_);
17620b57cec5SDimitry Andric      insert(__m.begin(), __m.end());
17630b57cec5SDimitry Andric    }
17640b57cec5SDimitry Andric#endif
17650b57cec5SDimitry Andric    return *this;
17660b57cec5SDimitry Andric  }
17670b57cec5SDimitry Andric
17680b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
17690b57cec5SDimitry Andric
1770*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m) noexcept(is_nothrow_move_constructible<__base>::value)
1771cb14a3feSDimitry Andric      : __tree_(std::move(__m.__tree_)) {}
17720b57cec5SDimitry Andric
177306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a);
17740b57cec5SDimitry Andric
1775*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap& operator=(multimap&& __m) noexcept(is_nothrow_move_assignable<__base>::value) {
17765f757f3fSDimitry Andric    __tree_ = std::move(__m.__tree_);
17770b57cec5SDimitry Andric    return *this;
17780b57cec5SDimitry Andric  }
17790b57cec5SDimitry Andric
1780cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
1781cb14a3feSDimitry Andric      : __tree_(__vc(__comp)) {
17820b57cec5SDimitry Andric    insert(__il.begin(), __il.end());
17830b57cec5SDimitry Andric  }
17840b57cec5SDimitry Andric
17855f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
17860b57cec5SDimitry Andric  multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
1787cb14a3feSDimitry Andric      : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
17880b57cec5SDimitry Andric    insert(__il.begin(), __il.end());
17890b57cec5SDimitry Andric  }
17900b57cec5SDimitry Andric
179106c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 14
1792cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap(initializer_list<value_type> __il, const allocator_type& __a)
17930b57cec5SDimitry Andric      : multimap(__il, key_compare(), __a) {}
17940b57cec5SDimitry Andric#  endif
17950b57cec5SDimitry Andric
1796cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap& operator=(initializer_list<value_type> __il) {
17970b57cec5SDimitry Andric    __tree_.__assign_multi(__il.begin(), __il.end());
17980b57cec5SDimitry Andric    return *this;
17990b57cec5SDimitry Andric  }
18000b57cec5SDimitry Andric
18010b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
18020b57cec5SDimitry Andric
1803cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit multimap(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {}
18040b57cec5SDimitry Andric
1805cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m, const allocator_type& __a)
1806cb14a3feSDimitry Andric      : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) {
18070b57cec5SDimitry Andric    insert(__m.begin(), __m.end());
18080b57cec5SDimitry Andric  }
18090b57cec5SDimitry Andric
1810cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~multimap() { static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
18110b57cec5SDimitry Andric
1812cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
1813cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
1814cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
1815cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
18160b57cec5SDimitry Andric
1817cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
1818cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }
1819cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
1820cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }
18210b57cec5SDimitry Andric
1822cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
1823cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
1824cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
1825cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
18260b57cec5SDimitry Andric
1827*0fca6ea1SDimitry Andric  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
1828cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
1829cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
18300b57cec5SDimitry Andric
1831cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(__tree_.__alloc()); }
1832cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }
1833cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__tree_.value_comp().key_comp()); }
18340b57cec5SDimitry Andric
18350b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
18360b57cec5SDimitry Andric
18370b57cec5SDimitry Andric  template <class... _Args>
1838cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {
18395f757f3fSDimitry Andric    return __tree_.__emplace_multi(std::forward<_Args>(__args)...);
18400b57cec5SDimitry Andric  }
18410b57cec5SDimitry Andric
18420b57cec5SDimitry Andric  template <class... _Args>
1843cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
18445f757f3fSDimitry Andric    return __tree_.__emplace_hint_multi(__p.__i_, std::forward<_Args>(__args)...);
18450b57cec5SDimitry Andric  }
18460b57cec5SDimitry Andric
1847*0fca6ea1SDimitry Andric  template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
1848cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(_Pp&& __p) {
1849cb14a3feSDimitry Andric    return __tree_.__insert_multi(std::forward<_Pp>(__p));
1850cb14a3feSDimitry Andric  }
18510b57cec5SDimitry Andric
1852*0fca6ea1SDimitry Andric  template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
1853cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, _Pp&& __p) {
1854cb14a3feSDimitry Andric    return __tree_.__insert_multi(__pos.__i_, std::forward<_Pp>(__p));
1855cb14a3feSDimitry Andric  }
18560b57cec5SDimitry Andric
1857cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __v) { return __tree_.__insert_multi(std::move(__v)); }
18580b57cec5SDimitry Andric
1859cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
1860cb14a3feSDimitry Andric    return __tree_.__insert_multi(__p.__i_, std::move(__v));
1861cb14a3feSDimitry Andric  }
18620b57cec5SDimitry Andric
1863cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
18640b57cec5SDimitry Andric
18650b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
18660b57cec5SDimitry Andric
1867cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __v) { return __tree_.__insert_multi(__v); }
18680b57cec5SDimitry Andric
1869cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
1870cb14a3feSDimitry Andric    return __tree_.__insert_multi(__p.__i_, __v);
1871cb14a3feSDimitry Andric  }
18720b57cec5SDimitry Andric
18730b57cec5SDimitry Andric  template <class _InputIterator>
1874cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
18750b57cec5SDimitry Andric    for (const_iterator __e = cend(); __f != __l; ++__f)
18760b57cec5SDimitry Andric      __tree_.__insert_multi(__e.__i_, *__f);
18770b57cec5SDimitry Andric  }
18780b57cec5SDimitry Andric
187906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
188006c3fb27SDimitry Andric  template <_ContainerCompatibleRange<value_type> _Range>
1881cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
188206c3fb27SDimitry Andric    const_iterator __end = cend();
188306c3fb27SDimitry Andric    for (auto&& __element : __range) {
188406c3fb27SDimitry Andric      __tree_.__insert_multi(__end.__i_, std::forward<decltype(__element)>(__element));
188506c3fb27SDimitry Andric    }
188606c3fb27SDimitry Andric  }
188706c3fb27SDimitry Andric#endif
188806c3fb27SDimitry Andric
1889cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p.__i_); }
1890cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __p) { return __tree_.erase(__p.__i_); }
1891cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_multi(__k); }
1892cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) {
1893cb14a3feSDimitry Andric    return __tree_.erase(__f.__i_, __l.__i_);
1894cb14a3feSDimitry Andric  }
18950b57cec5SDimitry Andric
189606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
1897cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(node_type&& __nh) {
189806c3fb27SDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
18990b57cec5SDimitry Andric                                        "node_type with incompatible allocator passed to multimap::insert()");
1900cb14a3feSDimitry Andric    return __tree_.template __node_handle_insert_multi<node_type>(std::move(__nh));
19010b57cec5SDimitry Andric  }
1902cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {
190306c3fb27SDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
19040b57cec5SDimitry Andric                                        "node_type with incompatible allocator passed to multimap::insert()");
1905cb14a3feSDimitry Andric    return __tree_.template __node_handle_insert_multi<node_type>(__hint.__i_, std::move(__nh));
19060b57cec5SDimitry Andric  }
1907cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
19080b57cec5SDimitry Andric    return __tree_.template __node_handle_extract<node_type>(__key);
19090b57cec5SDimitry Andric  }
1910cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
1911cb14a3feSDimitry Andric    return __tree_.template __node_handle_extract<node_type>(__it.__i_);
19120b57cec5SDimitry Andric  }
19130b57cec5SDimitry Andric  template <class _Compare2>
1914cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) {
1915cb14a3feSDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1916cb14a3feSDimitry Andric        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
19170b57cec5SDimitry Andric    return __tree_.__node_handle_merge_multi(__source.__tree_);
19180b57cec5SDimitry Andric  }
19190b57cec5SDimitry Andric  template <class _Compare2>
1920cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) {
1921cb14a3feSDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1922cb14a3feSDimitry Andric        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
19230b57cec5SDimitry Andric    return __tree_.__node_handle_merge_multi(__source.__tree_);
19240b57cec5SDimitry Andric  }
19250b57cec5SDimitry Andric  template <class _Compare2>
1926cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) {
1927cb14a3feSDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1928cb14a3feSDimitry Andric        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
19290b57cec5SDimitry Andric    return __tree_.__node_handle_merge_multi(__source.__tree_);
19300b57cec5SDimitry Andric  }
19310b57cec5SDimitry Andric  template <class _Compare2>
1932cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) {
1933cb14a3feSDimitry Andric    _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1934cb14a3feSDimitry Andric        __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
19350b57cec5SDimitry Andric    return __tree_.__node_handle_merge_multi(__source.__tree_);
19360b57cec5SDimitry Andric  }
19370b57cec5SDimitry Andric#endif
19380b57cec5SDimitry Andric
1939cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }
19400b57cec5SDimitry Andric
1941*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(multimap& __m) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) {
1942cb14a3feSDimitry Andric    __tree_.swap(__m.__tree_);
1943cb14a3feSDimitry Andric  }
19440b57cec5SDimitry Andric
1945cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
1946cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
194706c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
1948*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1949cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
1950cb14a3feSDimitry Andric    return __tree_.find(__k);
1951cb14a3feSDimitry Andric  }
1952*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1953cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
1954cb14a3feSDimitry Andric    return __tree_.find(__k);
1955cb14a3feSDimitry Andric  }
19560b57cec5SDimitry Andric#endif
19570b57cec5SDimitry Andric
1958cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_multi(__k); }
195906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
1960*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1961cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
1962cb14a3feSDimitry Andric    return __tree_.__count_multi(__k);
1963cb14a3feSDimitry Andric  }
19640b57cec5SDimitry Andric#endif
19650b57cec5SDimitry Andric
196606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20
1967cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
1968*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1969cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
1970cb14a3feSDimitry Andric    return find(__k) != end();
1971cb14a3feSDimitry Andric  }
197206c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20
19730b57cec5SDimitry Andric
1974cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.lower_bound(__k); }
1975cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const { return __tree_.lower_bound(__k); }
197606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
1977*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1978cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
1979cb14a3feSDimitry Andric    return __tree_.lower_bound(__k);
1980cb14a3feSDimitry Andric  }
19810b57cec5SDimitry Andric
1982*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1983cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
1984cb14a3feSDimitry Andric    return __tree_.lower_bound(__k);
1985cb14a3feSDimitry Andric  }
19860b57cec5SDimitry Andric#endif
19870b57cec5SDimitry Andric
1988cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.upper_bound(__k); }
1989cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const { return __tree_.upper_bound(__k); }
199006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
1991*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1992cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
1993cb14a3feSDimitry Andric    return __tree_.upper_bound(__k);
1994cb14a3feSDimitry Andric  }
1995*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
1996cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
1997cb14a3feSDimitry Andric    return __tree_.upper_bound(__k);
1998cb14a3feSDimitry Andric  }
19990b57cec5SDimitry Andric#endif
20000b57cec5SDimitry Andric
2001cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
2002cb14a3feSDimitry Andric    return __tree_.__equal_range_multi(__k);
2003cb14a3feSDimitry Andric  }
2004cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
2005cb14a3feSDimitry Andric    return __tree_.__equal_range_multi(__k);
2006cb14a3feSDimitry Andric  }
200706c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
2008*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
2009cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
2010cb14a3feSDimitry Andric    return __tree_.__equal_range_multi(__k);
2011cb14a3feSDimitry Andric  }
2012*0fca6ea1SDimitry Andric  template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>
2013cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
2014cb14a3feSDimitry Andric    return __tree_.__equal_range_multi(__k);
2015cb14a3feSDimitry Andric  }
20160b57cec5SDimitry Andric#endif
20170b57cec5SDimitry Andric
20180b57cec5SDimitry Andricprivate:
20190b57cec5SDimitry Andric  typedef typename __base::__node __node;
20200b57cec5SDimitry Andric  typedef typename __base::__node_allocator __node_allocator;
20210b57cec5SDimitry Andric  typedef typename __base::__node_pointer __node_pointer;
20220b57cec5SDimitry Andric
20230b57cec5SDimitry Andric  typedef __map_node_destructor<__node_allocator> _Dp;
20240b57cec5SDimitry Andric  typedef unique_ptr<__node, _Dp> __node_holder;
20250b57cec5SDimitry Andric};
20260b57cec5SDimitry Andric
2027349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17
2028cb14a3feSDimitry Andrictemplate <class _InputIterator,
2029cb14a3feSDimitry Andric          class _Compare   = less<__iter_key_type<_InputIterator>>,
20300b57cec5SDimitry Andric          class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,
203106c3fb27SDimitry Andric          class            = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
2032349cc55cSDimitry Andric          class            = enable_if_t<!__is_allocator<_Compare>::value, void>,
2033349cc55cSDimitry Andric          class            = enable_if_t<__is_allocator<_Allocator>::value, void>>
20340b57cec5SDimitry Andricmultimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
20350b57cec5SDimitry Andric    -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;
20360b57cec5SDimitry Andric
203706c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 23
2038cb14a3feSDimitry Andrictemplate <ranges::input_range _Range,
2039cb14a3feSDimitry Andric          class _Compare   = less<__range_key_type<_Range>>,
204006c3fb27SDimitry Andric          class _Allocator = allocator<__range_to_alloc_type<_Range>>,
204106c3fb27SDimitry Andric          class            = enable_if_t<!__is_allocator<_Compare>::value, void>,
204206c3fb27SDimitry Andric          class            = enable_if_t<__is_allocator<_Allocator>::value, void>>
204306c3fb27SDimitry Andricmultimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
204406c3fb27SDimitry Andric    -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;
204506c3fb27SDimitry Andric#  endif
204606c3fb27SDimitry Andric
2047cb14a3feSDimitry Andrictemplate <class _Key,
2048cb14a3feSDimitry Andric          class _Tp,
2049cb14a3feSDimitry Andric          class _Compare   = less<remove_const_t<_Key>>,
20500b57cec5SDimitry Andric          class _Allocator = allocator<pair<const _Key, _Tp>>,
2051349cc55cSDimitry Andric          class            = enable_if_t<!__is_allocator<_Compare>::value, void>,
2052349cc55cSDimitry Andric          class            = enable_if_t<__is_allocator<_Allocator>::value, void>>
2053*0fca6ea1SDimitry Andricmultimap(initializer_list<pair<_Key, _Tp>>,
2054*0fca6ea1SDimitry Andric         _Compare   = _Compare(),
2055*0fca6ea1SDimitry Andric         _Allocator = _Allocator()) -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;
20560b57cec5SDimitry Andric
2057cb14a3feSDimitry Andrictemplate <class _InputIterator,
2058cb14a3feSDimitry Andric          class _Allocator,
205906c3fb27SDimitry Andric          class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,
2060349cc55cSDimitry Andric          class = enable_if_t<__is_allocator<_Allocator>::value, void>>
20610b57cec5SDimitry Andricmultimap(_InputIterator, _InputIterator, _Allocator)
2062cb14a3feSDimitry Andric    -> multimap<__iter_key_type<_InputIterator>,
2063cb14a3feSDimitry Andric                __iter_mapped_type<_InputIterator>,
2064cb14a3feSDimitry Andric                less<__iter_key_type<_InputIterator>>,
2065cb14a3feSDimitry Andric                _Allocator>;
20660b57cec5SDimitry Andric
206706c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 23
2068cb14a3feSDimitry Andrictemplate <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
206906c3fb27SDimitry Andricmultimap(from_range_t, _Range&&, _Allocator)
207006c3fb27SDimitry Andric    -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;
207106c3fb27SDimitry Andric#  endif
207206c3fb27SDimitry Andric
2073cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value, void>>
2074*0fca6ea1SDimitry Andricmultimap(initializer_list<pair<_Key, _Tp>>,
2075*0fca6ea1SDimitry Andric         _Allocator) -> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;
20760b57cec5SDimitry Andric#endif
20770b57cec5SDimitry Andric
20780b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
20790b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
20800b57cec5SDimitry Andricmultimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a)
2081cb14a3feSDimitry Andric    : __tree_(std::move(__m.__tree_), typename __base::allocator_type(__a)) {
2082cb14a3feSDimitry Andric  if (__a != __m.get_allocator()) {
20830b57cec5SDimitry Andric    const_iterator __e = cend();
20840b57cec5SDimitry Andric    while (!__m.empty())
2085cb14a3feSDimitry Andric      __tree_.__insert_multi(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__move()));
20860b57cec5SDimitry Andric  }
20870b57cec5SDimitry Andric}
20880b57cec5SDimitry Andric#endif
20890b57cec5SDimitry Andric
20900b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
2091cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
2092cb14a3feSDimitry Andricoperator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
20935f757f3fSDimitry Andric  return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
20940b57cec5SDimitry Andric}
20950b57cec5SDimitry Andric
209606c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17
209706c3fb27SDimitry Andric
20980b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
2099cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
2100cb14a3feSDimitry Andricoperator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
21015f757f3fSDimitry Andric  return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
21020b57cec5SDimitry Andric}
21030b57cec5SDimitry Andric
21040b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
2105cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
2106cb14a3feSDimitry Andricoperator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
21070b57cec5SDimitry Andric  return !(__x == __y);
21080b57cec5SDimitry Andric}
21090b57cec5SDimitry Andric
21100b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
2111cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
2112cb14a3feSDimitry Andricoperator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
21130b57cec5SDimitry Andric  return __y < __x;
21140b57cec5SDimitry Andric}
21150b57cec5SDimitry Andric
21160b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
2117cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
2118cb14a3feSDimitry Andricoperator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
21190b57cec5SDimitry Andric  return !(__x < __y);
21200b57cec5SDimitry Andric}
21210b57cec5SDimitry Andric
21220b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
2123cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
2124cb14a3feSDimitry Andricoperator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
21250b57cec5SDimitry Andric  return !(__y < __x);
21260b57cec5SDimitry Andric}
21270b57cec5SDimitry Andric
212806c3fb27SDimitry Andric#else // #if _LIBCPP_STD_VER <= 17
212906c3fb27SDimitry Andric
213006c3fb27SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
213106c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
213206c3fb27SDimitry Andricoperator<=>(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
213306c3fb27SDimitry Andric            const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {
2134*0fca6ea1SDimitry Andric  return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), __synth_three_way);
213506c3fb27SDimitry Andric}
213606c3fb27SDimitry Andric
213706c3fb27SDimitry Andric#endif // #if _LIBCPP_STD_VER <= 17
213806c3fb27SDimitry Andric
21390b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator>
2140cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
2141cb14a3feSDimitry Andricswap(multimap<_Key, _Tp, _Compare, _Allocator>& __x, multimap<_Key, _Tp, _Compare, _Allocator>& __y)
2142cb14a3feSDimitry Andric    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
21430b57cec5SDimitry Andric  __x.swap(__y);
21440b57cec5SDimitry Andric}
21450b57cec5SDimitry Andric
214606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20
2147cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
2148cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type
2149cb14a3feSDimitry Andricerase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
21505f757f3fSDimitry Andric  return std::__libcpp_erase_if_container(__c, __pred);
21515ffd83dbSDimitry Andric}
21520b57cec5SDimitry Andric#endif
21530b57cec5SDimitry Andric
21540b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
21550b57cec5SDimitry Andric
215606c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
2157bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2158bdd1243dSDimitry Andricnamespace pmr {
2159bdd1243dSDimitry Andrictemplate <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
2160cb14a3feSDimitry Andricusing map _LIBCPP_AVAILABILITY_PMR =
2161cb14a3feSDimitry Andric    std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
2162bdd1243dSDimitry Andric
2163bdd1243dSDimitry Andrictemplate <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>
2164cb14a3feSDimitry Andricusing multimap _LIBCPP_AVAILABILITY_PMR =
2165cb14a3feSDimitry Andric    std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;
2166bdd1243dSDimitry Andric} // namespace pmr
2167bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD
2168bdd1243dSDimitry Andric#endif
2169bdd1243dSDimitry Andric
2170b3edf446SDimitry Andric_LIBCPP_POP_MACROS
2171b3edf446SDimitry Andric
2172bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
2173bdd1243dSDimitry Andric#  include <concepts>
217406c3fb27SDimitry Andric#  include <cstdlib>
2175bdd1243dSDimitry Andric#  include <functional>
2176bdd1243dSDimitry Andric#  include <iterator>
217706c3fb27SDimitry Andric#  include <type_traits>
2178bdd1243dSDimitry Andric#  include <utility>
2179bdd1243dSDimitry Andric#endif
2180bdd1243dSDimitry Andric
21810b57cec5SDimitry Andric#endif // _LIBCPP_MAP
2182