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