xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_map.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
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