138fd1498Szrj // Map implementation -*- C++ -*-
238fd1498Szrj
338fd1498Szrj // Copyright (C) 2001-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj
2538fd1498Szrj /*
2638fd1498Szrj *
2738fd1498Szrj * Copyright (c) 1994
2838fd1498Szrj * Hewlett-Packard Company
2938fd1498Szrj *
3038fd1498Szrj * Permission to use, copy, modify, distribute and sell this software
3138fd1498Szrj * and its documentation for any purpose is hereby granted without fee,
3238fd1498Szrj * provided that the above copyright notice appear in all copies and
3338fd1498Szrj * that both that copyright notice and this permission notice appear
3438fd1498Szrj * in supporting documentation. Hewlett-Packard Company makes no
3538fd1498Szrj * representations about the suitability of this software for any
3638fd1498Szrj * purpose. It is provided "as is" without express or implied warranty.
3738fd1498Szrj *
3838fd1498Szrj *
3938fd1498Szrj * Copyright (c) 1996,1997
4038fd1498Szrj * Silicon Graphics Computer Systems, Inc.
4138fd1498Szrj *
4238fd1498Szrj * Permission to use, copy, modify, distribute and sell this software
4338fd1498Szrj * and its documentation for any purpose is hereby granted without fee,
4438fd1498Szrj * provided that the above copyright notice appear in all copies and
4538fd1498Szrj * that both that copyright notice and this permission notice appear
4638fd1498Szrj * in supporting documentation. Silicon Graphics makes no
4738fd1498Szrj * representations about the suitability of this software for any
4838fd1498Szrj * purpose. It is provided "as is" without express or implied warranty.
4938fd1498Szrj */
5038fd1498Szrj
5138fd1498Szrj /** @file bits/stl_map.h
5238fd1498Szrj * This is an internal header file, included by other library headers.
5338fd1498Szrj * Do not attempt to use it directly. @headername{map}
5438fd1498Szrj */
5538fd1498Szrj
5638fd1498Szrj #ifndef _STL_MAP_H
5738fd1498Szrj #define _STL_MAP_H 1
5838fd1498Szrj
5938fd1498Szrj #include <bits/functexcept.h>
6038fd1498Szrj #include <bits/concept_check.h>
6138fd1498Szrj #if __cplusplus >= 201103L
6238fd1498Szrj #include <initializer_list>
6338fd1498Szrj #include <tuple>
6438fd1498Szrj #endif
6538fd1498Szrj
_GLIBCXX_VISIBILITY(default)6638fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
6738fd1498Szrj {
6838fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
6938fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
7038fd1498Szrj
7138fd1498Szrj template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
7238fd1498Szrj class multimap;
7338fd1498Szrj
7438fd1498Szrj /**
7538fd1498Szrj * @brief A standard container made up of (key,value) pairs, which can be
7638fd1498Szrj * retrieved based on a key, in logarithmic time.
7738fd1498Szrj *
7838fd1498Szrj * @ingroup associative_containers
7938fd1498Szrj *
8038fd1498Szrj * @tparam _Key Type of key objects.
8138fd1498Szrj * @tparam _Tp Type of mapped objects.
8238fd1498Szrj * @tparam _Compare Comparison function object type, defaults to less<_Key>.
8338fd1498Szrj * @tparam _Alloc Allocator type, defaults to
8438fd1498Szrj * allocator<pair<const _Key, _Tp>.
8538fd1498Szrj *
8638fd1498Szrj * Meets the requirements of a <a href="tables.html#65">container</a>, a
8738fd1498Szrj * <a href="tables.html#66">reversible container</a>, and an
8838fd1498Szrj * <a href="tables.html#69">associative container</a> (using unique keys).
8938fd1498Szrj * For a @c map<Key,T> the key_type is Key, the mapped_type is T, and the
9038fd1498Szrj * value_type is std::pair<const Key,T>.
9138fd1498Szrj *
9238fd1498Szrj * Maps support bidirectional iterators.
9338fd1498Szrj *
9438fd1498Szrj * The private tree data is declared exactly the same way for map and
9538fd1498Szrj * multimap; the distinction is made entirely in how the tree functions are
9638fd1498Szrj * called (*_unique versus *_equal, same as the standard).
9738fd1498Szrj */
9838fd1498Szrj template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
9938fd1498Szrj typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
10038fd1498Szrj class map
10138fd1498Szrj {
10238fd1498Szrj public:
10338fd1498Szrj typedef _Key key_type;
10438fd1498Szrj typedef _Tp mapped_type;
10538fd1498Szrj typedef std::pair<const _Key, _Tp> value_type;
10638fd1498Szrj typedef _Compare key_compare;
10738fd1498Szrj typedef _Alloc allocator_type;
10838fd1498Szrj
10938fd1498Szrj private:
11038fd1498Szrj #ifdef _GLIBCXX_CONCEPT_CHECKS
11138fd1498Szrj // concept requirements
11238fd1498Szrj typedef typename _Alloc::value_type _Alloc_value_type;
11338fd1498Szrj # if __cplusplus < 201103L
11438fd1498Szrj __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
11538fd1498Szrj # endif
11638fd1498Szrj __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
11738fd1498Szrj _BinaryFunctionConcept)
11838fd1498Szrj __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
11938fd1498Szrj #endif
12038fd1498Szrj
12138fd1498Szrj #if __cplusplus >= 201103L && defined(__STRICT_ANSI__)
12238fd1498Szrj static_assert(is_same<typename _Alloc::value_type, value_type>::value,
12338fd1498Szrj "std::map must have the same value_type as its allocator");
12438fd1498Szrj #endif
12538fd1498Szrj
12638fd1498Szrj public:
12738fd1498Szrj class value_compare
12838fd1498Szrj : public std::binary_function<value_type, value_type, bool>
12938fd1498Szrj {
13038fd1498Szrj friend class map<_Key, _Tp, _Compare, _Alloc>;
13138fd1498Szrj protected:
13238fd1498Szrj _Compare comp;
13338fd1498Szrj
13438fd1498Szrj value_compare(_Compare __c)
13538fd1498Szrj : comp(__c) { }
13638fd1498Szrj
13738fd1498Szrj public:
13838fd1498Szrj bool operator()(const value_type& __x, const value_type& __y) const
13938fd1498Szrj { return comp(__x.first, __y.first); }
14038fd1498Szrj };
14138fd1498Szrj
14238fd1498Szrj private:
14338fd1498Szrj /// This turns a red-black tree into a [multi]map.
14438fd1498Szrj typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
14538fd1498Szrj rebind<value_type>::other _Pair_alloc_type;
14638fd1498Szrj
14738fd1498Szrj typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
14838fd1498Szrj key_compare, _Pair_alloc_type> _Rep_type;
14938fd1498Szrj
15038fd1498Szrj /// The actual tree structure.
15138fd1498Szrj _Rep_type _M_t;
15238fd1498Szrj
15338fd1498Szrj typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits;
15438fd1498Szrj
15538fd1498Szrj public:
15638fd1498Szrj // many of these are specified differently in ISO, but the following are
15738fd1498Szrj // "functionally equivalent"
15838fd1498Szrj typedef typename _Alloc_traits::pointer pointer;
15938fd1498Szrj typedef typename _Alloc_traits::const_pointer const_pointer;
16038fd1498Szrj typedef typename _Alloc_traits::reference reference;
16138fd1498Szrj typedef typename _Alloc_traits::const_reference const_reference;
16238fd1498Szrj typedef typename _Rep_type::iterator iterator;
16338fd1498Szrj typedef typename _Rep_type::const_iterator const_iterator;
16438fd1498Szrj typedef typename _Rep_type::size_type size_type;
16538fd1498Szrj typedef typename _Rep_type::difference_type difference_type;
16638fd1498Szrj typedef typename _Rep_type::reverse_iterator reverse_iterator;
16738fd1498Szrj typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
16838fd1498Szrj
16938fd1498Szrj #if __cplusplus > 201402L
17038fd1498Szrj using node_type = typename _Rep_type::node_type;
17138fd1498Szrj using insert_return_type = typename _Rep_type::insert_return_type;
17238fd1498Szrj #endif
17338fd1498Szrj
17438fd1498Szrj // [23.3.1.1] construct/copy/destroy
17538fd1498Szrj // (get_allocator() is also listed in this section)
17638fd1498Szrj
17738fd1498Szrj /**
17838fd1498Szrj * @brief Default constructor creates no elements.
17938fd1498Szrj */
18038fd1498Szrj #if __cplusplus < 201103L
18138fd1498Szrj map() : _M_t() { }
18238fd1498Szrj #else
18338fd1498Szrj map() = default;
18438fd1498Szrj #endif
18538fd1498Szrj
18638fd1498Szrj /**
18738fd1498Szrj * @brief Creates a %map with no elements.
18838fd1498Szrj * @param __comp A comparison object.
18938fd1498Szrj * @param __a An allocator object.
19038fd1498Szrj */
19138fd1498Szrj explicit
19238fd1498Szrj map(const _Compare& __comp,
19338fd1498Szrj const allocator_type& __a = allocator_type())
19438fd1498Szrj : _M_t(__comp, _Pair_alloc_type(__a)) { }
19538fd1498Szrj
19638fd1498Szrj /**
19738fd1498Szrj * @brief %Map copy constructor.
19838fd1498Szrj *
19938fd1498Szrj * Whether the allocator is copied depends on the allocator traits.
20038fd1498Szrj */
20138fd1498Szrj #if __cplusplus < 201103L
20238fd1498Szrj map(const map& __x)
20338fd1498Szrj : _M_t(__x._M_t) { }
20438fd1498Szrj #else
20538fd1498Szrj map(const map&) = default;
20638fd1498Szrj
20738fd1498Szrj /**
20838fd1498Szrj * @brief %Map move constructor.
20938fd1498Szrj *
21038fd1498Szrj * The newly-created %map contains the exact contents of the moved
21138fd1498Szrj * instance. The moved instance is a valid, but unspecified, %map.
21238fd1498Szrj */
21338fd1498Szrj map(map&&) = default;
21438fd1498Szrj
21538fd1498Szrj /**
21638fd1498Szrj * @brief Builds a %map from an initializer_list.
21738fd1498Szrj * @param __l An initializer_list.
21838fd1498Szrj * @param __comp A comparison object.
21938fd1498Szrj * @param __a An allocator object.
22038fd1498Szrj *
22138fd1498Szrj * Create a %map consisting of copies of the elements in the
22238fd1498Szrj * initializer_list @a __l.
22338fd1498Szrj * This is linear in N if the range is already sorted, and NlogN
22438fd1498Szrj * otherwise (where N is @a __l.size()).
22538fd1498Szrj */
22638fd1498Szrj map(initializer_list<value_type> __l,
22738fd1498Szrj const _Compare& __comp = _Compare(),
22838fd1498Szrj const allocator_type& __a = allocator_type())
22938fd1498Szrj : _M_t(__comp, _Pair_alloc_type(__a))
23038fd1498Szrj { _M_t._M_insert_unique(__l.begin(), __l.end()); }
23138fd1498Szrj
23238fd1498Szrj /// Allocator-extended default constructor.
23338fd1498Szrj explicit
23438fd1498Szrj map(const allocator_type& __a)
23538fd1498Szrj : _M_t(_Compare(), _Pair_alloc_type(__a)) { }
23638fd1498Szrj
23738fd1498Szrj /// Allocator-extended copy constructor.
23838fd1498Szrj map(const map& __m, const allocator_type& __a)
23938fd1498Szrj : _M_t(__m._M_t, _Pair_alloc_type(__a)) { }
24038fd1498Szrj
24138fd1498Szrj /// Allocator-extended move constructor.
24238fd1498Szrj map(map&& __m, const allocator_type& __a)
24338fd1498Szrj noexcept(is_nothrow_copy_constructible<_Compare>::value
24438fd1498Szrj && _Alloc_traits::_S_always_equal())
24538fd1498Szrj : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { }
24638fd1498Szrj
24738fd1498Szrj /// Allocator-extended initialier-list constructor.
24838fd1498Szrj map(initializer_list<value_type> __l, const allocator_type& __a)
24938fd1498Szrj : _M_t(_Compare(), _Pair_alloc_type(__a))
25038fd1498Szrj { _M_t._M_insert_unique(__l.begin(), __l.end()); }
25138fd1498Szrj
25238fd1498Szrj /// Allocator-extended range constructor.
25338fd1498Szrj template<typename _InputIterator>
25438fd1498Szrj map(_InputIterator __first, _InputIterator __last,
25538fd1498Szrj const allocator_type& __a)
25638fd1498Szrj : _M_t(_Compare(), _Pair_alloc_type(__a))
25738fd1498Szrj { _M_t._M_insert_unique(__first, __last); }
25838fd1498Szrj #endif
25938fd1498Szrj
26038fd1498Szrj /**
26138fd1498Szrj * @brief Builds a %map from a range.
26238fd1498Szrj * @param __first An input iterator.
26338fd1498Szrj * @param __last An input iterator.
26438fd1498Szrj *
26538fd1498Szrj * Create a %map consisting of copies of the elements from
26638fd1498Szrj * [__first,__last). This is linear in N if the range is
26738fd1498Szrj * already sorted, and NlogN otherwise (where N is
26838fd1498Szrj * distance(__first,__last)).
26938fd1498Szrj */
27038fd1498Szrj template<typename _InputIterator>
27138fd1498Szrj map(_InputIterator __first, _InputIterator __last)
27238fd1498Szrj : _M_t()
27338fd1498Szrj { _M_t._M_insert_unique(__first, __last); }
27438fd1498Szrj
27538fd1498Szrj /**
27638fd1498Szrj * @brief Builds a %map from a range.
27738fd1498Szrj * @param __first An input iterator.
27838fd1498Szrj * @param __last An input iterator.
27938fd1498Szrj * @param __comp A comparison functor.
28038fd1498Szrj * @param __a An allocator object.
28138fd1498Szrj *
28238fd1498Szrj * Create a %map consisting of copies of the elements from
28338fd1498Szrj * [__first,__last). This is linear in N if the range is
28438fd1498Szrj * already sorted, and NlogN otherwise (where N is
28538fd1498Szrj * distance(__first,__last)).
28638fd1498Szrj */
28738fd1498Szrj template<typename _InputIterator>
28838fd1498Szrj map(_InputIterator __first, _InputIterator __last,
28938fd1498Szrj const _Compare& __comp,
29038fd1498Szrj const allocator_type& __a = allocator_type())
29138fd1498Szrj : _M_t(__comp, _Pair_alloc_type(__a))
29238fd1498Szrj { _M_t._M_insert_unique(__first, __last); }
29338fd1498Szrj
29438fd1498Szrj #if __cplusplus >= 201103L
29538fd1498Szrj /**
29638fd1498Szrj * The dtor only erases the elements, and note that if the elements
29738fd1498Szrj * themselves are pointers, the pointed-to memory is not touched in any
29838fd1498Szrj * way. Managing the pointer is the user's responsibility.
29938fd1498Szrj */
30038fd1498Szrj ~map() = default;
30138fd1498Szrj #endif
30238fd1498Szrj
30338fd1498Szrj /**
30438fd1498Szrj * @brief %Map assignment operator.
30538fd1498Szrj *
30638fd1498Szrj * Whether the allocator is copied depends on the allocator traits.
30738fd1498Szrj */
30838fd1498Szrj #if __cplusplus < 201103L
30938fd1498Szrj map&
31038fd1498Szrj operator=(const map& __x)
31138fd1498Szrj {
31238fd1498Szrj _M_t = __x._M_t;
31338fd1498Szrj return *this;
31438fd1498Szrj }
31538fd1498Szrj #else
31638fd1498Szrj map&
31738fd1498Szrj operator=(const map&) = default;
31838fd1498Szrj
31938fd1498Szrj /// Move assignment operator.
32038fd1498Szrj map&
32138fd1498Szrj operator=(map&&) = default;
32238fd1498Szrj
32338fd1498Szrj /**
32438fd1498Szrj * @brief %Map list assignment operator.
32538fd1498Szrj * @param __l An initializer_list.
32638fd1498Szrj *
32738fd1498Szrj * This function fills a %map with copies of the elements in the
32838fd1498Szrj * initializer list @a __l.
32938fd1498Szrj *
33038fd1498Szrj * Note that the assignment completely changes the %map and
33138fd1498Szrj * that the resulting %map's size is the same as the number
33238fd1498Szrj * of elements assigned.
33338fd1498Szrj */
33438fd1498Szrj map&
33538fd1498Szrj operator=(initializer_list<value_type> __l)
33638fd1498Szrj {
33738fd1498Szrj _M_t._M_assign_unique(__l.begin(), __l.end());
33838fd1498Szrj return *this;
33938fd1498Szrj }
34038fd1498Szrj #endif
34138fd1498Szrj
34238fd1498Szrj /// Get a copy of the memory allocation object.
34338fd1498Szrj allocator_type
34438fd1498Szrj get_allocator() const _GLIBCXX_NOEXCEPT
34538fd1498Szrj { return allocator_type(_M_t.get_allocator()); }
34638fd1498Szrj
34738fd1498Szrj // iterators
34838fd1498Szrj /**
34938fd1498Szrj * Returns a read/write iterator that points to the first pair in the
35038fd1498Szrj * %map.
35138fd1498Szrj * Iteration is done in ascending order according to the keys.
35238fd1498Szrj */
35338fd1498Szrj iterator
35438fd1498Szrj begin() _GLIBCXX_NOEXCEPT
35538fd1498Szrj { return _M_t.begin(); }
35638fd1498Szrj
35738fd1498Szrj /**
35838fd1498Szrj * Returns a read-only (constant) iterator that points to the first pair
35938fd1498Szrj * in the %map. Iteration is done in ascending order according to the
36038fd1498Szrj * keys.
36138fd1498Szrj */
36238fd1498Szrj const_iterator
36338fd1498Szrj begin() const _GLIBCXX_NOEXCEPT
36438fd1498Szrj { return _M_t.begin(); }
36538fd1498Szrj
36638fd1498Szrj /**
36738fd1498Szrj * Returns a read/write iterator that points one past the last
36838fd1498Szrj * pair in the %map. Iteration is done in ascending order
36938fd1498Szrj * according to the keys.
37038fd1498Szrj */
37138fd1498Szrj iterator
37238fd1498Szrj end() _GLIBCXX_NOEXCEPT
37338fd1498Szrj { return _M_t.end(); }
37438fd1498Szrj
37538fd1498Szrj /**
37638fd1498Szrj * Returns a read-only (constant) iterator that points one past the last
37738fd1498Szrj * pair in the %map. Iteration is done in ascending order according to
37838fd1498Szrj * the keys.
37938fd1498Szrj */
38038fd1498Szrj const_iterator
38138fd1498Szrj end() const _GLIBCXX_NOEXCEPT
38238fd1498Szrj { return _M_t.end(); }
38338fd1498Szrj
38438fd1498Szrj /**
38538fd1498Szrj * Returns a read/write reverse iterator that points to the last pair in
38638fd1498Szrj * the %map. Iteration is done in descending order according to the
38738fd1498Szrj * keys.
38838fd1498Szrj */
38938fd1498Szrj reverse_iterator
39038fd1498Szrj rbegin() _GLIBCXX_NOEXCEPT
39138fd1498Szrj { return _M_t.rbegin(); }
39238fd1498Szrj
39338fd1498Szrj /**
39438fd1498Szrj * Returns a read-only (constant) reverse iterator that points to the
39538fd1498Szrj * last pair in the %map. Iteration is done in descending order
39638fd1498Szrj * according to the keys.
39738fd1498Szrj */
39838fd1498Szrj const_reverse_iterator
39938fd1498Szrj rbegin() const _GLIBCXX_NOEXCEPT
40038fd1498Szrj { return _M_t.rbegin(); }
40138fd1498Szrj
40238fd1498Szrj /**
40338fd1498Szrj * Returns a read/write reverse iterator that points to one before the
40438fd1498Szrj * first pair in the %map. Iteration is done in descending order
40538fd1498Szrj * according to the keys.
40638fd1498Szrj */
40738fd1498Szrj reverse_iterator
40838fd1498Szrj rend() _GLIBCXX_NOEXCEPT
40938fd1498Szrj { return _M_t.rend(); }
41038fd1498Szrj
41138fd1498Szrj /**
41238fd1498Szrj * Returns a read-only (constant) reverse iterator that points to one
41338fd1498Szrj * before the first pair in the %map. Iteration is done in descending
41438fd1498Szrj * order according to the keys.
41538fd1498Szrj */
41638fd1498Szrj const_reverse_iterator
41738fd1498Szrj rend() const _GLIBCXX_NOEXCEPT
41838fd1498Szrj { return _M_t.rend(); }
41938fd1498Szrj
42038fd1498Szrj #if __cplusplus >= 201103L
42138fd1498Szrj /**
42238fd1498Szrj * Returns a read-only (constant) iterator that points to the first pair
42338fd1498Szrj * in the %map. Iteration is done in ascending order according to the
42438fd1498Szrj * keys.
42538fd1498Szrj */
42638fd1498Szrj const_iterator
42738fd1498Szrj cbegin() const noexcept
42838fd1498Szrj { return _M_t.begin(); }
42938fd1498Szrj
43038fd1498Szrj /**
43138fd1498Szrj * Returns a read-only (constant) iterator that points one past the last
43238fd1498Szrj * pair in the %map. Iteration is done in ascending order according to
43338fd1498Szrj * the keys.
43438fd1498Szrj */
43538fd1498Szrj const_iterator
43638fd1498Szrj cend() const noexcept
43738fd1498Szrj { return _M_t.end(); }
43838fd1498Szrj
43938fd1498Szrj /**
44038fd1498Szrj * Returns a read-only (constant) reverse iterator that points to the
44138fd1498Szrj * last pair in the %map. Iteration is done in descending order
44238fd1498Szrj * according to the keys.
44338fd1498Szrj */
44438fd1498Szrj const_reverse_iterator
44538fd1498Szrj crbegin() const noexcept
44638fd1498Szrj { return _M_t.rbegin(); }
44738fd1498Szrj
44838fd1498Szrj /**
44938fd1498Szrj * Returns a read-only (constant) reverse iterator that points to one
45038fd1498Szrj * before the first pair in the %map. Iteration is done in descending
45138fd1498Szrj * order according to the keys.
45238fd1498Szrj */
45338fd1498Szrj const_reverse_iterator
45438fd1498Szrj crend() const noexcept
45538fd1498Szrj { return _M_t.rend(); }
45638fd1498Szrj #endif
45738fd1498Szrj
45838fd1498Szrj // capacity
45938fd1498Szrj /** Returns true if the %map is empty. (Thus begin() would equal
46038fd1498Szrj * end().)
46138fd1498Szrj */
46238fd1498Szrj bool
46338fd1498Szrj empty() const _GLIBCXX_NOEXCEPT
46438fd1498Szrj { return _M_t.empty(); }
46538fd1498Szrj
46638fd1498Szrj /** Returns the size of the %map. */
46738fd1498Szrj size_type
46838fd1498Szrj size() const _GLIBCXX_NOEXCEPT
46938fd1498Szrj { return _M_t.size(); }
47038fd1498Szrj
47138fd1498Szrj /** Returns the maximum size of the %map. */
47238fd1498Szrj size_type
47338fd1498Szrj max_size() const _GLIBCXX_NOEXCEPT
47438fd1498Szrj { return _M_t.max_size(); }
47538fd1498Szrj
47638fd1498Szrj // [23.3.1.2] element access
47738fd1498Szrj /**
47838fd1498Szrj * @brief Subscript ( @c [] ) access to %map data.
47938fd1498Szrj * @param __k The key for which data should be retrieved.
48038fd1498Szrj * @return A reference to the data of the (key,data) %pair.
48138fd1498Szrj *
48238fd1498Szrj * Allows for easy lookup with the subscript ( @c [] )
48338fd1498Szrj * operator. Returns data associated with the key specified in
48438fd1498Szrj * subscript. If the key does not exist, a pair with that key
48538fd1498Szrj * is created using default values, which is then returned.
48638fd1498Szrj *
48738fd1498Szrj * Lookup requires logarithmic time.
48838fd1498Szrj */
48938fd1498Szrj mapped_type&
49038fd1498Szrj operator[](const key_type& __k)
49138fd1498Szrj {
49238fd1498Szrj // concept requirements
49338fd1498Szrj __glibcxx_function_requires(_DefaultConstructibleConcept<mapped_type>)
49438fd1498Szrj
49538fd1498Szrj iterator __i = lower_bound(__k);
49638fd1498Szrj // __i->first is greater than or equivalent to __k.
49738fd1498Szrj if (__i == end() || key_comp()(__k, (*__i).first))
49838fd1498Szrj #if __cplusplus >= 201103L
49938fd1498Szrj __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct,
50038fd1498Szrj std::tuple<const key_type&>(__k),
50138fd1498Szrj std::tuple<>());
50238fd1498Szrj #else
50338fd1498Szrj __i = insert(__i, value_type(__k, mapped_type()));
50438fd1498Szrj #endif
50538fd1498Szrj return (*__i).second;
50638fd1498Szrj }
50738fd1498Szrj
50838fd1498Szrj #if __cplusplus >= 201103L
50938fd1498Szrj mapped_type&
51038fd1498Szrj operator[](key_type&& __k)
51138fd1498Szrj {
51238fd1498Szrj // concept requirements
51338fd1498Szrj __glibcxx_function_requires(_DefaultConstructibleConcept<mapped_type>)
51438fd1498Szrj
51538fd1498Szrj iterator __i = lower_bound(__k);
51638fd1498Szrj // __i->first is greater than or equivalent to __k.
51738fd1498Szrj if (__i == end() || key_comp()(__k, (*__i).first))
51838fd1498Szrj __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct,
51938fd1498Szrj std::forward_as_tuple(std::move(__k)),
52038fd1498Szrj std::tuple<>());
52138fd1498Szrj return (*__i).second;
52238fd1498Szrj }
52338fd1498Szrj #endif
52438fd1498Szrj
52538fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
52638fd1498Szrj // DR 464. Suggestion for new member functions in standard containers.
52738fd1498Szrj /**
52838fd1498Szrj * @brief Access to %map data.
52938fd1498Szrj * @param __k The key for which data should be retrieved.
53038fd1498Szrj * @return A reference to the data whose key is equivalent to @a __k, if
53138fd1498Szrj * such a data is present in the %map.
53238fd1498Szrj * @throw std::out_of_range If no such data is present.
53338fd1498Szrj */
53438fd1498Szrj mapped_type&
53538fd1498Szrj at(const key_type& __k)
53638fd1498Szrj {
53738fd1498Szrj iterator __i = lower_bound(__k);
53838fd1498Szrj if (__i == end() || key_comp()(__k, (*__i).first))
53938fd1498Szrj __throw_out_of_range(__N("map::at"));
54038fd1498Szrj return (*__i).second;
54138fd1498Szrj }
54238fd1498Szrj
54338fd1498Szrj const mapped_type&
54438fd1498Szrj at(const key_type& __k) const
54538fd1498Szrj {
54638fd1498Szrj const_iterator __i = lower_bound(__k);
54738fd1498Szrj if (__i == end() || key_comp()(__k, (*__i).first))
54838fd1498Szrj __throw_out_of_range(__N("map::at"));
54938fd1498Szrj return (*__i).second;
55038fd1498Szrj }
55138fd1498Szrj
55238fd1498Szrj // modifiers
55338fd1498Szrj #if __cplusplus >= 201103L
55438fd1498Szrj /**
55538fd1498Szrj * @brief Attempts to build and insert a std::pair into the %map.
55638fd1498Szrj *
55738fd1498Szrj * @param __args Arguments used to generate a new pair instance (see
55838fd1498Szrj * std::piecewise_contruct for passing arguments to each
55938fd1498Szrj * part of the pair constructor).
56038fd1498Szrj *
56138fd1498Szrj * @return A pair, of which the first element is an iterator that points
56238fd1498Szrj * to the possibly inserted pair, and the second is a bool that
56338fd1498Szrj * is true if the pair was actually inserted.
56438fd1498Szrj *
56538fd1498Szrj * This function attempts to build and insert a (key, value) %pair into
56638fd1498Szrj * the %map.
56738fd1498Szrj * A %map relies on unique keys and thus a %pair is only inserted if its
56838fd1498Szrj * first element (the key) is not already present in the %map.
56938fd1498Szrj *
57038fd1498Szrj * Insertion requires logarithmic time.
57138fd1498Szrj */
57238fd1498Szrj template<typename... _Args>
57338fd1498Szrj std::pair<iterator, bool>
57438fd1498Szrj emplace(_Args&&... __args)
57538fd1498Szrj { return _M_t._M_emplace_unique(std::forward<_Args>(__args)...); }
57638fd1498Szrj
57738fd1498Szrj /**
57838fd1498Szrj * @brief Attempts to build and insert a std::pair into the %map.
57938fd1498Szrj *
58038fd1498Szrj * @param __pos An iterator that serves as a hint as to where the pair
58138fd1498Szrj * should be inserted.
58238fd1498Szrj * @param __args Arguments used to generate a new pair instance (see
58338fd1498Szrj * std::piecewise_contruct for passing arguments to each
58438fd1498Szrj * part of the pair constructor).
58538fd1498Szrj * @return An iterator that points to the element with key of the
58638fd1498Szrj * std::pair built from @a __args (may or may not be that
58738fd1498Szrj * std::pair).
58838fd1498Szrj *
58938fd1498Szrj * This function is not concerned about whether the insertion took place,
59038fd1498Szrj * and thus does not return a boolean like the single-argument emplace()
59138fd1498Szrj * does.
59238fd1498Szrj * Note that the first parameter is only a hint and can potentially
59338fd1498Szrj * improve the performance of the insertion process. A bad hint would
59438fd1498Szrj * cause no gains in efficiency.
59538fd1498Szrj *
59638fd1498Szrj * See
59738fd1498Szrj * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
59838fd1498Szrj * for more on @a hinting.
59938fd1498Szrj *
60038fd1498Szrj * Insertion requires logarithmic time (if the hint is not taken).
60138fd1498Szrj */
60238fd1498Szrj template<typename... _Args>
60338fd1498Szrj iterator
60438fd1498Szrj emplace_hint(const_iterator __pos, _Args&&... __args)
60538fd1498Szrj {
60638fd1498Szrj return _M_t._M_emplace_hint_unique(__pos,
60738fd1498Szrj std::forward<_Args>(__args)...);
60838fd1498Szrj }
60938fd1498Szrj #endif
61038fd1498Szrj
61138fd1498Szrj #if __cplusplus > 201402L
61238fd1498Szrj /// Extract a node.
61338fd1498Szrj node_type
61438fd1498Szrj extract(const_iterator __pos)
61538fd1498Szrj {
61638fd1498Szrj __glibcxx_assert(__pos != end());
61738fd1498Szrj return _M_t.extract(__pos);
61838fd1498Szrj }
61938fd1498Szrj
62038fd1498Szrj /// Extract a node.
62138fd1498Szrj node_type
62238fd1498Szrj extract(const key_type& __x)
62338fd1498Szrj { return _M_t.extract(__x); }
62438fd1498Szrj
62538fd1498Szrj /// Re-insert an extracted node.
62638fd1498Szrj insert_return_type
62738fd1498Szrj insert(node_type&& __nh)
62838fd1498Szrj { return _M_t._M_reinsert_node_unique(std::move(__nh)); }
62938fd1498Szrj
63038fd1498Szrj /// Re-insert an extracted node.
63138fd1498Szrj iterator
63238fd1498Szrj insert(const_iterator __hint, node_type&& __nh)
63338fd1498Szrj { return _M_t._M_reinsert_node_hint_unique(__hint, std::move(__nh)); }
63438fd1498Szrj
63538fd1498Szrj template<typename, typename>
63638fd1498Szrj friend class std::_Rb_tree_merge_helper;
63738fd1498Szrj
63838fd1498Szrj template<typename _C2>
63938fd1498Szrj void
64038fd1498Szrj merge(map<_Key, _Tp, _C2, _Alloc>& __source)
64138fd1498Szrj {
64238fd1498Szrj using _Merge_helper = _Rb_tree_merge_helper<map, _C2>;
64338fd1498Szrj _M_t._M_merge_unique(_Merge_helper::_S_get_tree(__source));
64438fd1498Szrj }
64538fd1498Szrj
64638fd1498Szrj template<typename _C2>
64738fd1498Szrj void
64838fd1498Szrj merge(map<_Key, _Tp, _C2, _Alloc>&& __source)
64938fd1498Szrj { merge(__source); }
65038fd1498Szrj
65138fd1498Szrj template<typename _C2>
65238fd1498Szrj void
65338fd1498Szrj merge(multimap<_Key, _Tp, _C2, _Alloc>& __source)
65438fd1498Szrj {
65538fd1498Szrj using _Merge_helper = _Rb_tree_merge_helper<map, _C2>;
65638fd1498Szrj _M_t._M_merge_unique(_Merge_helper::_S_get_tree(__source));
65738fd1498Szrj }
65838fd1498Szrj
65938fd1498Szrj template<typename _C2>
66038fd1498Szrj void
66138fd1498Szrj merge(multimap<_Key, _Tp, _C2, _Alloc>&& __source)
66238fd1498Szrj { merge(__source); }
66338fd1498Szrj #endif // C++17
66438fd1498Szrj
66538fd1498Szrj #if __cplusplus > 201402L
66638fd1498Szrj #define __cpp_lib_map_try_emplace 201411
66738fd1498Szrj /**
66838fd1498Szrj * @brief Attempts to build and insert a std::pair into the %map.
66938fd1498Szrj *
67038fd1498Szrj * @param __k Key to use for finding a possibly existing pair in
67138fd1498Szrj * the map.
67238fd1498Szrj * @param __args Arguments used to generate the .second for a new pair
67338fd1498Szrj * instance.
67438fd1498Szrj *
67538fd1498Szrj * @return A pair, of which the first element is an iterator that points
67638fd1498Szrj * to the possibly inserted pair, and the second is a bool that
67738fd1498Szrj * is true if the pair was actually inserted.
67838fd1498Szrj *
67938fd1498Szrj * This function attempts to build and insert a (key, value) %pair into
68038fd1498Szrj * the %map.
68138fd1498Szrj * A %map relies on unique keys and thus a %pair is only inserted if its
68238fd1498Szrj * first element (the key) is not already present in the %map.
68338fd1498Szrj * If a %pair is not inserted, this function has no effect.
68438fd1498Szrj *
68538fd1498Szrj * Insertion requires logarithmic time.
68638fd1498Szrj */
68738fd1498Szrj template <typename... _Args>
68838fd1498Szrj pair<iterator, bool>
68938fd1498Szrj try_emplace(const key_type& __k, _Args&&... __args)
69038fd1498Szrj {
69138fd1498Szrj iterator __i = lower_bound(__k);
69238fd1498Szrj if (__i == end() || key_comp()(__k, (*__i).first))
69338fd1498Szrj {
69438fd1498Szrj __i = emplace_hint(__i, std::piecewise_construct,
69538fd1498Szrj std::forward_as_tuple(__k),
69638fd1498Szrj std::forward_as_tuple(
69738fd1498Szrj std::forward<_Args>(__args)...));
69838fd1498Szrj return {__i, true};
69938fd1498Szrj }
70038fd1498Szrj return {__i, false};
70138fd1498Szrj }
70238fd1498Szrj
70338fd1498Szrj // move-capable overload
70438fd1498Szrj template <typename... _Args>
70538fd1498Szrj pair<iterator, bool>
70638fd1498Szrj try_emplace(key_type&& __k, _Args&&... __args)
70738fd1498Szrj {
70838fd1498Szrj iterator __i = lower_bound(__k);
70938fd1498Szrj if (__i == end() || key_comp()(__k, (*__i).first))
71038fd1498Szrj {
71138fd1498Szrj __i = emplace_hint(__i, std::piecewise_construct,
71238fd1498Szrj std::forward_as_tuple(std::move(__k)),
71338fd1498Szrj std::forward_as_tuple(
71438fd1498Szrj std::forward<_Args>(__args)...));
71538fd1498Szrj return {__i, true};
71638fd1498Szrj }
71738fd1498Szrj return {__i, false};
71838fd1498Szrj }
71938fd1498Szrj
72038fd1498Szrj /**
72138fd1498Szrj * @brief Attempts to build and insert a std::pair into the %map.
72238fd1498Szrj *
72338fd1498Szrj * @param __hint An iterator that serves as a hint as to where the
72438fd1498Szrj * pair should be inserted.
72538fd1498Szrj * @param __k Key to use for finding a possibly existing pair in
72638fd1498Szrj * the map.
72738fd1498Szrj * @param __args Arguments used to generate the .second for a new pair
72838fd1498Szrj * instance.
72938fd1498Szrj * @return An iterator that points to the element with key of the
73038fd1498Szrj * std::pair built from @a __args (may or may not be that
73138fd1498Szrj * std::pair).
73238fd1498Szrj *
73338fd1498Szrj * This function is not concerned about whether the insertion took place,
73438fd1498Szrj * and thus does not return a boolean like the single-argument
73538fd1498Szrj * try_emplace() does. However, if insertion did not take place,
73638fd1498Szrj * this function has no effect.
73738fd1498Szrj * Note that the first parameter is only a hint and can potentially
73838fd1498Szrj * improve the performance of the insertion process. A bad hint would
73938fd1498Szrj * cause no gains in efficiency.
74038fd1498Szrj *
74138fd1498Szrj * See
74238fd1498Szrj * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
74338fd1498Szrj * for more on @a hinting.
74438fd1498Szrj *
74538fd1498Szrj * Insertion requires logarithmic time (if the hint is not taken).
74638fd1498Szrj */
74738fd1498Szrj template <typename... _Args>
74838fd1498Szrj iterator
74938fd1498Szrj try_emplace(const_iterator __hint, const key_type& __k,
75038fd1498Szrj _Args&&... __args)
75138fd1498Szrj {
75238fd1498Szrj iterator __i;
75338fd1498Szrj auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
75438fd1498Szrj if (__true_hint.second)
75538fd1498Szrj __i = emplace_hint(iterator(__true_hint.second),
75638fd1498Szrj std::piecewise_construct,
75738fd1498Szrj std::forward_as_tuple(__k),
75838fd1498Szrj std::forward_as_tuple(
75938fd1498Szrj std::forward<_Args>(__args)...));
76038fd1498Szrj else
76138fd1498Szrj __i = iterator(__true_hint.first);
76238fd1498Szrj return __i;
76338fd1498Szrj }
76438fd1498Szrj
76538fd1498Szrj // move-capable overload
76638fd1498Szrj template <typename... _Args>
76738fd1498Szrj iterator
76838fd1498Szrj try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
76938fd1498Szrj {
77038fd1498Szrj iterator __i;
77138fd1498Szrj auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
77238fd1498Szrj if (__true_hint.second)
77338fd1498Szrj __i = emplace_hint(iterator(__true_hint.second),
77438fd1498Szrj std::piecewise_construct,
77538fd1498Szrj std::forward_as_tuple(std::move(__k)),
77638fd1498Szrj std::forward_as_tuple(
77738fd1498Szrj std::forward<_Args>(__args)...));
77838fd1498Szrj else
77938fd1498Szrj __i = iterator(__true_hint.first);
78038fd1498Szrj return __i;
78138fd1498Szrj }
78238fd1498Szrj #endif
78338fd1498Szrj
78438fd1498Szrj /**
78538fd1498Szrj * @brief Attempts to insert a std::pair into the %map.
78638fd1498Szrj * @param __x Pair to be inserted (see std::make_pair for easy
78738fd1498Szrj * creation of pairs).
78838fd1498Szrj *
78938fd1498Szrj * @return A pair, of which the first element is an iterator that
79038fd1498Szrj * points to the possibly inserted pair, and the second is
79138fd1498Szrj * a bool that is true if the pair was actually inserted.
79238fd1498Szrj *
79338fd1498Szrj * This function attempts to insert a (key, value) %pair into the %map.
79438fd1498Szrj * A %map relies on unique keys and thus a %pair is only inserted if its
79538fd1498Szrj * first element (the key) is not already present in the %map.
79638fd1498Szrj *
79738fd1498Szrj * Insertion requires logarithmic time.
79838fd1498Szrj * @{
79938fd1498Szrj */
80038fd1498Szrj std::pair<iterator, bool>
80138fd1498Szrj insert(const value_type& __x)
80238fd1498Szrj { return _M_t._M_insert_unique(__x); }
80338fd1498Szrj
80438fd1498Szrj #if __cplusplus >= 201103L
80538fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
80638fd1498Szrj // 2354. Unnecessary copying when inserting into maps with braced-init
80738fd1498Szrj std::pair<iterator, bool>
80838fd1498Szrj insert(value_type&& __x)
80938fd1498Szrj { return _M_t._M_insert_unique(std::move(__x)); }
81038fd1498Szrj
811*58e805e6Szrj template<typename _Pair>
812*58e805e6Szrj __enable_if_t<is_constructible<value_type, _Pair>::value,
813*58e805e6Szrj pair<iterator, bool>>
81438fd1498Szrj insert(_Pair&& __x)
815*58e805e6Szrj { return _M_t._M_emplace_unique(std::forward<_Pair>(__x)); }
81638fd1498Szrj #endif
81738fd1498Szrj // @}
81838fd1498Szrj
81938fd1498Szrj #if __cplusplus >= 201103L
82038fd1498Szrj /**
82138fd1498Szrj * @brief Attempts to insert a list of std::pairs into the %map.
82238fd1498Szrj * @param __list A std::initializer_list<value_type> of pairs to be
82338fd1498Szrj * inserted.
82438fd1498Szrj *
82538fd1498Szrj * Complexity similar to that of the range constructor.
82638fd1498Szrj */
82738fd1498Szrj void
82838fd1498Szrj insert(std::initializer_list<value_type> __list)
82938fd1498Szrj { insert(__list.begin(), __list.end()); }
83038fd1498Szrj #endif
83138fd1498Szrj
83238fd1498Szrj /**
83338fd1498Szrj * @brief Attempts to insert a std::pair into the %map.
83438fd1498Szrj * @param __position An iterator that serves as a hint as to where the
83538fd1498Szrj * pair should be inserted.
83638fd1498Szrj * @param __x Pair to be inserted (see std::make_pair for easy creation
83738fd1498Szrj * of pairs).
83838fd1498Szrj * @return An iterator that points to the element with key of
83938fd1498Szrj * @a __x (may or may not be the %pair passed in).
84038fd1498Szrj *
84138fd1498Szrj
84238fd1498Szrj * This function is not concerned about whether the insertion
84338fd1498Szrj * took place, and thus does not return a boolean like the
84438fd1498Szrj * single-argument insert() does. Note that the first
84538fd1498Szrj * parameter is only a hint and can potentially improve the
84638fd1498Szrj * performance of the insertion process. A bad hint would
84738fd1498Szrj * cause no gains in efficiency.
84838fd1498Szrj *
84938fd1498Szrj * See
85038fd1498Szrj * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
85138fd1498Szrj * for more on @a hinting.
85238fd1498Szrj *
85338fd1498Szrj * Insertion requires logarithmic time (if the hint is not taken).
85438fd1498Szrj * @{
85538fd1498Szrj */
85638fd1498Szrj iterator
85738fd1498Szrj #if __cplusplus >= 201103L
85838fd1498Szrj insert(const_iterator __position, const value_type& __x)
85938fd1498Szrj #else
86038fd1498Szrj insert(iterator __position, const value_type& __x)
86138fd1498Szrj #endif
86238fd1498Szrj { return _M_t._M_insert_unique_(__position, __x); }
86338fd1498Szrj
86438fd1498Szrj #if __cplusplus >= 201103L
86538fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
86638fd1498Szrj // 2354. Unnecessary copying when inserting into maps with braced-init
86738fd1498Szrj iterator
86838fd1498Szrj insert(const_iterator __position, value_type&& __x)
86938fd1498Szrj { return _M_t._M_insert_unique_(__position, std::move(__x)); }
87038fd1498Szrj
871*58e805e6Szrj template<typename _Pair>
872*58e805e6Szrj __enable_if_t<is_constructible<value_type, _Pair>::value, iterator>
87338fd1498Szrj insert(const_iterator __position, _Pair&& __x)
874*58e805e6Szrj {
875*58e805e6Szrj return _M_t._M_emplace_hint_unique(__position,
876*58e805e6Szrj std::forward<_Pair>(__x));
877*58e805e6Szrj }
87838fd1498Szrj #endif
87938fd1498Szrj // @}
88038fd1498Szrj
88138fd1498Szrj /**
88238fd1498Szrj * @brief Template function that attempts to insert a range of elements.
88338fd1498Szrj * @param __first Iterator pointing to the start of the range to be
88438fd1498Szrj * inserted.
88538fd1498Szrj * @param __last Iterator pointing to the end of the range.
88638fd1498Szrj *
88738fd1498Szrj * Complexity similar to that of the range constructor.
88838fd1498Szrj */
88938fd1498Szrj template<typename _InputIterator>
89038fd1498Szrj void
89138fd1498Szrj insert(_InputIterator __first, _InputIterator __last)
89238fd1498Szrj { _M_t._M_insert_unique(__first, __last); }
89338fd1498Szrj
89438fd1498Szrj #if __cplusplus > 201402L
89538fd1498Szrj #define __cpp_lib_map_insertion 201411
89638fd1498Szrj /**
89738fd1498Szrj * @brief Attempts to insert or assign a std::pair into the %map.
89838fd1498Szrj * @param __k Key to use for finding a possibly existing pair in
89938fd1498Szrj * the map.
90038fd1498Szrj * @param __obj Argument used to generate the .second for a pair
90138fd1498Szrj * instance.
90238fd1498Szrj *
90338fd1498Szrj * @return A pair, of which the first element is an iterator that
90438fd1498Szrj * points to the possibly inserted pair, and the second is
90538fd1498Szrj * a bool that is true if the pair was actually inserted.
90638fd1498Szrj *
90738fd1498Szrj * This function attempts to insert a (key, value) %pair into the %map.
90838fd1498Szrj * A %map relies on unique keys and thus a %pair is only inserted if its
90938fd1498Szrj * first element (the key) is not already present in the %map.
91038fd1498Szrj * If the %pair was already in the %map, the .second of the %pair
91138fd1498Szrj * is assigned from __obj.
91238fd1498Szrj *
91338fd1498Szrj * Insertion requires logarithmic time.
91438fd1498Szrj */
91538fd1498Szrj template <typename _Obj>
91638fd1498Szrj pair<iterator, bool>
91738fd1498Szrj insert_or_assign(const key_type& __k, _Obj&& __obj)
91838fd1498Szrj {
91938fd1498Szrj iterator __i = lower_bound(__k);
92038fd1498Szrj if (__i == end() || key_comp()(__k, (*__i).first))
92138fd1498Szrj {
92238fd1498Szrj __i = emplace_hint(__i, std::piecewise_construct,
92338fd1498Szrj std::forward_as_tuple(__k),
92438fd1498Szrj std::forward_as_tuple(
92538fd1498Szrj std::forward<_Obj>(__obj)));
92638fd1498Szrj return {__i, true};
92738fd1498Szrj }
92838fd1498Szrj (*__i).second = std::forward<_Obj>(__obj);
92938fd1498Szrj return {__i, false};
93038fd1498Szrj }
93138fd1498Szrj
93238fd1498Szrj // move-capable overload
93338fd1498Szrj template <typename _Obj>
93438fd1498Szrj pair<iterator, bool>
93538fd1498Szrj insert_or_assign(key_type&& __k, _Obj&& __obj)
93638fd1498Szrj {
93738fd1498Szrj iterator __i = lower_bound(__k);
93838fd1498Szrj if (__i == end() || key_comp()(__k, (*__i).first))
93938fd1498Szrj {
94038fd1498Szrj __i = emplace_hint(__i, std::piecewise_construct,
94138fd1498Szrj std::forward_as_tuple(std::move(__k)),
94238fd1498Szrj std::forward_as_tuple(
94338fd1498Szrj std::forward<_Obj>(__obj)));
94438fd1498Szrj return {__i, true};
94538fd1498Szrj }
94638fd1498Szrj (*__i).second = std::forward<_Obj>(__obj);
94738fd1498Szrj return {__i, false};
94838fd1498Szrj }
94938fd1498Szrj
95038fd1498Szrj /**
95138fd1498Szrj * @brief Attempts to insert or assign a std::pair into the %map.
95238fd1498Szrj * @param __hint An iterator that serves as a hint as to where the
95338fd1498Szrj * pair should be inserted.
95438fd1498Szrj * @param __k Key to use for finding a possibly existing pair in
95538fd1498Szrj * the map.
95638fd1498Szrj * @param __obj Argument used to generate the .second for a pair
95738fd1498Szrj * instance.
95838fd1498Szrj *
95938fd1498Szrj * @return An iterator that points to the element with key of
96038fd1498Szrj * @a __x (may or may not be the %pair passed in).
96138fd1498Szrj *
96238fd1498Szrj * This function attempts to insert a (key, value) %pair into the %map.
96338fd1498Szrj * A %map relies on unique keys and thus a %pair is only inserted if its
96438fd1498Szrj * first element (the key) is not already present in the %map.
96538fd1498Szrj * If the %pair was already in the %map, the .second of the %pair
96638fd1498Szrj * is assigned from __obj.
96738fd1498Szrj *
96838fd1498Szrj * Insertion requires logarithmic time.
96938fd1498Szrj */
97038fd1498Szrj template <typename _Obj>
97138fd1498Szrj iterator
97238fd1498Szrj insert_or_assign(const_iterator __hint,
97338fd1498Szrj const key_type& __k, _Obj&& __obj)
97438fd1498Szrj {
97538fd1498Szrj iterator __i;
97638fd1498Szrj auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
97738fd1498Szrj if (__true_hint.second)
97838fd1498Szrj {
97938fd1498Szrj return emplace_hint(iterator(__true_hint.second),
98038fd1498Szrj std::piecewise_construct,
98138fd1498Szrj std::forward_as_tuple(__k),
98238fd1498Szrj std::forward_as_tuple(
98338fd1498Szrj std::forward<_Obj>(__obj)));
98438fd1498Szrj }
98538fd1498Szrj __i = iterator(__true_hint.first);
98638fd1498Szrj (*__i).second = std::forward<_Obj>(__obj);
98738fd1498Szrj return __i;
98838fd1498Szrj }
98938fd1498Szrj
99038fd1498Szrj // move-capable overload
99138fd1498Szrj template <typename _Obj>
99238fd1498Szrj iterator
99338fd1498Szrj insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
99438fd1498Szrj {
99538fd1498Szrj iterator __i;
99638fd1498Szrj auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k);
99738fd1498Szrj if (__true_hint.second)
99838fd1498Szrj {
99938fd1498Szrj return emplace_hint(iterator(__true_hint.second),
100038fd1498Szrj std::piecewise_construct,
100138fd1498Szrj std::forward_as_tuple(std::move(__k)),
100238fd1498Szrj std::forward_as_tuple(
100338fd1498Szrj std::forward<_Obj>(__obj)));
100438fd1498Szrj }
100538fd1498Szrj __i = iterator(__true_hint.first);
100638fd1498Szrj (*__i).second = std::forward<_Obj>(__obj);
100738fd1498Szrj return __i;
100838fd1498Szrj }
100938fd1498Szrj #endif
101038fd1498Szrj
101138fd1498Szrj #if __cplusplus >= 201103L
101238fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
101338fd1498Szrj // DR 130. Associative erase should return an iterator.
101438fd1498Szrj /**
101538fd1498Szrj * @brief Erases an element from a %map.
101638fd1498Szrj * @param __position An iterator pointing to the element to be erased.
101738fd1498Szrj * @return An iterator pointing to the element immediately following
101838fd1498Szrj * @a position prior to the element being erased. If no such
101938fd1498Szrj * element exists, end() is returned.
102038fd1498Szrj *
102138fd1498Szrj * This function erases an element, pointed to by the given
102238fd1498Szrj * iterator, from a %map. Note that this function only erases
102338fd1498Szrj * the element, and that if the element is itself a pointer,
102438fd1498Szrj * the pointed-to memory is not touched in any way. Managing
102538fd1498Szrj * the pointer is the user's responsibility.
102638fd1498Szrj *
102738fd1498Szrj * @{
102838fd1498Szrj */
102938fd1498Szrj iterator
103038fd1498Szrj erase(const_iterator __position)
103138fd1498Szrj { return _M_t.erase(__position); }
103238fd1498Szrj
103338fd1498Szrj // LWG 2059
103438fd1498Szrj _GLIBCXX_ABI_TAG_CXX11
103538fd1498Szrj iterator
103638fd1498Szrj erase(iterator __position)
103738fd1498Szrj { return _M_t.erase(__position); }
103838fd1498Szrj // @}
103938fd1498Szrj #else
104038fd1498Szrj /**
104138fd1498Szrj * @brief Erases an element from a %map.
104238fd1498Szrj * @param __position An iterator pointing to the element to be erased.
104338fd1498Szrj *
104438fd1498Szrj * This function erases an element, pointed to by the given
104538fd1498Szrj * iterator, from a %map. Note that this function only erases
104638fd1498Szrj * the element, and that if the element is itself a pointer,
104738fd1498Szrj * the pointed-to memory is not touched in any way. Managing
104838fd1498Szrj * the pointer is the user's responsibility.
104938fd1498Szrj */
105038fd1498Szrj void
105138fd1498Szrj erase(iterator __position)
105238fd1498Szrj { _M_t.erase(__position); }
105338fd1498Szrj #endif
105438fd1498Szrj
105538fd1498Szrj /**
105638fd1498Szrj * @brief Erases elements according to the provided key.
105738fd1498Szrj * @param __x Key of element to be erased.
105838fd1498Szrj * @return The number of elements erased.
105938fd1498Szrj *
106038fd1498Szrj * This function erases all the elements located by the given key from
106138fd1498Szrj * a %map.
106238fd1498Szrj * Note that this function only erases the element, and that if
106338fd1498Szrj * the element is itself a pointer, the pointed-to memory is not touched
106438fd1498Szrj * in any way. Managing the pointer is the user's responsibility.
106538fd1498Szrj */
106638fd1498Szrj size_type
106738fd1498Szrj erase(const key_type& __x)
106838fd1498Szrj { return _M_t.erase(__x); }
106938fd1498Szrj
107038fd1498Szrj #if __cplusplus >= 201103L
107138fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
107238fd1498Szrj // DR 130. Associative erase should return an iterator.
107338fd1498Szrj /**
107438fd1498Szrj * @brief Erases a [first,last) range of elements from a %map.
107538fd1498Szrj * @param __first Iterator pointing to the start of the range to be
107638fd1498Szrj * erased.
107738fd1498Szrj * @param __last Iterator pointing to the end of the range to
107838fd1498Szrj * be erased.
107938fd1498Szrj * @return The iterator @a __last.
108038fd1498Szrj *
108138fd1498Szrj * This function erases a sequence of elements from a %map.
108238fd1498Szrj * Note that this function only erases the element, and that if
108338fd1498Szrj * the element is itself a pointer, the pointed-to memory is not touched
108438fd1498Szrj * in any way. Managing the pointer is the user's responsibility.
108538fd1498Szrj */
108638fd1498Szrj iterator
108738fd1498Szrj erase(const_iterator __first, const_iterator __last)
108838fd1498Szrj { return _M_t.erase(__first, __last); }
108938fd1498Szrj #else
109038fd1498Szrj /**
109138fd1498Szrj * @brief Erases a [__first,__last) range of elements from a %map.
109238fd1498Szrj * @param __first Iterator pointing to the start of the range to be
109338fd1498Szrj * erased.
109438fd1498Szrj * @param __last Iterator pointing to the end of the range to
109538fd1498Szrj * be erased.
109638fd1498Szrj *
109738fd1498Szrj * This function erases a sequence of elements from a %map.
109838fd1498Szrj * Note that this function only erases the element, and that if
109938fd1498Szrj * the element is itself a pointer, the pointed-to memory is not touched
110038fd1498Szrj * in any way. Managing the pointer is the user's responsibility.
110138fd1498Szrj */
110238fd1498Szrj void
110338fd1498Szrj erase(iterator __first, iterator __last)
110438fd1498Szrj { _M_t.erase(__first, __last); }
110538fd1498Szrj #endif
110638fd1498Szrj
110738fd1498Szrj /**
110838fd1498Szrj * @brief Swaps data with another %map.
110938fd1498Szrj * @param __x A %map of the same element and allocator types.
111038fd1498Szrj *
111138fd1498Szrj * This exchanges the elements between two maps in constant
111238fd1498Szrj * time. (It is only swapping a pointer, an integer, and an
111338fd1498Szrj * instance of the @c Compare type (which itself is often
111438fd1498Szrj * stateless and empty), so it should be quite fast.) Note
111538fd1498Szrj * that the global std::swap() function is specialized such
111638fd1498Szrj * that std::swap(m1,m2) will feed to this function.
111738fd1498Szrj *
111838fd1498Szrj * Whether the allocators are swapped depends on the allocator traits.
111938fd1498Szrj */
112038fd1498Szrj void
112138fd1498Szrj swap(map& __x)
112238fd1498Szrj _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value)
112338fd1498Szrj { _M_t.swap(__x._M_t); }
112438fd1498Szrj
112538fd1498Szrj /**
112638fd1498Szrj * Erases all elements in a %map. Note that this function only
112738fd1498Szrj * erases the elements, and that if the elements themselves are
112838fd1498Szrj * pointers, the pointed-to memory is not touched in any way.
112938fd1498Szrj * Managing the pointer is the user's responsibility.
113038fd1498Szrj */
113138fd1498Szrj void
113238fd1498Szrj clear() _GLIBCXX_NOEXCEPT
113338fd1498Szrj { _M_t.clear(); }
113438fd1498Szrj
113538fd1498Szrj // observers
113638fd1498Szrj /**
113738fd1498Szrj * Returns the key comparison object out of which the %map was
113838fd1498Szrj * constructed.
113938fd1498Szrj */
114038fd1498Szrj key_compare
114138fd1498Szrj key_comp() const
114238fd1498Szrj { return _M_t.key_comp(); }
114338fd1498Szrj
114438fd1498Szrj /**
114538fd1498Szrj * Returns a value comparison object, built from the key comparison
114638fd1498Szrj * object out of which the %map was constructed.
114738fd1498Szrj */
114838fd1498Szrj value_compare
114938fd1498Szrj value_comp() const
115038fd1498Szrj { return value_compare(_M_t.key_comp()); }
115138fd1498Szrj
115238fd1498Szrj // [23.3.1.3] map operations
115338fd1498Szrj
115438fd1498Szrj //@{
115538fd1498Szrj /**
115638fd1498Szrj * @brief Tries to locate an element in a %map.
115738fd1498Szrj * @param __x Key of (key, value) %pair to be located.
115838fd1498Szrj * @return Iterator pointing to sought-after element, or end() if not
115938fd1498Szrj * found.
116038fd1498Szrj *
116138fd1498Szrj * This function takes a key and tries to locate the element with which
116238fd1498Szrj * the key matches. If successful the function returns an iterator
116338fd1498Szrj * pointing to the sought after %pair. If unsuccessful it returns the
116438fd1498Szrj * past-the-end ( @c end() ) iterator.
116538fd1498Szrj */
116638fd1498Szrj
116738fd1498Szrj iterator
116838fd1498Szrj find(const key_type& __x)
116938fd1498Szrj { return _M_t.find(__x); }
117038fd1498Szrj
117138fd1498Szrj #if __cplusplus > 201103L
117238fd1498Szrj template<typename _Kt>
117338fd1498Szrj auto
117438fd1498Szrj find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x))
117538fd1498Szrj { return _M_t._M_find_tr(__x); }
117638fd1498Szrj #endif
117738fd1498Szrj //@}
117838fd1498Szrj
117938fd1498Szrj //@{
118038fd1498Szrj /**
118138fd1498Szrj * @brief Tries to locate an element in a %map.
118238fd1498Szrj * @param __x Key of (key, value) %pair to be located.
118338fd1498Szrj * @return Read-only (constant) iterator pointing to sought-after
118438fd1498Szrj * element, or end() if not found.
118538fd1498Szrj *
118638fd1498Szrj * This function takes a key and tries to locate the element with which
118738fd1498Szrj * the key matches. If successful the function returns a constant
118838fd1498Szrj * iterator pointing to the sought after %pair. If unsuccessful it
118938fd1498Szrj * returns the past-the-end ( @c end() ) iterator.
119038fd1498Szrj */
119138fd1498Szrj
119238fd1498Szrj const_iterator
119338fd1498Szrj find(const key_type& __x) const
119438fd1498Szrj { return _M_t.find(__x); }
119538fd1498Szrj
119638fd1498Szrj #if __cplusplus > 201103L
119738fd1498Szrj template<typename _Kt>
119838fd1498Szrj auto
119938fd1498Szrj find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x))
120038fd1498Szrj { return _M_t._M_find_tr(__x); }
120138fd1498Szrj #endif
120238fd1498Szrj //@}
120338fd1498Szrj
120438fd1498Szrj //@{
120538fd1498Szrj /**
120638fd1498Szrj * @brief Finds the number of elements with given key.
120738fd1498Szrj * @param __x Key of (key, value) pairs to be located.
120838fd1498Szrj * @return Number of elements with specified key.
120938fd1498Szrj *
121038fd1498Szrj * This function only makes sense for multimaps; for map the result will
121138fd1498Szrj * either be 0 (not present) or 1 (present).
121238fd1498Szrj */
121338fd1498Szrj size_type
121438fd1498Szrj count(const key_type& __x) const
121538fd1498Szrj { return _M_t.find(__x) == _M_t.end() ? 0 : 1; }
121638fd1498Szrj
121738fd1498Szrj #if __cplusplus > 201103L
121838fd1498Szrj template<typename _Kt>
121938fd1498Szrj auto
122038fd1498Szrj count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x))
122138fd1498Szrj { return _M_t._M_count_tr(__x); }
122238fd1498Szrj #endif
122338fd1498Szrj //@}
122438fd1498Szrj
122538fd1498Szrj //@{
122638fd1498Szrj /**
122738fd1498Szrj * @brief Finds the beginning of a subsequence matching given key.
122838fd1498Szrj * @param __x Key of (key, value) pair to be located.
122938fd1498Szrj * @return Iterator pointing to first element equal to or greater
123038fd1498Szrj * than key, or end().
123138fd1498Szrj *
123238fd1498Szrj * This function returns the first element of a subsequence of elements
123338fd1498Szrj * that matches the given key. If unsuccessful it returns an iterator
123438fd1498Szrj * pointing to the first element that has a greater value than given key
123538fd1498Szrj * or end() if no such element exists.
123638fd1498Szrj */
123738fd1498Szrj iterator
123838fd1498Szrj lower_bound(const key_type& __x)
123938fd1498Szrj { return _M_t.lower_bound(__x); }
124038fd1498Szrj
124138fd1498Szrj #if __cplusplus > 201103L
124238fd1498Szrj template<typename _Kt>
124338fd1498Szrj auto
124438fd1498Szrj lower_bound(const _Kt& __x)
124538fd1498Szrj -> decltype(iterator(_M_t._M_lower_bound_tr(__x)))
124638fd1498Szrj { return iterator(_M_t._M_lower_bound_tr(__x)); }
124738fd1498Szrj #endif
124838fd1498Szrj //@}
124938fd1498Szrj
125038fd1498Szrj //@{
125138fd1498Szrj /**
125238fd1498Szrj * @brief Finds the beginning of a subsequence matching given key.
125338fd1498Szrj * @param __x Key of (key, value) pair to be located.
125438fd1498Szrj * @return Read-only (constant) iterator pointing to first element
125538fd1498Szrj * equal to or greater than key, or end().
125638fd1498Szrj *
125738fd1498Szrj * This function returns the first element of a subsequence of elements
125838fd1498Szrj * that matches the given key. If unsuccessful it returns an iterator
125938fd1498Szrj * pointing to the first element that has a greater value than given key
126038fd1498Szrj * or end() if no such element exists.
126138fd1498Szrj */
126238fd1498Szrj const_iterator
126338fd1498Szrj lower_bound(const key_type& __x) const
126438fd1498Szrj { return _M_t.lower_bound(__x); }
126538fd1498Szrj
126638fd1498Szrj #if __cplusplus > 201103L
126738fd1498Szrj template<typename _Kt>
126838fd1498Szrj auto
126938fd1498Szrj lower_bound(const _Kt& __x) const
127038fd1498Szrj -> decltype(const_iterator(_M_t._M_lower_bound_tr(__x)))
127138fd1498Szrj { return const_iterator(_M_t._M_lower_bound_tr(__x)); }
127238fd1498Szrj #endif
127338fd1498Szrj //@}
127438fd1498Szrj
127538fd1498Szrj //@{
127638fd1498Szrj /**
127738fd1498Szrj * @brief Finds the end of a subsequence matching given key.
127838fd1498Szrj * @param __x Key of (key, value) pair to be located.
127938fd1498Szrj * @return Iterator pointing to the first element
128038fd1498Szrj * greater than key, or end().
128138fd1498Szrj */
128238fd1498Szrj iterator
128338fd1498Szrj upper_bound(const key_type& __x)
128438fd1498Szrj { return _M_t.upper_bound(__x); }
128538fd1498Szrj
128638fd1498Szrj #if __cplusplus > 201103L
128738fd1498Szrj template<typename _Kt>
128838fd1498Szrj auto
128938fd1498Szrj upper_bound(const _Kt& __x)
129038fd1498Szrj -> decltype(iterator(_M_t._M_upper_bound_tr(__x)))
129138fd1498Szrj { return iterator(_M_t._M_upper_bound_tr(__x)); }
129238fd1498Szrj #endif
129338fd1498Szrj //@}
129438fd1498Szrj
129538fd1498Szrj //@{
129638fd1498Szrj /**
129738fd1498Szrj * @brief Finds the end of a subsequence matching given key.
129838fd1498Szrj * @param __x Key of (key, value) pair to be located.
129938fd1498Szrj * @return Read-only (constant) iterator pointing to first iterator
130038fd1498Szrj * greater than key, or end().
130138fd1498Szrj */
130238fd1498Szrj const_iterator
130338fd1498Szrj upper_bound(const key_type& __x) const
130438fd1498Szrj { return _M_t.upper_bound(__x); }
130538fd1498Szrj
130638fd1498Szrj #if __cplusplus > 201103L
130738fd1498Szrj template<typename _Kt>
130838fd1498Szrj auto
130938fd1498Szrj upper_bound(const _Kt& __x) const
131038fd1498Szrj -> decltype(const_iterator(_M_t._M_upper_bound_tr(__x)))
131138fd1498Szrj { return const_iterator(_M_t._M_upper_bound_tr(__x)); }
131238fd1498Szrj #endif
131338fd1498Szrj //@}
131438fd1498Szrj
131538fd1498Szrj //@{
131638fd1498Szrj /**
131738fd1498Szrj * @brief Finds a subsequence matching given key.
131838fd1498Szrj * @param __x Key of (key, value) pairs to be located.
131938fd1498Szrj * @return Pair of iterators that possibly points to the subsequence
132038fd1498Szrj * matching given key.
132138fd1498Szrj *
132238fd1498Szrj * This function is equivalent to
132338fd1498Szrj * @code
132438fd1498Szrj * std::make_pair(c.lower_bound(val),
132538fd1498Szrj * c.upper_bound(val))
132638fd1498Szrj * @endcode
132738fd1498Szrj * (but is faster than making the calls separately).
132838fd1498Szrj *
132938fd1498Szrj * This function probably only makes sense for multimaps.
133038fd1498Szrj */
133138fd1498Szrj std::pair<iterator, iterator>
133238fd1498Szrj equal_range(const key_type& __x)
133338fd1498Szrj { return _M_t.equal_range(__x); }
133438fd1498Szrj
133538fd1498Szrj #if __cplusplus > 201103L
133638fd1498Szrj template<typename _Kt>
133738fd1498Szrj auto
133838fd1498Szrj equal_range(const _Kt& __x)
133938fd1498Szrj -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)))
134038fd1498Szrj { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); }
134138fd1498Szrj #endif
134238fd1498Szrj //@}
134338fd1498Szrj
134438fd1498Szrj //@{
134538fd1498Szrj /**
134638fd1498Szrj * @brief Finds a subsequence matching given key.
134738fd1498Szrj * @param __x Key of (key, value) pairs to be located.
134838fd1498Szrj * @return Pair of read-only (constant) iterators that possibly points
134938fd1498Szrj * to the subsequence matching given key.
135038fd1498Szrj *
135138fd1498Szrj * This function is equivalent to
135238fd1498Szrj * @code
135338fd1498Szrj * std::make_pair(c.lower_bound(val),
135438fd1498Szrj * c.upper_bound(val))
135538fd1498Szrj * @endcode
135638fd1498Szrj * (but is faster than making the calls separately).
135738fd1498Szrj *
135838fd1498Szrj * This function probably only makes sense for multimaps.
135938fd1498Szrj */
136038fd1498Szrj std::pair<const_iterator, const_iterator>
136138fd1498Szrj equal_range(const key_type& __x) const
136238fd1498Szrj { return _M_t.equal_range(__x); }
136338fd1498Szrj
136438fd1498Szrj #if __cplusplus > 201103L
136538fd1498Szrj template<typename _Kt>
136638fd1498Szrj auto
136738fd1498Szrj equal_range(const _Kt& __x) const
136838fd1498Szrj -> decltype(pair<const_iterator, const_iterator>(
136938fd1498Szrj _M_t._M_equal_range_tr(__x)))
137038fd1498Szrj {
137138fd1498Szrj return pair<const_iterator, const_iterator>(
137238fd1498Szrj _M_t._M_equal_range_tr(__x));
137338fd1498Szrj }
137438fd1498Szrj #endif
137538fd1498Szrj //@}
137638fd1498Szrj
137738fd1498Szrj template<typename _K1, typename _T1, typename _C1, typename _A1>
137838fd1498Szrj friend bool
137938fd1498Szrj operator==(const map<_K1, _T1, _C1, _A1>&,
138038fd1498Szrj const map<_K1, _T1, _C1, _A1>&);
138138fd1498Szrj
138238fd1498Szrj template<typename _K1, typename _T1, typename _C1, typename _A1>
138338fd1498Szrj friend bool
138438fd1498Szrj operator<(const map<_K1, _T1, _C1, _A1>&,
138538fd1498Szrj const map<_K1, _T1, _C1, _A1>&);
138638fd1498Szrj };
138738fd1498Szrj
138838fd1498Szrj
138938fd1498Szrj #if __cpp_deduction_guides >= 201606
139038fd1498Szrj
139138fd1498Szrj template<typename _InputIterator,
139238fd1498Szrj typename _Compare = less<__iter_key_t<_InputIterator>>,
139338fd1498Szrj typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
139438fd1498Szrj typename = _RequireInputIter<_InputIterator>,
139538fd1498Szrj typename = _RequireAllocator<_Allocator>>
139638fd1498Szrj map(_InputIterator, _InputIterator,
139738fd1498Szrj _Compare = _Compare(), _Allocator = _Allocator())
139838fd1498Szrj -> map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
139938fd1498Szrj _Compare, _Allocator>;
140038fd1498Szrj
140138fd1498Szrj template<typename _Key, typename _Tp, typename _Compare = less<_Key>,
140238fd1498Szrj typename _Allocator = allocator<pair<const _Key, _Tp>>,
140338fd1498Szrj typename = _RequireAllocator<_Allocator>>
140438fd1498Szrj map(initializer_list<pair<_Key, _Tp>>,
140538fd1498Szrj _Compare = _Compare(), _Allocator = _Allocator())
140638fd1498Szrj -> map<_Key, _Tp, _Compare, _Allocator>;
140738fd1498Szrj
140838fd1498Szrj template <typename _InputIterator, typename _Allocator,
140938fd1498Szrj typename = _RequireInputIter<_InputIterator>,
141038fd1498Szrj typename = _RequireAllocator<_Allocator>>
141138fd1498Szrj map(_InputIterator, _InputIterator, _Allocator)
141238fd1498Szrj -> map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
141338fd1498Szrj less<__iter_key_t<_InputIterator>>, _Allocator>;
141438fd1498Szrj
141538fd1498Szrj template<typename _Key, typename _Tp, typename _Allocator,
141638fd1498Szrj typename = _RequireAllocator<_Allocator>>
141738fd1498Szrj map(initializer_list<pair<_Key, _Tp>>, _Allocator)
141838fd1498Szrj -> map<_Key, _Tp, less<_Key>, _Allocator>;
141938fd1498Szrj
142038fd1498Szrj #endif
142138fd1498Szrj
142238fd1498Szrj /**
142338fd1498Szrj * @brief Map equality comparison.
142438fd1498Szrj * @param __x A %map.
142538fd1498Szrj * @param __y A %map of the same type as @a x.
142638fd1498Szrj * @return True iff the size and elements of the maps are equal.
142738fd1498Szrj *
142838fd1498Szrj * This is an equivalence relation. It is linear in the size of the
142938fd1498Szrj * maps. Maps are considered equivalent if their sizes are equal,
143038fd1498Szrj * and if corresponding elements compare equal.
143138fd1498Szrj */
143238fd1498Szrj template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
143338fd1498Szrj inline bool
143438fd1498Szrj operator==(const map<_Key, _Tp, _Compare, _Alloc>& __x,
143538fd1498Szrj const map<_Key, _Tp, _Compare, _Alloc>& __y)
143638fd1498Szrj { return __x._M_t == __y._M_t; }
143738fd1498Szrj
143838fd1498Szrj /**
143938fd1498Szrj * @brief Map ordering relation.
144038fd1498Szrj * @param __x A %map.
144138fd1498Szrj * @param __y A %map of the same type as @a x.
144238fd1498Szrj * @return True iff @a x is lexicographically less than @a y.
144338fd1498Szrj *
144438fd1498Szrj * This is a total ordering relation. It is linear in the size of the
144538fd1498Szrj * maps. The elements must be comparable with @c <.
144638fd1498Szrj *
144738fd1498Szrj * See std::lexicographical_compare() for how the determination is made.
144838fd1498Szrj */
144938fd1498Szrj template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
145038fd1498Szrj inline bool
145138fd1498Szrj operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x,
145238fd1498Szrj const map<_Key, _Tp, _Compare, _Alloc>& __y)
145338fd1498Szrj { return __x._M_t < __y._M_t; }
145438fd1498Szrj
145538fd1498Szrj /// Based on operator==
145638fd1498Szrj template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
145738fd1498Szrj inline bool
145838fd1498Szrj operator!=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
145938fd1498Szrj const map<_Key, _Tp, _Compare, _Alloc>& __y)
146038fd1498Szrj { return !(__x == __y); }
146138fd1498Szrj
146238fd1498Szrj /// Based on operator<
146338fd1498Szrj template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
146438fd1498Szrj inline bool
146538fd1498Szrj operator>(const map<_Key, _Tp, _Compare, _Alloc>& __x,
146638fd1498Szrj const map<_Key, _Tp, _Compare, _Alloc>& __y)
146738fd1498Szrj { return __y < __x; }
146838fd1498Szrj
146938fd1498Szrj /// Based on operator<
147038fd1498Szrj template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
147138fd1498Szrj inline bool
147238fd1498Szrj operator<=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
147338fd1498Szrj const map<_Key, _Tp, _Compare, _Alloc>& __y)
147438fd1498Szrj { return !(__y < __x); }
147538fd1498Szrj
147638fd1498Szrj /// Based on operator<
147738fd1498Szrj template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
147838fd1498Szrj inline bool
147938fd1498Szrj operator>=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
148038fd1498Szrj const map<_Key, _Tp, _Compare, _Alloc>& __y)
148138fd1498Szrj { return !(__x < __y); }
148238fd1498Szrj
148338fd1498Szrj /// See std::map::swap().
148438fd1498Szrj template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
148538fd1498Szrj inline void
148638fd1498Szrj swap(map<_Key, _Tp, _Compare, _Alloc>& __x,
148738fd1498Szrj map<_Key, _Tp, _Compare, _Alloc>& __y)
148838fd1498Szrj _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
148938fd1498Szrj { __x.swap(__y); }
149038fd1498Szrj
149138fd1498Szrj _GLIBCXX_END_NAMESPACE_CONTAINER
149238fd1498Szrj
149338fd1498Szrj #if __cplusplus > 201402L
149438fd1498Szrj // Allow std::map access to internals of compatible maps.
149538fd1498Szrj template<typename _Key, typename _Val, typename _Cmp1, typename _Alloc,
149638fd1498Szrj typename _Cmp2>
149738fd1498Szrj struct
149838fd1498Szrj _Rb_tree_merge_helper<_GLIBCXX_STD_C::map<_Key, _Val, _Cmp1, _Alloc>,
149938fd1498Szrj _Cmp2>
150038fd1498Szrj {
150138fd1498Szrj private:
150238fd1498Szrj friend class _GLIBCXX_STD_C::map<_Key, _Val, _Cmp1, _Alloc>;
150338fd1498Szrj
150438fd1498Szrj static auto&
150538fd1498Szrj _S_get_tree(_GLIBCXX_STD_C::map<_Key, _Val, _Cmp2, _Alloc>& __map)
150638fd1498Szrj { return __map._M_t; }
150738fd1498Szrj
150838fd1498Szrj static auto&
150938fd1498Szrj _S_get_tree(_GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp2, _Alloc>& __map)
151038fd1498Szrj { return __map._M_t; }
151138fd1498Szrj };
151238fd1498Szrj #endif // C++17
151338fd1498Szrj
151438fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
151538fd1498Szrj } // namespace std
151638fd1498Szrj
151738fd1498Szrj #endif /* _STL_MAP_H */
1518