xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_multimap.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj // Multimap 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_multimap.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_MULTIMAP_H
5738fd1498Szrj #define _STL_MULTIMAP_H 1
5838fd1498Szrj 
5938fd1498Szrj #include <bits/concept_check.h>
6038fd1498Szrj #if __cplusplus >= 201103L
6138fd1498Szrj #include <initializer_list>
6238fd1498Szrj #endif
6338fd1498Szrj 
_GLIBCXX_VISIBILITY(default)6438fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
6538fd1498Szrj {
6638fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
6738fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
6838fd1498Szrj 
6938fd1498Szrj   template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
7038fd1498Szrj     class map;
7138fd1498Szrj 
7238fd1498Szrj   /**
7338fd1498Szrj    *  @brief A standard container made up of (key,value) pairs, which can be
7438fd1498Szrj    *  retrieved based on a key, in logarithmic time.
7538fd1498Szrj    *
7638fd1498Szrj    *  @ingroup associative_containers
7738fd1498Szrj    *
7838fd1498Szrj    *  @tparam _Key  Type of key objects.
7938fd1498Szrj    *  @tparam  _Tp  Type of mapped objects.
8038fd1498Szrj    *  @tparam _Compare  Comparison function object type, defaults to less<_Key>.
8138fd1498Szrj    *  @tparam _Alloc  Allocator type, defaults to
8238fd1498Szrj    *                  allocator<pair<const _Key, _Tp>.
8338fd1498Szrj    *
8438fd1498Szrj    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
8538fd1498Szrj    *  <a href="tables.html#66">reversible container</a>, and an
8638fd1498Szrj    *  <a href="tables.html#69">associative container</a> (using equivalent
8738fd1498Szrj    *  keys).  For a @c multimap<Key,T> the key_type is Key, the mapped_type
8838fd1498Szrj    *  is T, and the value_type is std::pair<const Key,T>.
8938fd1498Szrj    *
9038fd1498Szrj    *  Multimaps support bidirectional iterators.
9138fd1498Szrj    *
9238fd1498Szrj    *  The private tree data is declared exactly the same way for map and
9338fd1498Szrj    *  multimap; the distinction is made entirely in how the tree functions are
9438fd1498Szrj    *  called (*_unique versus *_equal, same as the standard).
9538fd1498Szrj   */
9638fd1498Szrj   template <typename _Key, typename _Tp,
9738fd1498Szrj 	    typename _Compare = std::less<_Key>,
9838fd1498Szrj 	    typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
9938fd1498Szrj     class multimap
10038fd1498Szrj     {
10138fd1498Szrj     public:
10238fd1498Szrj       typedef _Key					key_type;
10338fd1498Szrj       typedef _Tp					mapped_type;
10438fd1498Szrj       typedef std::pair<const _Key, _Tp>		value_type;
10538fd1498Szrj       typedef _Compare					key_compare;
10638fd1498Szrj       typedef _Alloc					allocator_type;
10738fd1498Szrj 
10838fd1498Szrj     private:
10938fd1498Szrj #ifdef _GLIBCXX_CONCEPT_CHECKS
11038fd1498Szrj       // concept requirements
11138fd1498Szrj       typedef typename _Alloc::value_type		_Alloc_value_type;
11238fd1498Szrj # if __cplusplus < 201103L
11338fd1498Szrj       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
11438fd1498Szrj # endif
11538fd1498Szrj       __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
11638fd1498Szrj 				_BinaryFunctionConcept)
11738fd1498Szrj       __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
11838fd1498Szrj #endif
11938fd1498Szrj 
12038fd1498Szrj #if __cplusplus >= 201103L && defined(__STRICT_ANSI__)
12138fd1498Szrj       static_assert(is_same<typename _Alloc::value_type, value_type>::value,
12238fd1498Szrj 	  "std::multimap must have the same value_type as its allocator");
12338fd1498Szrj #endif
12438fd1498Szrj 
12538fd1498Szrj     public:
12638fd1498Szrj       class value_compare
12738fd1498Szrj       : public std::binary_function<value_type, value_type, bool>
12838fd1498Szrj       {
12938fd1498Szrj 	friend class multimap<_Key, _Tp, _Compare, _Alloc>;
13038fd1498Szrj       protected:
13138fd1498Szrj 	_Compare comp;
13238fd1498Szrj 
13338fd1498Szrj 	value_compare(_Compare __c)
13438fd1498Szrj 	: comp(__c) { }
13538fd1498Szrj 
13638fd1498Szrj       public:
13738fd1498Szrj 	bool operator()(const value_type& __x, const value_type& __y) const
13838fd1498Szrj 	{ return comp(__x.first, __y.first); }
13938fd1498Szrj       };
14038fd1498Szrj 
14138fd1498Szrj     private:
14238fd1498Szrj       /// This turns a red-black tree into a [multi]map.
14338fd1498Szrj       typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
14438fd1498Szrj 	rebind<value_type>::other _Pair_alloc_type;
14538fd1498Szrj 
14638fd1498Szrj       typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
14738fd1498Szrj 		       key_compare, _Pair_alloc_type> _Rep_type;
14838fd1498Szrj       /// The actual tree structure.
14938fd1498Szrj       _Rep_type _M_t;
15038fd1498Szrj 
15138fd1498Szrj       typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits;
15238fd1498Szrj 
15338fd1498Szrj     public:
15438fd1498Szrj       // many of these are specified differently in ISO, but the following are
15538fd1498Szrj       // "functionally equivalent"
15638fd1498Szrj       typedef typename _Alloc_traits::pointer		 pointer;
15738fd1498Szrj       typedef typename _Alloc_traits::const_pointer	 const_pointer;
15838fd1498Szrj       typedef typename _Alloc_traits::reference		 reference;
15938fd1498Szrj       typedef typename _Alloc_traits::const_reference	 const_reference;
16038fd1498Szrj       typedef typename _Rep_type::iterator		 iterator;
16138fd1498Szrj       typedef typename _Rep_type::const_iterator	 const_iterator;
16238fd1498Szrj       typedef typename _Rep_type::size_type		 size_type;
16338fd1498Szrj       typedef typename _Rep_type::difference_type	 difference_type;
16438fd1498Szrj       typedef typename _Rep_type::reverse_iterator	 reverse_iterator;
16538fd1498Szrj       typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
16638fd1498Szrj 
16738fd1498Szrj #if __cplusplus > 201402L
16838fd1498Szrj       using node_type = typename _Rep_type::node_type;
16938fd1498Szrj #endif
17038fd1498Szrj 
17138fd1498Szrj       // [23.3.2] construct/copy/destroy
17238fd1498Szrj       // (get_allocator() is also listed in this section)
17338fd1498Szrj 
17438fd1498Szrj       /**
17538fd1498Szrj        *  @brief  Default constructor creates no elements.
17638fd1498Szrj        */
17738fd1498Szrj #if __cplusplus < 201103L
17838fd1498Szrj       multimap() : _M_t() { }
17938fd1498Szrj #else
18038fd1498Szrj       multimap() = default;
18138fd1498Szrj #endif
18238fd1498Szrj 
18338fd1498Szrj       /**
18438fd1498Szrj        *  @brief  Creates a %multimap with no elements.
18538fd1498Szrj        *  @param  __comp  A comparison object.
18638fd1498Szrj        *  @param  __a  An allocator object.
18738fd1498Szrj        */
18838fd1498Szrj       explicit
18938fd1498Szrj       multimap(const _Compare& __comp,
19038fd1498Szrj 	       const allocator_type& __a = allocator_type())
19138fd1498Szrj       : _M_t(__comp, _Pair_alloc_type(__a)) { }
19238fd1498Szrj 
19338fd1498Szrj       /**
19438fd1498Szrj        *  @brief  %Multimap copy constructor.
19538fd1498Szrj        *
19638fd1498Szrj        *  Whether the allocator is copied depends on the allocator traits.
19738fd1498Szrj        */
19838fd1498Szrj #if __cplusplus < 201103L
19938fd1498Szrj       multimap(const multimap& __x)
20038fd1498Szrj       : _M_t(__x._M_t) { }
20138fd1498Szrj #else
20238fd1498Szrj       multimap(const multimap&) = default;
20338fd1498Szrj 
20438fd1498Szrj       /**
20538fd1498Szrj        *  @brief  %Multimap move constructor.
20638fd1498Szrj        *
20738fd1498Szrj        *  The newly-created %multimap contains the exact contents of the
20838fd1498Szrj        *  moved instance. The moved instance is a valid, but unspecified
20938fd1498Szrj        *  %multimap.
21038fd1498Szrj        */
21138fd1498Szrj       multimap(multimap&&) = default;
21238fd1498Szrj 
21338fd1498Szrj       /**
21438fd1498Szrj        *  @brief  Builds a %multimap from an initializer_list.
21538fd1498Szrj        *  @param  __l  An initializer_list.
21638fd1498Szrj        *  @param  __comp  A comparison functor.
21738fd1498Szrj        *  @param  __a  An allocator object.
21838fd1498Szrj        *
21938fd1498Szrj        *  Create a %multimap consisting of copies of the elements from
22038fd1498Szrj        *  the initializer_list.  This is linear in N if the list is already
22138fd1498Szrj        *  sorted, and NlogN otherwise (where N is @a __l.size()).
22238fd1498Szrj        */
22338fd1498Szrj       multimap(initializer_list<value_type> __l,
22438fd1498Szrj 	       const _Compare& __comp = _Compare(),
22538fd1498Szrj 	       const allocator_type& __a = allocator_type())
22638fd1498Szrj       : _M_t(__comp, _Pair_alloc_type(__a))
22738fd1498Szrj       { _M_t._M_insert_equal(__l.begin(), __l.end()); }
22838fd1498Szrj 
22938fd1498Szrj       /// Allocator-extended default constructor.
23038fd1498Szrj       explicit
23138fd1498Szrj       multimap(const allocator_type& __a)
23238fd1498Szrj       : _M_t(_Compare(), _Pair_alloc_type(__a)) { }
23338fd1498Szrj 
23438fd1498Szrj       /// Allocator-extended copy constructor.
23538fd1498Szrj       multimap(const multimap& __m, const allocator_type& __a)
23638fd1498Szrj       : _M_t(__m._M_t, _Pair_alloc_type(__a)) { }
23738fd1498Szrj 
23838fd1498Szrj       /// Allocator-extended move constructor.
23938fd1498Szrj       multimap(multimap&& __m, const allocator_type& __a)
24038fd1498Szrj       noexcept(is_nothrow_copy_constructible<_Compare>::value
24138fd1498Szrj 	       && _Alloc_traits::_S_always_equal())
24238fd1498Szrj       : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { }
24338fd1498Szrj 
24438fd1498Szrj       /// Allocator-extended initialier-list constructor.
24538fd1498Szrj       multimap(initializer_list<value_type> __l, const allocator_type& __a)
24638fd1498Szrj       : _M_t(_Compare(), _Pair_alloc_type(__a))
24738fd1498Szrj       { _M_t._M_insert_equal(__l.begin(), __l.end()); }
24838fd1498Szrj 
24938fd1498Szrj       /// Allocator-extended range constructor.
25038fd1498Szrj       template<typename _InputIterator>
25138fd1498Szrj 	multimap(_InputIterator __first, _InputIterator __last,
25238fd1498Szrj 		 const allocator_type& __a)
25338fd1498Szrj 	: _M_t(_Compare(), _Pair_alloc_type(__a))
25438fd1498Szrj 	{ _M_t._M_insert_equal(__first, __last); }
25538fd1498Szrj #endif
25638fd1498Szrj 
25738fd1498Szrj       /**
25838fd1498Szrj        *  @brief  Builds a %multimap from a range.
25938fd1498Szrj        *  @param  __first  An input iterator.
26038fd1498Szrj        *  @param  __last  An input iterator.
26138fd1498Szrj        *
26238fd1498Szrj        *  Create a %multimap consisting of copies of the elements from
26338fd1498Szrj        *  [__first,__last).  This is linear in N if the range is already sorted,
26438fd1498Szrj        *  and NlogN otherwise (where N is distance(__first,__last)).
26538fd1498Szrj        */
26638fd1498Szrj       template<typename _InputIterator>
26738fd1498Szrj 	multimap(_InputIterator __first, _InputIterator __last)
26838fd1498Szrj 	: _M_t()
26938fd1498Szrj 	{ _M_t._M_insert_equal(__first, __last); }
27038fd1498Szrj 
27138fd1498Szrj       /**
27238fd1498Szrj        *  @brief  Builds a %multimap from a range.
27338fd1498Szrj        *  @param  __first  An input iterator.
27438fd1498Szrj        *  @param  __last  An input iterator.
27538fd1498Szrj        *  @param  __comp  A comparison functor.
27638fd1498Szrj        *  @param  __a  An allocator object.
27738fd1498Szrj        *
27838fd1498Szrj        *  Create a %multimap consisting of copies of the elements from
27938fd1498Szrj        *  [__first,__last).  This is linear in N if the range is already sorted,
28038fd1498Szrj        *  and NlogN otherwise (where N is distance(__first,__last)).
28138fd1498Szrj        */
28238fd1498Szrj       template<typename _InputIterator>
28338fd1498Szrj 	multimap(_InputIterator __first, _InputIterator __last,
28438fd1498Szrj 		 const _Compare& __comp,
28538fd1498Szrj 		 const allocator_type& __a = allocator_type())
28638fd1498Szrj 	: _M_t(__comp, _Pair_alloc_type(__a))
28738fd1498Szrj 	{ _M_t._M_insert_equal(__first, __last); }
28838fd1498Szrj 
28938fd1498Szrj #if __cplusplus >= 201103L
29038fd1498Szrj       /**
29138fd1498Szrj        *  The dtor only erases the elements, and note that if the elements
29238fd1498Szrj        *  themselves are pointers, the pointed-to memory is not touched in any
29338fd1498Szrj        *  way. Managing the pointer is the user's responsibility.
29438fd1498Szrj        */
29538fd1498Szrj       ~multimap() = default;
29638fd1498Szrj #endif
29738fd1498Szrj 
29838fd1498Szrj       /**
29938fd1498Szrj        *  @brief  %Multimap assignment operator.
30038fd1498Szrj        *
30138fd1498Szrj        *  Whether the allocator is copied depends on the allocator traits.
30238fd1498Szrj        */
30338fd1498Szrj #if __cplusplus < 201103L
30438fd1498Szrj       multimap&
30538fd1498Szrj       operator=(const multimap& __x)
30638fd1498Szrj       {
30738fd1498Szrj 	_M_t = __x._M_t;
30838fd1498Szrj 	return *this;
30938fd1498Szrj       }
31038fd1498Szrj #else
31138fd1498Szrj       multimap&
31238fd1498Szrj       operator=(const multimap&) = default;
31338fd1498Szrj 
31438fd1498Szrj       /// Move assignment operator.
31538fd1498Szrj       multimap&
31638fd1498Szrj       operator=(multimap&&) = default;
31738fd1498Szrj 
31838fd1498Szrj       /**
31938fd1498Szrj        *  @brief  %Multimap list assignment operator.
32038fd1498Szrj        *  @param  __l  An initializer_list.
32138fd1498Szrj        *
32238fd1498Szrj        *  This function fills a %multimap with copies of the elements
32338fd1498Szrj        *  in the initializer list @a __l.
32438fd1498Szrj        *
32538fd1498Szrj        *  Note that the assignment completely changes the %multimap and
32638fd1498Szrj        *  that the resulting %multimap's size is the same as the number
32738fd1498Szrj        *  of elements assigned.
32838fd1498Szrj        */
32938fd1498Szrj       multimap&
33038fd1498Szrj       operator=(initializer_list<value_type> __l)
33138fd1498Szrj       {
33238fd1498Szrj 	_M_t._M_assign_equal(__l.begin(), __l.end());
33338fd1498Szrj 	return *this;
33438fd1498Szrj       }
33538fd1498Szrj #endif
33638fd1498Szrj 
33738fd1498Szrj       /// Get a copy of the memory allocation object.
33838fd1498Szrj       allocator_type
33938fd1498Szrj       get_allocator() const _GLIBCXX_NOEXCEPT
34038fd1498Szrj       { return allocator_type(_M_t.get_allocator()); }
34138fd1498Szrj 
34238fd1498Szrj       // iterators
34338fd1498Szrj       /**
34438fd1498Szrj        *  Returns a read/write iterator that points to the first pair in the
34538fd1498Szrj        *  %multimap.  Iteration is done in ascending order according to the
34638fd1498Szrj        *  keys.
34738fd1498Szrj        */
34838fd1498Szrj       iterator
34938fd1498Szrj       begin() _GLIBCXX_NOEXCEPT
35038fd1498Szrj       { return _M_t.begin(); }
35138fd1498Szrj 
35238fd1498Szrj       /**
35338fd1498Szrj        *  Returns a read-only (constant) iterator that points to the first pair
35438fd1498Szrj        *  in the %multimap.  Iteration is done in ascending order according to
35538fd1498Szrj        *  the keys.
35638fd1498Szrj        */
35738fd1498Szrj       const_iterator
35838fd1498Szrj       begin() const _GLIBCXX_NOEXCEPT
35938fd1498Szrj       { return _M_t.begin(); }
36038fd1498Szrj 
36138fd1498Szrj       /**
36238fd1498Szrj        *  Returns a read/write iterator that points one past the last pair in
36338fd1498Szrj        *  the %multimap.  Iteration is done in ascending order according to the
36438fd1498Szrj        *  keys.
36538fd1498Szrj        */
36638fd1498Szrj       iterator
36738fd1498Szrj       end() _GLIBCXX_NOEXCEPT
36838fd1498Szrj       { return _M_t.end(); }
36938fd1498Szrj 
37038fd1498Szrj       /**
37138fd1498Szrj        *  Returns a read-only (constant) iterator that points one past the last
37238fd1498Szrj        *  pair in the %multimap.  Iteration is done in ascending order according
37338fd1498Szrj        *  to the keys.
37438fd1498Szrj        */
37538fd1498Szrj       const_iterator
37638fd1498Szrj       end() const _GLIBCXX_NOEXCEPT
37738fd1498Szrj       { return _M_t.end(); }
37838fd1498Szrj 
37938fd1498Szrj       /**
38038fd1498Szrj        *  Returns a read/write reverse iterator that points to the last pair in
38138fd1498Szrj        *  the %multimap.  Iteration is done in descending order according to the
38238fd1498Szrj        *  keys.
38338fd1498Szrj        */
38438fd1498Szrj       reverse_iterator
38538fd1498Szrj       rbegin() _GLIBCXX_NOEXCEPT
38638fd1498Szrj       { return _M_t.rbegin(); }
38738fd1498Szrj 
38838fd1498Szrj       /**
38938fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points to the
39038fd1498Szrj        *  last pair in the %multimap.  Iteration is done in descending order
39138fd1498Szrj        *  according to the keys.
39238fd1498Szrj        */
39338fd1498Szrj       const_reverse_iterator
39438fd1498Szrj       rbegin() const _GLIBCXX_NOEXCEPT
39538fd1498Szrj       { return _M_t.rbegin(); }
39638fd1498Szrj 
39738fd1498Szrj       /**
39838fd1498Szrj        *  Returns a read/write reverse iterator that points to one before the
39938fd1498Szrj        *  first pair in the %multimap.  Iteration is done in descending order
40038fd1498Szrj        *  according to the keys.
40138fd1498Szrj        */
40238fd1498Szrj       reverse_iterator
40338fd1498Szrj       rend() _GLIBCXX_NOEXCEPT
40438fd1498Szrj       { return _M_t.rend(); }
40538fd1498Szrj 
40638fd1498Szrj       /**
40738fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points to one
40838fd1498Szrj        *  before the first pair in the %multimap.  Iteration is done in
40938fd1498Szrj        *  descending order according to the keys.
41038fd1498Szrj        */
41138fd1498Szrj       const_reverse_iterator
41238fd1498Szrj       rend() const _GLIBCXX_NOEXCEPT
41338fd1498Szrj       { return _M_t.rend(); }
41438fd1498Szrj 
41538fd1498Szrj #if __cplusplus >= 201103L
41638fd1498Szrj       /**
41738fd1498Szrj        *  Returns a read-only (constant) iterator that points to the first pair
41838fd1498Szrj        *  in the %multimap.  Iteration is done in ascending order according to
41938fd1498Szrj        *  the keys.
42038fd1498Szrj        */
42138fd1498Szrj       const_iterator
42238fd1498Szrj       cbegin() const noexcept
42338fd1498Szrj       { return _M_t.begin(); }
42438fd1498Szrj 
42538fd1498Szrj       /**
42638fd1498Szrj        *  Returns a read-only (constant) iterator that points one past the last
42738fd1498Szrj        *  pair in the %multimap.  Iteration is done in ascending order according
42838fd1498Szrj        *  to the keys.
42938fd1498Szrj        */
43038fd1498Szrj       const_iterator
43138fd1498Szrj       cend() const noexcept
43238fd1498Szrj       { return _M_t.end(); }
43338fd1498Szrj 
43438fd1498Szrj       /**
43538fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points to the
43638fd1498Szrj        *  last pair in the %multimap.  Iteration is done in descending order
43738fd1498Szrj        *  according to the keys.
43838fd1498Szrj        */
43938fd1498Szrj       const_reverse_iterator
44038fd1498Szrj       crbegin() const noexcept
44138fd1498Szrj       { return _M_t.rbegin(); }
44238fd1498Szrj 
44338fd1498Szrj       /**
44438fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points to one
44538fd1498Szrj        *  before the first pair in the %multimap.  Iteration is done in
44638fd1498Szrj        *  descending order according to the keys.
44738fd1498Szrj        */
44838fd1498Szrj       const_reverse_iterator
44938fd1498Szrj       crend() const noexcept
45038fd1498Szrj       { return _M_t.rend(); }
45138fd1498Szrj #endif
45238fd1498Szrj 
45338fd1498Szrj       // capacity
45438fd1498Szrj       /** Returns true if the %multimap is empty.  */
45538fd1498Szrj       bool
45638fd1498Szrj       empty() const _GLIBCXX_NOEXCEPT
45738fd1498Szrj       { return _M_t.empty(); }
45838fd1498Szrj 
45938fd1498Szrj       /** Returns the size of the %multimap.  */
46038fd1498Szrj       size_type
46138fd1498Szrj       size() const _GLIBCXX_NOEXCEPT
46238fd1498Szrj       { return _M_t.size(); }
46338fd1498Szrj 
46438fd1498Szrj       /** Returns the maximum size of the %multimap.  */
46538fd1498Szrj       size_type
46638fd1498Szrj       max_size() const _GLIBCXX_NOEXCEPT
46738fd1498Szrj       { return _M_t.max_size(); }
46838fd1498Szrj 
46938fd1498Szrj       // modifiers
47038fd1498Szrj #if __cplusplus >= 201103L
47138fd1498Szrj       /**
47238fd1498Szrj        *  @brief Build and insert a std::pair into the %multimap.
47338fd1498Szrj        *
47438fd1498Szrj        *  @param __args  Arguments used to generate a new pair instance (see
47538fd1498Szrj        *	        std::piecewise_contruct for passing arguments to each
47638fd1498Szrj        *	        part of the pair constructor).
47738fd1498Szrj        *
47838fd1498Szrj        *  @return An iterator that points to the inserted (key,value) pair.
47938fd1498Szrj        *
48038fd1498Szrj        *  This function builds and inserts a (key, value) %pair into the
48138fd1498Szrj        *  %multimap.
48238fd1498Szrj        *  Contrary to a std::map the %multimap does not rely on unique keys and
48338fd1498Szrj        *  thus multiple pairs with the same key can be inserted.
48438fd1498Szrj        *
48538fd1498Szrj        *  Insertion requires logarithmic time.
48638fd1498Szrj        */
48738fd1498Szrj       template<typename... _Args>
48838fd1498Szrj 	iterator
48938fd1498Szrj 	emplace(_Args&&... __args)
49038fd1498Szrj 	{ return _M_t._M_emplace_equal(std::forward<_Args>(__args)...); }
49138fd1498Szrj 
49238fd1498Szrj       /**
49338fd1498Szrj        *  @brief Builds and inserts a std::pair into the %multimap.
49438fd1498Szrj        *
49538fd1498Szrj        *  @param  __pos  An iterator that serves as a hint as to where the pair
49638fd1498Szrj        *                should be inserted.
49738fd1498Szrj        *  @param  __args  Arguments used to generate a new pair instance (see
49838fd1498Szrj        *	         std::piecewise_contruct for passing arguments to each
49938fd1498Szrj        *	         part of the pair constructor).
50038fd1498Szrj        *  @return An iterator that points to the inserted (key,value) pair.
50138fd1498Szrj        *
50238fd1498Szrj        *  This function inserts a (key, value) pair into the %multimap.
50338fd1498Szrj        *  Contrary to a std::map the %multimap does not rely on unique keys and
50438fd1498Szrj        *  thus multiple pairs with the same key can be inserted.
50538fd1498Szrj        *  Note that the first parameter is only a hint and can potentially
50638fd1498Szrj        *  improve the performance of the insertion process.  A bad hint would
50738fd1498Szrj        *  cause no gains in efficiency.
50838fd1498Szrj        *
50938fd1498Szrj        *  For more on @a hinting, see:
51038fd1498Szrj        *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
51138fd1498Szrj        *
51238fd1498Szrj        *  Insertion requires logarithmic time (if the hint is not taken).
51338fd1498Szrj        */
51438fd1498Szrj       template<typename... _Args>
51538fd1498Szrj 	iterator
51638fd1498Szrj 	emplace_hint(const_iterator __pos, _Args&&... __args)
51738fd1498Szrj 	{
51838fd1498Szrj 	  return _M_t._M_emplace_hint_equal(__pos,
51938fd1498Szrj 					    std::forward<_Args>(__args)...);
52038fd1498Szrj 	}
52138fd1498Szrj #endif
52238fd1498Szrj 
52338fd1498Szrj       /**
52438fd1498Szrj        *  @brief Inserts a std::pair into the %multimap.
52538fd1498Szrj        *  @param  __x  Pair to be inserted (see std::make_pair for easy creation
52638fd1498Szrj        *             of pairs).
52738fd1498Szrj        *  @return An iterator that points to the inserted (key,value) pair.
52838fd1498Szrj        *
52938fd1498Szrj        *  This function inserts a (key, value) pair into the %multimap.
53038fd1498Szrj        *  Contrary to a std::map the %multimap does not rely on unique keys and
53138fd1498Szrj        *  thus multiple pairs with the same key can be inserted.
53238fd1498Szrj        *
53338fd1498Szrj        *  Insertion requires logarithmic time.
53438fd1498Szrj        *  @{
53538fd1498Szrj        */
53638fd1498Szrj       iterator
53738fd1498Szrj       insert(const value_type& __x)
53838fd1498Szrj       { return _M_t._M_insert_equal(__x); }
53938fd1498Szrj 
54038fd1498Szrj #if __cplusplus >= 201103L
54138fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
54238fd1498Szrj       // 2354. Unnecessary copying when inserting into maps with braced-init
54338fd1498Szrj       iterator
54438fd1498Szrj       insert(value_type&& __x)
54538fd1498Szrj       { return _M_t._M_insert_equal(std::move(__x)); }
54638fd1498Szrj 
547*58e805e6Szrj       template<typename _Pair>
548*58e805e6Szrj 	__enable_if_t<is_constructible<value_type, _Pair>::value, iterator>
54938fd1498Szrj 	insert(_Pair&& __x)
550*58e805e6Szrj 	{ return _M_t._M_emplace_equal(std::forward<_Pair>(__x)); }
55138fd1498Szrj #endif
55238fd1498Szrj       // @}
55338fd1498Szrj 
55438fd1498Szrj       /**
55538fd1498Szrj        *  @brief Inserts a std::pair into the %multimap.
55638fd1498Szrj        *  @param  __position  An iterator that serves as a hint as to where the
55738fd1498Szrj        *                      pair should be inserted.
55838fd1498Szrj        *  @param  __x  Pair to be inserted (see std::make_pair for easy creation
55938fd1498Szrj        *               of pairs).
56038fd1498Szrj        *  @return An iterator that points to the inserted (key,value) pair.
56138fd1498Szrj        *
56238fd1498Szrj        *  This function inserts a (key, value) pair into the %multimap.
56338fd1498Szrj        *  Contrary to a std::map the %multimap does not rely on unique keys and
56438fd1498Szrj        *  thus multiple pairs with the same key can be inserted.
56538fd1498Szrj        *  Note that the first parameter is only a hint and can potentially
56638fd1498Szrj        *  improve the performance of the insertion process.  A bad hint would
56738fd1498Szrj        *  cause no gains in efficiency.
56838fd1498Szrj        *
56938fd1498Szrj        *  For more on @a hinting, see:
57038fd1498Szrj        *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
57138fd1498Szrj        *
57238fd1498Szrj        *  Insertion requires logarithmic time (if the hint is not taken).
57338fd1498Szrj        * @{
57438fd1498Szrj        */
57538fd1498Szrj       iterator
57638fd1498Szrj #if __cplusplus >= 201103L
57738fd1498Szrj       insert(const_iterator __position, const value_type& __x)
57838fd1498Szrj #else
57938fd1498Szrj       insert(iterator __position, const value_type& __x)
58038fd1498Szrj #endif
58138fd1498Szrj       { return _M_t._M_insert_equal_(__position, __x); }
58238fd1498Szrj 
58338fd1498Szrj #if __cplusplus >= 201103L
58438fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
58538fd1498Szrj       // 2354. Unnecessary copying when inserting into maps with braced-init
58638fd1498Szrj       iterator
58738fd1498Szrj       insert(const_iterator __position, value_type&& __x)
58838fd1498Szrj       { return _M_t._M_insert_equal_(__position, std::move(__x)); }
58938fd1498Szrj 
590*58e805e6Szrj       template<typename _Pair>
591*58e805e6Szrj 	__enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator>
59238fd1498Szrj 	insert(const_iterator __position, _Pair&& __x)
593*58e805e6Szrj 	{
594*58e805e6Szrj 	  return _M_t._M_emplace_hint_equal(__position,
595*58e805e6Szrj 					    std::forward<_Pair>(__x));
596*58e805e6Szrj 	}
59738fd1498Szrj #endif
59838fd1498Szrj       // @}
59938fd1498Szrj 
60038fd1498Szrj       /**
60138fd1498Szrj        *  @brief A template function that attempts to insert a range
60238fd1498Szrj        *  of elements.
60338fd1498Szrj        *  @param  __first  Iterator pointing to the start of the range to be
60438fd1498Szrj        *                   inserted.
60538fd1498Szrj        *  @param  __last  Iterator pointing to the end of the range.
60638fd1498Szrj        *
60738fd1498Szrj        *  Complexity similar to that of the range constructor.
60838fd1498Szrj        */
60938fd1498Szrj       template<typename _InputIterator>
61038fd1498Szrj 	void
61138fd1498Szrj 	insert(_InputIterator __first, _InputIterator __last)
61238fd1498Szrj 	{ _M_t._M_insert_equal(__first, __last); }
61338fd1498Szrj 
61438fd1498Szrj #if __cplusplus >= 201103L
61538fd1498Szrj       /**
61638fd1498Szrj        *  @brief Attempts to insert a list of std::pairs into the %multimap.
61738fd1498Szrj        *  @param  __l  A std::initializer_list<value_type> of pairs to be
61838fd1498Szrj        *               inserted.
61938fd1498Szrj        *
62038fd1498Szrj        *  Complexity similar to that of the range constructor.
62138fd1498Szrj        */
62238fd1498Szrj       void
62338fd1498Szrj       insert(initializer_list<value_type> __l)
62438fd1498Szrj       { this->insert(__l.begin(), __l.end()); }
62538fd1498Szrj #endif
62638fd1498Szrj 
62738fd1498Szrj #if __cplusplus > 201402L
62838fd1498Szrj       /// Extract a node.
62938fd1498Szrj       node_type
63038fd1498Szrj       extract(const_iterator __pos)
63138fd1498Szrj       {
63238fd1498Szrj 	__glibcxx_assert(__pos != end());
63338fd1498Szrj 	return _M_t.extract(__pos);
63438fd1498Szrj       }
63538fd1498Szrj 
63638fd1498Szrj       /// Extract a node.
63738fd1498Szrj       node_type
63838fd1498Szrj       extract(const key_type& __x)
63938fd1498Szrj       { return _M_t.extract(__x); }
64038fd1498Szrj 
64138fd1498Szrj       /// Re-insert an extracted node.
64238fd1498Szrj       iterator
64338fd1498Szrj       insert(node_type&& __nh)
64438fd1498Szrj       { return _M_t._M_reinsert_node_equal(std::move(__nh)); }
64538fd1498Szrj 
64638fd1498Szrj       /// Re-insert an extracted node.
64738fd1498Szrj       iterator
64838fd1498Szrj       insert(const_iterator __hint, node_type&& __nh)
64938fd1498Szrj       { return _M_t._M_reinsert_node_hint_equal(__hint, std::move(__nh)); }
65038fd1498Szrj 
65138fd1498Szrj       template<typename, typename>
65238fd1498Szrj 	friend class std::_Rb_tree_merge_helper;
65338fd1498Szrj 
65438fd1498Szrj       template<typename _C2>
65538fd1498Szrj 	void
65638fd1498Szrj 	merge(multimap<_Key, _Tp, _C2, _Alloc>& __source)
65738fd1498Szrj 	{
65838fd1498Szrj 	  using _Merge_helper = _Rb_tree_merge_helper<multimap, _C2>;
65938fd1498Szrj 	  _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source));
66038fd1498Szrj 	}
66138fd1498Szrj 
66238fd1498Szrj       template<typename _C2>
66338fd1498Szrj 	void
66438fd1498Szrj 	merge(multimap<_Key, _Tp, _C2, _Alloc>&& __source)
66538fd1498Szrj 	{ merge(__source); }
66638fd1498Szrj 
66738fd1498Szrj       template<typename _C2>
66838fd1498Szrj 	void
66938fd1498Szrj 	merge(map<_Key, _Tp, _C2, _Alloc>& __source)
67038fd1498Szrj 	{
67138fd1498Szrj 	  using _Merge_helper = _Rb_tree_merge_helper<multimap, _C2>;
67238fd1498Szrj 	  _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source));
67338fd1498Szrj 	}
67438fd1498Szrj 
67538fd1498Szrj       template<typename _C2>
67638fd1498Szrj 	void
67738fd1498Szrj 	merge(map<_Key, _Tp, _C2, _Alloc>&& __source)
67838fd1498Szrj 	{ merge(__source); }
67938fd1498Szrj #endif // C++17
68038fd1498Szrj 
68138fd1498Szrj #if __cplusplus >= 201103L
68238fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
68338fd1498Szrj       // DR 130. Associative erase should return an iterator.
68438fd1498Szrj       /**
68538fd1498Szrj        *  @brief Erases an element from a %multimap.
68638fd1498Szrj        *  @param  __position  An iterator pointing to the element to be erased.
68738fd1498Szrj        *  @return An iterator pointing to the element immediately following
68838fd1498Szrj        *          @a position prior to the element being erased. If no such
68938fd1498Szrj        *          element exists, end() is returned.
69038fd1498Szrj        *
69138fd1498Szrj        *  This function erases an element, pointed to by the given iterator,
69238fd1498Szrj        *  from a %multimap.  Note that this function only erases the element,
69338fd1498Szrj        *  and that if the element is itself a pointer, the pointed-to memory is
69438fd1498Szrj        *  not touched in any way.  Managing the pointer is the user's
69538fd1498Szrj        *  responsibility.
69638fd1498Szrj        *
69738fd1498Szrj        * @{
69838fd1498Szrj        */
69938fd1498Szrj       iterator
70038fd1498Szrj       erase(const_iterator __position)
70138fd1498Szrj       { return _M_t.erase(__position); }
70238fd1498Szrj 
70338fd1498Szrj       // LWG 2059.
70438fd1498Szrj       _GLIBCXX_ABI_TAG_CXX11
70538fd1498Szrj       iterator
70638fd1498Szrj       erase(iterator __position)
70738fd1498Szrj       { return _M_t.erase(__position); }
70838fd1498Szrj       // @}
70938fd1498Szrj #else
71038fd1498Szrj       /**
71138fd1498Szrj        *  @brief Erases an element from a %multimap.
71238fd1498Szrj        *  @param  __position  An iterator pointing to the element to be erased.
71338fd1498Szrj        *
71438fd1498Szrj        *  This function erases an element, pointed to by the given iterator,
71538fd1498Szrj        *  from a %multimap.  Note that this function only erases the element,
71638fd1498Szrj        *  and that if the element is itself a pointer, the pointed-to memory is
71738fd1498Szrj        *  not touched in any way.  Managing the pointer is the user's
71838fd1498Szrj        *  responsibility.
71938fd1498Szrj        */
72038fd1498Szrj       void
72138fd1498Szrj       erase(iterator __position)
72238fd1498Szrj       { _M_t.erase(__position); }
72338fd1498Szrj #endif
72438fd1498Szrj 
72538fd1498Szrj       /**
72638fd1498Szrj        *  @brief Erases elements according to the provided key.
72738fd1498Szrj        *  @param  __x  Key of element to be erased.
72838fd1498Szrj        *  @return  The number of elements erased.
72938fd1498Szrj        *
73038fd1498Szrj        *  This function erases all elements located by the given key from a
73138fd1498Szrj        *  %multimap.
73238fd1498Szrj        *  Note that this function only erases the element, and that if
73338fd1498Szrj        *  the element is itself a pointer, the pointed-to memory is not touched
73438fd1498Szrj        *  in any way.  Managing the pointer is the user's responsibility.
73538fd1498Szrj        */
73638fd1498Szrj       size_type
73738fd1498Szrj       erase(const key_type& __x)
73838fd1498Szrj       { return _M_t.erase(__x); }
73938fd1498Szrj 
74038fd1498Szrj #if __cplusplus >= 201103L
74138fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
74238fd1498Szrj       // DR 130. Associative erase should return an iterator.
74338fd1498Szrj       /**
74438fd1498Szrj        *  @brief Erases a [first,last) range of elements from a %multimap.
74538fd1498Szrj        *  @param  __first  Iterator pointing to the start of the range to be
74638fd1498Szrj        *                   erased.
74738fd1498Szrj        *  @param __last Iterator pointing to the end of the range to be
74838fd1498Szrj        *                erased .
74938fd1498Szrj        *  @return The iterator @a __last.
75038fd1498Szrj        *
75138fd1498Szrj        *  This function erases a sequence of elements from a %multimap.
75238fd1498Szrj        *  Note that this function only erases the elements, and that if
75338fd1498Szrj        *  the elements themselves are pointers, the pointed-to memory is not
75438fd1498Szrj        *  touched in any way.  Managing the pointer is the user's
75538fd1498Szrj        *  responsibility.
75638fd1498Szrj        */
75738fd1498Szrj       iterator
75838fd1498Szrj       erase(const_iterator __first, const_iterator __last)
75938fd1498Szrj       { return _M_t.erase(__first, __last); }
76038fd1498Szrj #else
76138fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
76238fd1498Szrj       // DR 130. Associative erase should return an iterator.
76338fd1498Szrj       /**
76438fd1498Szrj        *  @brief Erases a [first,last) range of elements from a %multimap.
76538fd1498Szrj        *  @param  __first  Iterator pointing to the start of the range to be
76638fd1498Szrj        *                 erased.
76738fd1498Szrj        *  @param __last Iterator pointing to the end of the range to
76838fd1498Szrj        *                be erased.
76938fd1498Szrj        *
77038fd1498Szrj        *  This function erases a sequence of elements from a %multimap.
77138fd1498Szrj        *  Note that this function only erases the elements, and that if
77238fd1498Szrj        *  the elements themselves are pointers, the pointed-to memory is not
77338fd1498Szrj        *  touched in any way.  Managing the pointer is the user's
77438fd1498Szrj        *  responsibility.
77538fd1498Szrj        */
77638fd1498Szrj       void
77738fd1498Szrj       erase(iterator __first, iterator __last)
77838fd1498Szrj       { _M_t.erase(__first, __last); }
77938fd1498Szrj #endif
78038fd1498Szrj 
78138fd1498Szrj       /**
78238fd1498Szrj        *  @brief  Swaps data with another %multimap.
78338fd1498Szrj        *  @param  __x  A %multimap of the same element and allocator types.
78438fd1498Szrj        *
78538fd1498Szrj        *  This exchanges the elements between two multimaps in constant time.
78638fd1498Szrj        *  (It is only swapping a pointer, an integer, and an instance of
78738fd1498Szrj        *  the @c Compare type (which itself is often stateless and empty), so it
78838fd1498Szrj        *  should be quite fast.)
78938fd1498Szrj        *  Note that the global std::swap() function is specialized such that
79038fd1498Szrj        *  std::swap(m1,m2) will feed to this function.
79138fd1498Szrj        *
79238fd1498Szrj        *  Whether the allocators are swapped depends on the allocator traits.
79338fd1498Szrj        */
79438fd1498Szrj       void
79538fd1498Szrj       swap(multimap& __x)
79638fd1498Szrj       _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value)
79738fd1498Szrj       { _M_t.swap(__x._M_t); }
79838fd1498Szrj 
79938fd1498Szrj       /**
80038fd1498Szrj        *  Erases all elements in a %multimap.  Note that this function only
80138fd1498Szrj        *  erases the elements, and that if the elements themselves are pointers,
80238fd1498Szrj        *  the pointed-to memory is not touched in any way.  Managing the pointer
80338fd1498Szrj        *  is the user's responsibility.
80438fd1498Szrj        */
80538fd1498Szrj       void
80638fd1498Szrj       clear() _GLIBCXX_NOEXCEPT
80738fd1498Szrj       { _M_t.clear(); }
80838fd1498Szrj 
80938fd1498Szrj       // observers
81038fd1498Szrj       /**
81138fd1498Szrj        *  Returns the key comparison object out of which the %multimap
81238fd1498Szrj        *  was constructed.
81338fd1498Szrj        */
81438fd1498Szrj       key_compare
81538fd1498Szrj       key_comp() const
81638fd1498Szrj       { return _M_t.key_comp(); }
81738fd1498Szrj 
81838fd1498Szrj       /**
81938fd1498Szrj        *  Returns a value comparison object, built from the key comparison
82038fd1498Szrj        *  object out of which the %multimap was constructed.
82138fd1498Szrj        */
82238fd1498Szrj       value_compare
82338fd1498Szrj       value_comp() const
82438fd1498Szrj       { return value_compare(_M_t.key_comp()); }
82538fd1498Szrj 
82638fd1498Szrj       // multimap operations
82738fd1498Szrj 
82838fd1498Szrj       //@{
82938fd1498Szrj       /**
83038fd1498Szrj        *  @brief Tries to locate an element in a %multimap.
83138fd1498Szrj        *  @param  __x  Key of (key, value) pair to be located.
83238fd1498Szrj        *  @return  Iterator pointing to sought-after element,
83338fd1498Szrj        *           or end() if not found.
83438fd1498Szrj        *
83538fd1498Szrj        *  This function takes a key and tries to locate the element with which
83638fd1498Szrj        *  the key matches.  If successful the function returns an iterator
83738fd1498Szrj        *  pointing to the sought after %pair.  If unsuccessful it returns the
83838fd1498Szrj        *  past-the-end ( @c end() ) iterator.
83938fd1498Szrj        */
84038fd1498Szrj       iterator
84138fd1498Szrj       find(const key_type& __x)
84238fd1498Szrj       { return _M_t.find(__x); }
84338fd1498Szrj 
84438fd1498Szrj #if __cplusplus > 201103L
84538fd1498Szrj       template<typename _Kt>
84638fd1498Szrj 	auto
84738fd1498Szrj 	find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x))
84838fd1498Szrj 	{ return _M_t._M_find_tr(__x); }
84938fd1498Szrj #endif
85038fd1498Szrj       //@}
85138fd1498Szrj 
85238fd1498Szrj       //@{
85338fd1498Szrj       /**
85438fd1498Szrj        *  @brief Tries to locate an element in a %multimap.
85538fd1498Szrj        *  @param  __x  Key of (key, value) pair to be located.
85638fd1498Szrj        *  @return  Read-only (constant) iterator pointing to sought-after
85738fd1498Szrj        *           element, or end() if not found.
85838fd1498Szrj        *
85938fd1498Szrj        *  This function takes a key and tries to locate the element with which
86038fd1498Szrj        *  the key matches.  If successful the function returns a constant
86138fd1498Szrj        *  iterator pointing to the sought after %pair.  If unsuccessful it
86238fd1498Szrj        *  returns the past-the-end ( @c end() ) iterator.
86338fd1498Szrj        */
86438fd1498Szrj       const_iterator
86538fd1498Szrj       find(const key_type& __x) const
86638fd1498Szrj       { return _M_t.find(__x); }
86738fd1498Szrj 
86838fd1498Szrj #if __cplusplus > 201103L
86938fd1498Szrj       template<typename _Kt>
87038fd1498Szrj 	auto
87138fd1498Szrj 	find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x))
87238fd1498Szrj 	{ return _M_t._M_find_tr(__x); }
87338fd1498Szrj #endif
87438fd1498Szrj       //@}
87538fd1498Szrj 
87638fd1498Szrj       //@{
87738fd1498Szrj       /**
87838fd1498Szrj        *  @brief Finds the number of elements with given key.
87938fd1498Szrj        *  @param  __x  Key of (key, value) pairs to be located.
88038fd1498Szrj        *  @return Number of elements with specified key.
88138fd1498Szrj        */
88238fd1498Szrj       size_type
88338fd1498Szrj       count(const key_type& __x) const
88438fd1498Szrj       { return _M_t.count(__x); }
88538fd1498Szrj 
88638fd1498Szrj #if __cplusplus > 201103L
88738fd1498Szrj       template<typename _Kt>
88838fd1498Szrj 	auto
88938fd1498Szrj 	count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x))
89038fd1498Szrj 	{ return _M_t._M_count_tr(__x); }
89138fd1498Szrj #endif
89238fd1498Szrj       //@}
89338fd1498Szrj 
89438fd1498Szrj       //@{
89538fd1498Szrj       /**
89638fd1498Szrj        *  @brief Finds the beginning of a subsequence matching given key.
89738fd1498Szrj        *  @param  __x  Key of (key, value) pair to be located.
89838fd1498Szrj        *  @return  Iterator pointing to first element equal to or greater
89938fd1498Szrj        *           than key, or end().
90038fd1498Szrj        *
90138fd1498Szrj        *  This function returns the first element of a subsequence of elements
90238fd1498Szrj        *  that matches the given key.  If unsuccessful it returns an iterator
90338fd1498Szrj        *  pointing to the first element that has a greater value than given key
90438fd1498Szrj        *  or end() if no such element exists.
90538fd1498Szrj        */
90638fd1498Szrj       iterator
90738fd1498Szrj       lower_bound(const key_type& __x)
90838fd1498Szrj       { return _M_t.lower_bound(__x); }
90938fd1498Szrj 
91038fd1498Szrj #if __cplusplus > 201103L
91138fd1498Szrj       template<typename _Kt>
91238fd1498Szrj 	auto
91338fd1498Szrj 	lower_bound(const _Kt& __x)
91438fd1498Szrj 	-> decltype(iterator(_M_t._M_lower_bound_tr(__x)))
91538fd1498Szrj 	{ return iterator(_M_t._M_lower_bound_tr(__x)); }
91638fd1498Szrj #endif
91738fd1498Szrj       //@}
91838fd1498Szrj 
91938fd1498Szrj       //@{
92038fd1498Szrj       /**
92138fd1498Szrj        *  @brief Finds the beginning of a subsequence matching given key.
92238fd1498Szrj        *  @param  __x  Key of (key, value) pair to be located.
92338fd1498Szrj        *  @return  Read-only (constant) iterator pointing to first element
92438fd1498Szrj        *           equal to or greater than key, or end().
92538fd1498Szrj        *
92638fd1498Szrj        *  This function returns the first element of a subsequence of
92738fd1498Szrj        *  elements that matches the given key.  If unsuccessful the
92838fd1498Szrj        *  iterator will point to the next greatest element or, if no
92938fd1498Szrj        *  such greater element exists, to end().
93038fd1498Szrj        */
93138fd1498Szrj       const_iterator
93238fd1498Szrj       lower_bound(const key_type& __x) const
93338fd1498Szrj       { return _M_t.lower_bound(__x); }
93438fd1498Szrj 
93538fd1498Szrj #if __cplusplus > 201103L
93638fd1498Szrj       template<typename _Kt>
93738fd1498Szrj 	auto
93838fd1498Szrj 	lower_bound(const _Kt& __x) const
93938fd1498Szrj 	-> decltype(const_iterator(_M_t._M_lower_bound_tr(__x)))
94038fd1498Szrj 	{ return const_iterator(_M_t._M_lower_bound_tr(__x)); }
94138fd1498Szrj #endif
94238fd1498Szrj       //@}
94338fd1498Szrj 
94438fd1498Szrj       //@{
94538fd1498Szrj       /**
94638fd1498Szrj        *  @brief Finds the end of a subsequence matching given key.
94738fd1498Szrj        *  @param  __x  Key of (key, value) pair to be located.
94838fd1498Szrj        *  @return Iterator pointing to the first element
94938fd1498Szrj        *          greater than key, or end().
95038fd1498Szrj        */
95138fd1498Szrj       iterator
95238fd1498Szrj       upper_bound(const key_type& __x)
95338fd1498Szrj       { return _M_t.upper_bound(__x); }
95438fd1498Szrj 
95538fd1498Szrj #if __cplusplus > 201103L
95638fd1498Szrj       template<typename _Kt>
95738fd1498Szrj 	auto
95838fd1498Szrj 	upper_bound(const _Kt& __x)
95938fd1498Szrj 	-> decltype(iterator(_M_t._M_upper_bound_tr(__x)))
96038fd1498Szrj 	{ return iterator(_M_t._M_upper_bound_tr(__x)); }
96138fd1498Szrj #endif
96238fd1498Szrj       //@}
96338fd1498Szrj 
96438fd1498Szrj       //@{
96538fd1498Szrj       /**
96638fd1498Szrj        *  @brief Finds the end of a subsequence matching given key.
96738fd1498Szrj        *  @param  __x  Key of (key, value) pair to be located.
96838fd1498Szrj        *  @return  Read-only (constant) iterator pointing to first iterator
96938fd1498Szrj        *           greater than key, or end().
97038fd1498Szrj        */
97138fd1498Szrj       const_iterator
97238fd1498Szrj       upper_bound(const key_type& __x) const
97338fd1498Szrj       { return _M_t.upper_bound(__x); }
97438fd1498Szrj 
97538fd1498Szrj #if __cplusplus > 201103L
97638fd1498Szrj       template<typename _Kt>
97738fd1498Szrj 	auto
97838fd1498Szrj 	upper_bound(const _Kt& __x) const
97938fd1498Szrj 	-> decltype(const_iterator(_M_t._M_upper_bound_tr(__x)))
98038fd1498Szrj 	{ return const_iterator(_M_t._M_upper_bound_tr(__x)); }
98138fd1498Szrj #endif
98238fd1498Szrj       //@}
98338fd1498Szrj 
98438fd1498Szrj       //@{
98538fd1498Szrj       /**
98638fd1498Szrj        *  @brief Finds a subsequence matching given key.
98738fd1498Szrj        *  @param  __x  Key of (key, value) pairs to be located.
98838fd1498Szrj        *  @return  Pair of iterators that possibly points to the subsequence
98938fd1498Szrj        *           matching given key.
99038fd1498Szrj        *
99138fd1498Szrj        *  This function is equivalent to
99238fd1498Szrj        *  @code
99338fd1498Szrj        *    std::make_pair(c.lower_bound(val),
99438fd1498Szrj        *                   c.upper_bound(val))
99538fd1498Szrj        *  @endcode
99638fd1498Szrj        *  (but is faster than making the calls separately).
99738fd1498Szrj        */
99838fd1498Szrj       std::pair<iterator, iterator>
99938fd1498Szrj       equal_range(const key_type& __x)
100038fd1498Szrj       { return _M_t.equal_range(__x); }
100138fd1498Szrj 
100238fd1498Szrj #if __cplusplus > 201103L
100338fd1498Szrj       template<typename _Kt>
100438fd1498Szrj 	auto
100538fd1498Szrj 	equal_range(const _Kt& __x)
100638fd1498Szrj 	-> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)))
100738fd1498Szrj 	{ return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); }
100838fd1498Szrj #endif
100938fd1498Szrj       //@}
101038fd1498Szrj 
101138fd1498Szrj       //@{
101238fd1498Szrj       /**
101338fd1498Szrj        *  @brief Finds a subsequence matching given key.
101438fd1498Szrj        *  @param  __x  Key of (key, value) pairs to be located.
101538fd1498Szrj        *  @return  Pair of read-only (constant) iterators that possibly points
101638fd1498Szrj        *           to the subsequence matching given key.
101738fd1498Szrj        *
101838fd1498Szrj        *  This function is equivalent to
101938fd1498Szrj        *  @code
102038fd1498Szrj        *    std::make_pair(c.lower_bound(val),
102138fd1498Szrj        *                   c.upper_bound(val))
102238fd1498Szrj        *  @endcode
102338fd1498Szrj        *  (but is faster than making the calls separately).
102438fd1498Szrj        */
102538fd1498Szrj       std::pair<const_iterator, const_iterator>
102638fd1498Szrj       equal_range(const key_type& __x) const
102738fd1498Szrj       { return _M_t.equal_range(__x); }
102838fd1498Szrj 
102938fd1498Szrj #if __cplusplus > 201103L
103038fd1498Szrj       template<typename _Kt>
103138fd1498Szrj 	auto
103238fd1498Szrj 	equal_range(const _Kt& __x) const
103338fd1498Szrj 	-> decltype(pair<const_iterator, const_iterator>(
103438fd1498Szrj 	      _M_t._M_equal_range_tr(__x)))
103538fd1498Szrj 	{
103638fd1498Szrj 	  return pair<const_iterator, const_iterator>(
103738fd1498Szrj 	      _M_t._M_equal_range_tr(__x));
103838fd1498Szrj 	}
103938fd1498Szrj #endif
104038fd1498Szrj       //@}
104138fd1498Szrj 
104238fd1498Szrj       template<typename _K1, typename _T1, typename _C1, typename _A1>
104338fd1498Szrj 	friend bool
104438fd1498Szrj 	operator==(const multimap<_K1, _T1, _C1, _A1>&,
104538fd1498Szrj 		   const multimap<_K1, _T1, _C1, _A1>&);
104638fd1498Szrj 
104738fd1498Szrj       template<typename _K1, typename _T1, typename _C1, typename _A1>
104838fd1498Szrj 	friend bool
104938fd1498Szrj 	operator<(const multimap<_K1, _T1, _C1, _A1>&,
105038fd1498Szrj 		  const multimap<_K1, _T1, _C1, _A1>&);
105138fd1498Szrj   };
105238fd1498Szrj 
105338fd1498Szrj #if __cpp_deduction_guides >= 201606
105438fd1498Szrj 
105538fd1498Szrj   template<typename _InputIterator,
105638fd1498Szrj 	   typename _Compare = less<__iter_key_t<_InputIterator>>,
105738fd1498Szrj 	   typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
105838fd1498Szrj 	   typename = _RequireInputIter<_InputIterator>,
105938fd1498Szrj 	   typename = _RequireAllocator<_Allocator>>
106038fd1498Szrj     multimap(_InputIterator, _InputIterator,
106138fd1498Szrj 	     _Compare = _Compare(), _Allocator = _Allocator())
106238fd1498Szrj     -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
106338fd1498Szrj 		_Compare, _Allocator>;
106438fd1498Szrj 
106538fd1498Szrj   template<typename _Key, typename _Tp, typename _Compare = less<_Key>,
106638fd1498Szrj 	   typename _Allocator = allocator<pair<const _Key, _Tp>>,
106738fd1498Szrj 	   typename = _RequireAllocator<_Allocator>>
106838fd1498Szrj     multimap(initializer_list<pair<_Key, _Tp>>,
106938fd1498Szrj 	     _Compare = _Compare(), _Allocator = _Allocator())
107038fd1498Szrj     -> multimap<_Key, _Tp, _Compare, _Allocator>;
107138fd1498Szrj 
107238fd1498Szrj   template<typename _InputIterator, typename _Allocator,
107338fd1498Szrj 	   typename = _RequireInputIter<_InputIterator>,
107438fd1498Szrj 	   typename = _RequireAllocator<_Allocator>>
107538fd1498Szrj     multimap(_InputIterator, _InputIterator, _Allocator)
107638fd1498Szrj     -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
107738fd1498Szrj 		less<__iter_key_t<_InputIterator>>, _Allocator>;
107838fd1498Szrj 
107938fd1498Szrj   template<typename _Key, typename _Tp, typename _Allocator,
108038fd1498Szrj 	   typename = _RequireAllocator<_Allocator>>
108138fd1498Szrj     multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
108238fd1498Szrj     -> multimap<_Key, _Tp, less<_Key>, _Allocator>;
108338fd1498Szrj 
108438fd1498Szrj #endif
108538fd1498Szrj 
108638fd1498Szrj   /**
108738fd1498Szrj    *  @brief  Multimap equality comparison.
108838fd1498Szrj    *  @param  __x  A %multimap.
108938fd1498Szrj    *  @param  __y  A %multimap of the same type as @a __x.
109038fd1498Szrj    *  @return  True iff the size and elements of the maps are equal.
109138fd1498Szrj    *
109238fd1498Szrj    *  This is an equivalence relation.  It is linear in the size of the
109338fd1498Szrj    *  multimaps.  Multimaps are considered equivalent if their sizes are equal,
109438fd1498Szrj    *  and if corresponding elements compare equal.
109538fd1498Szrj   */
109638fd1498Szrj   template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
109738fd1498Szrj     inline bool
109838fd1498Szrj     operator==(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
109938fd1498Szrj 	       const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
110038fd1498Szrj     { return __x._M_t == __y._M_t; }
110138fd1498Szrj 
110238fd1498Szrj   /**
110338fd1498Szrj    *  @brief  Multimap ordering relation.
110438fd1498Szrj    *  @param  __x  A %multimap.
110538fd1498Szrj    *  @param  __y  A %multimap of the same type as @a __x.
110638fd1498Szrj    *  @return  True iff @a x is lexicographically less than @a y.
110738fd1498Szrj    *
110838fd1498Szrj    *  This is a total ordering relation.  It is linear in the size of the
110938fd1498Szrj    *  multimaps.  The elements must be comparable with @c <.
111038fd1498Szrj    *
111138fd1498Szrj    *  See std::lexicographical_compare() for how the determination is made.
111238fd1498Szrj   */
111338fd1498Szrj   template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
111438fd1498Szrj     inline bool
111538fd1498Szrj     operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
111638fd1498Szrj 	      const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
111738fd1498Szrj     { return __x._M_t < __y._M_t; }
111838fd1498Szrj 
111938fd1498Szrj   /// Based on operator==
112038fd1498Szrj   template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
112138fd1498Szrj     inline bool
112238fd1498Szrj     operator!=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
112338fd1498Szrj 	       const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
112438fd1498Szrj     { return !(__x == __y); }
112538fd1498Szrj 
112638fd1498Szrj   /// Based on operator<
112738fd1498Szrj   template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
112838fd1498Szrj     inline bool
112938fd1498Szrj     operator>(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
113038fd1498Szrj 	      const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
113138fd1498Szrj     { return __y < __x; }
113238fd1498Szrj 
113338fd1498Szrj   /// Based on operator<
113438fd1498Szrj   template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
113538fd1498Szrj     inline bool
113638fd1498Szrj     operator<=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
113738fd1498Szrj 	       const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
113838fd1498Szrj     { return !(__y < __x); }
113938fd1498Szrj 
114038fd1498Szrj   /// Based on operator<
114138fd1498Szrj   template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
114238fd1498Szrj     inline bool
114338fd1498Szrj     operator>=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
114438fd1498Szrj 	       const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
114538fd1498Szrj     { return !(__x < __y); }
114638fd1498Szrj 
114738fd1498Szrj   /// See std::multimap::swap().
114838fd1498Szrj   template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
114938fd1498Szrj     inline void
115038fd1498Szrj     swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x,
115138fd1498Szrj 	 multimap<_Key, _Tp, _Compare, _Alloc>& __y)
115238fd1498Szrj     _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
115338fd1498Szrj     { __x.swap(__y); }
115438fd1498Szrj 
115538fd1498Szrj _GLIBCXX_END_NAMESPACE_CONTAINER
115638fd1498Szrj 
115738fd1498Szrj #if __cplusplus > 201402L
115838fd1498Szrj   // Allow std::multimap access to internals of compatible maps.
115938fd1498Szrj   template<typename _Key, typename _Val, typename _Cmp1, typename _Alloc,
116038fd1498Szrj 	   typename _Cmp2>
116138fd1498Szrj     struct
116238fd1498Szrj     _Rb_tree_merge_helper<_GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp1, _Alloc>,
116338fd1498Szrj 			  _Cmp2>
116438fd1498Szrj     {
116538fd1498Szrj     private:
116638fd1498Szrj       friend class _GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp1, _Alloc>;
116738fd1498Szrj 
116838fd1498Szrj       static auto&
116938fd1498Szrj       _S_get_tree(_GLIBCXX_STD_C::map<_Key, _Val, _Cmp2, _Alloc>& __map)
117038fd1498Szrj       { return __map._M_t; }
117138fd1498Szrj 
117238fd1498Szrj       static auto&
117338fd1498Szrj       _S_get_tree(_GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp2, _Alloc>& __map)
117438fd1498Szrj       { return __map._M_t; }
117538fd1498Szrj     };
117638fd1498Szrj #endif // C++17
117738fd1498Szrj 
117838fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
117938fd1498Szrj } // namespace std
118038fd1498Szrj 
118138fd1498Szrj #endif /* _STL_MULTIMAP_H */
1182