138fd1498Szrj // Debugging multimap implementation -*- C++ -*-
238fd1498Szrj
338fd1498Szrj // Copyright (C) 2003-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 /** @file debug/multimap.h
2638fd1498Szrj * This file is a GNU debug extension to the Standard C++ Library.
2738fd1498Szrj */
2838fd1498Szrj
2938fd1498Szrj #ifndef _GLIBCXX_DEBUG_MULTIMAP_H
3038fd1498Szrj #define _GLIBCXX_DEBUG_MULTIMAP_H 1
3138fd1498Szrj
3238fd1498Szrj #include <debug/safe_sequence.h>
3338fd1498Szrj #include <debug/safe_container.h>
3438fd1498Szrj #include <debug/safe_iterator.h>
3538fd1498Szrj #include <utility>
3638fd1498Szrj
_GLIBCXX_VISIBILITY(default)3738fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
3838fd1498Szrj {
3938fd1498Szrj namespace __debug
4038fd1498Szrj {
4138fd1498Szrj /// Class std::multimap with safety/checking/debug instrumentation.
4238fd1498Szrj template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
4338fd1498Szrj typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
4438fd1498Szrj class multimap
4538fd1498Szrj : public __gnu_debug::_Safe_container<
4638fd1498Szrj multimap<_Key, _Tp, _Compare, _Allocator>, _Allocator,
4738fd1498Szrj __gnu_debug::_Safe_node_sequence>,
4838fd1498Szrj public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>
4938fd1498Szrj {
5038fd1498Szrj typedef _GLIBCXX_STD_C::multimap<
5138fd1498Szrj _Key, _Tp, _Compare, _Allocator> _Base;
5238fd1498Szrj typedef __gnu_debug::_Safe_container<
5338fd1498Szrj multimap, _Allocator, __gnu_debug::_Safe_node_sequence> _Safe;
5438fd1498Szrj
5538fd1498Szrj typedef typename _Base::const_iterator _Base_const_iterator;
5638fd1498Szrj typedef typename _Base::iterator _Base_iterator;
5738fd1498Szrj typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
5838fd1498Szrj
5938fd1498Szrj public:
6038fd1498Szrj // types:
6138fd1498Szrj typedef _Key key_type;
6238fd1498Szrj typedef _Tp mapped_type;
6338fd1498Szrj typedef std::pair<const _Key, _Tp> value_type;
6438fd1498Szrj typedef _Compare key_compare;
6538fd1498Szrj typedef _Allocator allocator_type;
6638fd1498Szrj typedef typename _Base::reference reference;
6738fd1498Szrj typedef typename _Base::const_reference const_reference;
6838fd1498Szrj
6938fd1498Szrj typedef __gnu_debug::_Safe_iterator<_Base_iterator, multimap>
7038fd1498Szrj iterator;
7138fd1498Szrj typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
7238fd1498Szrj multimap> const_iterator;
7338fd1498Szrj
7438fd1498Szrj typedef typename _Base::size_type size_type;
7538fd1498Szrj typedef typename _Base::difference_type difference_type;
7638fd1498Szrj typedef typename _Base::pointer pointer;
7738fd1498Szrj typedef typename _Base::const_pointer const_pointer;
7838fd1498Szrj typedef std::reverse_iterator<iterator> reverse_iterator;
7938fd1498Szrj typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
8038fd1498Szrj
8138fd1498Szrj // 23.3.1.1 construct/copy/destroy:
8238fd1498Szrj
8338fd1498Szrj #if __cplusplus < 201103L
8438fd1498Szrj multimap() : _Base() { }
8538fd1498Szrj
8638fd1498Szrj multimap(const multimap& __x)
8738fd1498Szrj : _Base(__x) { }
8838fd1498Szrj
8938fd1498Szrj ~multimap() { }
9038fd1498Szrj #else
9138fd1498Szrj multimap() = default;
9238fd1498Szrj multimap(const multimap&) = default;
9338fd1498Szrj multimap(multimap&&) = default;
9438fd1498Szrj
9538fd1498Szrj multimap(initializer_list<value_type> __l,
9638fd1498Szrj const _Compare& __c = _Compare(),
9738fd1498Szrj const allocator_type& __a = allocator_type())
9838fd1498Szrj : _Base(__l, __c, __a) { }
9938fd1498Szrj
10038fd1498Szrj explicit
10138fd1498Szrj multimap(const allocator_type& __a)
10238fd1498Szrj : _Base(__a) { }
10338fd1498Szrj
10438fd1498Szrj multimap(const multimap& __m, const allocator_type& __a)
10538fd1498Szrj : _Base(__m, __a) { }
10638fd1498Szrj
10738fd1498Szrj multimap(multimap&& __m, const allocator_type& __a)
108*58e805e6Szrj noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) )
10938fd1498Szrj : _Safe(std::move(__m._M_safe()), __a),
11038fd1498Szrj _Base(std::move(__m._M_base()), __a) { }
11138fd1498Szrj
11238fd1498Szrj multimap(initializer_list<value_type> __l, const allocator_type& __a)
11338fd1498Szrj : _Base(__l, __a) { }
11438fd1498Szrj
11538fd1498Szrj template<typename _InputIterator>
11638fd1498Szrj multimap(_InputIterator __first, _InputIterator __last,
11738fd1498Szrj const allocator_type& __a)
11838fd1498Szrj : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
11938fd1498Szrj __last)),
12038fd1498Szrj __gnu_debug::__base(__last), __a) { }
12138fd1498Szrj
12238fd1498Szrj ~multimap() = default;
12338fd1498Szrj #endif
12438fd1498Szrj
12538fd1498Szrj explicit multimap(const _Compare& __comp,
12638fd1498Szrj const _Allocator& __a = _Allocator())
12738fd1498Szrj : _Base(__comp, __a) { }
12838fd1498Szrj
12938fd1498Szrj template<typename _InputIterator>
13038fd1498Szrj multimap(_InputIterator __first, _InputIterator __last,
13138fd1498Szrj const _Compare& __comp = _Compare(),
13238fd1498Szrj const _Allocator& __a = _Allocator())
13338fd1498Szrj : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
13438fd1498Szrj __last)),
13538fd1498Szrj __gnu_debug::__base(__last),
13638fd1498Szrj __comp, __a) { }
13738fd1498Szrj
13838fd1498Szrj multimap(const _Base& __x)
13938fd1498Szrj : _Base(__x) { }
14038fd1498Szrj
14138fd1498Szrj #if __cplusplus < 201103L
14238fd1498Szrj multimap&
14338fd1498Szrj operator=(const multimap& __x)
14438fd1498Szrj {
14538fd1498Szrj this->_M_safe() = __x;
14638fd1498Szrj _M_base() = __x;
14738fd1498Szrj return *this;
14838fd1498Szrj }
14938fd1498Szrj #else
15038fd1498Szrj multimap&
15138fd1498Szrj operator=(const multimap&) = default;
15238fd1498Szrj
15338fd1498Szrj multimap&
15438fd1498Szrj operator=(multimap&&) = default;
15538fd1498Szrj
15638fd1498Szrj multimap&
15738fd1498Szrj operator=(initializer_list<value_type> __l)
15838fd1498Szrj {
15938fd1498Szrj _M_base() = __l;
16038fd1498Szrj this->_M_invalidate_all();
16138fd1498Szrj return *this;
16238fd1498Szrj }
16338fd1498Szrj #endif
16438fd1498Szrj
16538fd1498Szrj using _Base::get_allocator;
16638fd1498Szrj
16738fd1498Szrj // iterators:
16838fd1498Szrj iterator
16938fd1498Szrj begin() _GLIBCXX_NOEXCEPT
17038fd1498Szrj { return iterator(_Base::begin(), this); }
17138fd1498Szrj
17238fd1498Szrj const_iterator
17338fd1498Szrj begin() const _GLIBCXX_NOEXCEPT
17438fd1498Szrj { return const_iterator(_Base::begin(), this); }
17538fd1498Szrj
17638fd1498Szrj iterator
17738fd1498Szrj end() _GLIBCXX_NOEXCEPT
17838fd1498Szrj { return iterator(_Base::end(), this); }
17938fd1498Szrj
18038fd1498Szrj const_iterator
18138fd1498Szrj end() const _GLIBCXX_NOEXCEPT
18238fd1498Szrj { return const_iterator(_Base::end(), this); }
18338fd1498Szrj
18438fd1498Szrj reverse_iterator
18538fd1498Szrj rbegin() _GLIBCXX_NOEXCEPT
18638fd1498Szrj { return reverse_iterator(end()); }
18738fd1498Szrj
18838fd1498Szrj const_reverse_iterator
18938fd1498Szrj rbegin() const _GLIBCXX_NOEXCEPT
19038fd1498Szrj { return const_reverse_iterator(end()); }
19138fd1498Szrj
19238fd1498Szrj reverse_iterator
19338fd1498Szrj rend() _GLIBCXX_NOEXCEPT
19438fd1498Szrj { return reverse_iterator(begin()); }
19538fd1498Szrj
19638fd1498Szrj const_reverse_iterator
19738fd1498Szrj rend() const _GLIBCXX_NOEXCEPT
19838fd1498Szrj { return const_reverse_iterator(begin()); }
19938fd1498Szrj
20038fd1498Szrj #if __cplusplus >= 201103L
20138fd1498Szrj const_iterator
20238fd1498Szrj cbegin() const noexcept
20338fd1498Szrj { return const_iterator(_Base::begin(), this); }
20438fd1498Szrj
20538fd1498Szrj const_iterator
20638fd1498Szrj cend() const noexcept
20738fd1498Szrj { return const_iterator(_Base::end(), this); }
20838fd1498Szrj
20938fd1498Szrj const_reverse_iterator
21038fd1498Szrj crbegin() const noexcept
21138fd1498Szrj { return const_reverse_iterator(end()); }
21238fd1498Szrj
21338fd1498Szrj const_reverse_iterator
21438fd1498Szrj crend() const noexcept
21538fd1498Szrj { return const_reverse_iterator(begin()); }
21638fd1498Szrj #endif
21738fd1498Szrj
21838fd1498Szrj // capacity:
21938fd1498Szrj using _Base::empty;
22038fd1498Szrj using _Base::size;
22138fd1498Szrj using _Base::max_size;
22238fd1498Szrj
22338fd1498Szrj // modifiers:
22438fd1498Szrj #if __cplusplus >= 201103L
22538fd1498Szrj template<typename... _Args>
22638fd1498Szrj iterator
22738fd1498Szrj emplace(_Args&&... __args)
22838fd1498Szrj {
22938fd1498Szrj return iterator(_Base::emplace(std::forward<_Args>(__args)...), this);
23038fd1498Szrj }
23138fd1498Szrj
23238fd1498Szrj template<typename... _Args>
23338fd1498Szrj iterator
23438fd1498Szrj emplace_hint(const_iterator __pos, _Args&&... __args)
23538fd1498Szrj {
23638fd1498Szrj __glibcxx_check_insert(__pos);
23738fd1498Szrj return iterator(_Base::emplace_hint(__pos.base(),
23838fd1498Szrj std::forward<_Args>(__args)...),
23938fd1498Szrj this);
24038fd1498Szrj }
24138fd1498Szrj #endif
24238fd1498Szrj
24338fd1498Szrj iterator
24438fd1498Szrj insert(const value_type& __x)
24538fd1498Szrj { return iterator(_Base::insert(__x), this); }
24638fd1498Szrj
24738fd1498Szrj #if __cplusplus >= 201103L
24838fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
24938fd1498Szrj // 2354. Unnecessary copying when inserting into maps with braced-init
25038fd1498Szrj iterator
25138fd1498Szrj insert(value_type&& __x)
25238fd1498Szrj { return { _Base::insert(std::move(__x)), this }; }
25338fd1498Szrj
25438fd1498Szrj template<typename _Pair, typename = typename
25538fd1498Szrj std::enable_if<std::is_constructible<value_type,
25638fd1498Szrj _Pair&&>::value>::type>
25738fd1498Szrj iterator
25838fd1498Szrj insert(_Pair&& __x)
25938fd1498Szrj { return iterator(_Base::insert(std::forward<_Pair>(__x)), this); }
26038fd1498Szrj #endif
26138fd1498Szrj
26238fd1498Szrj #if __cplusplus >= 201103L
26338fd1498Szrj void
26438fd1498Szrj insert(std::initializer_list<value_type> __list)
26538fd1498Szrj { _Base::insert(__list); }
26638fd1498Szrj #endif
26738fd1498Szrj
26838fd1498Szrj iterator
26938fd1498Szrj #if __cplusplus >= 201103L
27038fd1498Szrj insert(const_iterator __position, const value_type& __x)
27138fd1498Szrj #else
27238fd1498Szrj insert(iterator __position, const value_type& __x)
27338fd1498Szrj #endif
27438fd1498Szrj {
27538fd1498Szrj __glibcxx_check_insert(__position);
27638fd1498Szrj return iterator(_Base::insert(__position.base(), __x), this);
27738fd1498Szrj }
27838fd1498Szrj
27938fd1498Szrj #if __cplusplus >= 201103L
28038fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
28138fd1498Szrj // 2354. Unnecessary copying when inserting into maps with braced-init
28238fd1498Szrj iterator
28338fd1498Szrj insert(const_iterator __position, value_type&& __x)
28438fd1498Szrj {
28538fd1498Szrj __glibcxx_check_insert(__position);
28638fd1498Szrj return { _Base::insert(__position.base(), std::move(__x)), this };
28738fd1498Szrj }
28838fd1498Szrj
28938fd1498Szrj template<typename _Pair, typename = typename
29038fd1498Szrj std::enable_if<std::is_constructible<value_type,
29138fd1498Szrj _Pair&&>::value>::type>
29238fd1498Szrj iterator
29338fd1498Szrj insert(const_iterator __position, _Pair&& __x)
29438fd1498Szrj {
29538fd1498Szrj __glibcxx_check_insert(__position);
29638fd1498Szrj return iterator(_Base::insert(__position.base(),
29738fd1498Szrj std::forward<_Pair>(__x)), this);
29838fd1498Szrj }
29938fd1498Szrj #endif
30038fd1498Szrj
30138fd1498Szrj template<typename _InputIterator>
30238fd1498Szrj void
30338fd1498Szrj insert(_InputIterator __first, _InputIterator __last)
30438fd1498Szrj {
30538fd1498Szrj typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
30638fd1498Szrj __glibcxx_check_valid_range2(__first, __last, __dist);
30738fd1498Szrj
30838fd1498Szrj if (__dist.second >= __gnu_debug::__dp_sign)
30938fd1498Szrj _Base::insert(__gnu_debug::__unsafe(__first),
31038fd1498Szrj __gnu_debug::__unsafe(__last));
31138fd1498Szrj else
31238fd1498Szrj _Base::insert(__first, __last);
31338fd1498Szrj }
31438fd1498Szrj
31538fd1498Szrj #if __cplusplus > 201402L
31638fd1498Szrj using node_type = typename _Base::node_type;
31738fd1498Szrj
31838fd1498Szrj node_type
31938fd1498Szrj extract(const_iterator __position)
32038fd1498Szrj {
32138fd1498Szrj __glibcxx_check_erase(__position);
32238fd1498Szrj this->_M_invalidate_if(_Equal(__position.base()));
32338fd1498Szrj return _Base::extract(__position.base());
32438fd1498Szrj }
32538fd1498Szrj
32638fd1498Szrj node_type
32738fd1498Szrj extract(const key_type& __key)
32838fd1498Szrj {
32938fd1498Szrj const auto __position = find(__key);
33038fd1498Szrj if (__position != end())
33138fd1498Szrj return extract(__position);
33238fd1498Szrj return {};
33338fd1498Szrj }
33438fd1498Szrj
33538fd1498Szrj iterator
33638fd1498Szrj insert(node_type&& __nh)
33738fd1498Szrj { return iterator(_Base::insert(std::move(__nh)), this); }
33838fd1498Szrj
33938fd1498Szrj iterator
34038fd1498Szrj insert(const_iterator __hint, node_type&& __nh)
34138fd1498Szrj {
34238fd1498Szrj __glibcxx_check_insert(__hint);
34338fd1498Szrj return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
34438fd1498Szrj }
34538fd1498Szrj
34638fd1498Szrj using _Base::merge;
34738fd1498Szrj #endif // C++17
34838fd1498Szrj
34938fd1498Szrj #if __cplusplus >= 201103L
35038fd1498Szrj iterator
35138fd1498Szrj erase(const_iterator __position)
35238fd1498Szrj {
35338fd1498Szrj __glibcxx_check_erase(__position);
35438fd1498Szrj this->_M_invalidate_if(_Equal(__position.base()));
35538fd1498Szrj return iterator(_Base::erase(__position.base()), this);
35638fd1498Szrj }
35738fd1498Szrj
35838fd1498Szrj iterator
35938fd1498Szrj erase(iterator __position)
36038fd1498Szrj { return erase(const_iterator(__position)); }
36138fd1498Szrj #else
36238fd1498Szrj void
36338fd1498Szrj erase(iterator __position)
36438fd1498Szrj {
36538fd1498Szrj __glibcxx_check_erase(__position);
36638fd1498Szrj this->_M_invalidate_if(_Equal(__position.base()));
36738fd1498Szrj _Base::erase(__position.base());
36838fd1498Szrj }
36938fd1498Szrj #endif
37038fd1498Szrj
37138fd1498Szrj size_type
37238fd1498Szrj erase(const key_type& __x)
37338fd1498Szrj {
37438fd1498Szrj std::pair<_Base_iterator, _Base_iterator> __victims =
37538fd1498Szrj _Base::equal_range(__x);
37638fd1498Szrj size_type __count = 0;
37738fd1498Szrj _Base_iterator __victim = __victims.first;
37838fd1498Szrj while (__victim != __victims.second)
37938fd1498Szrj {
38038fd1498Szrj this->_M_invalidate_if(_Equal(__victim));
38138fd1498Szrj _Base::erase(__victim++);
38238fd1498Szrj ++__count;
38338fd1498Szrj }
38438fd1498Szrj return __count;
38538fd1498Szrj }
38638fd1498Szrj
38738fd1498Szrj #if __cplusplus >= 201103L
38838fd1498Szrj iterator
38938fd1498Szrj erase(const_iterator __first, const_iterator __last)
39038fd1498Szrj {
39138fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
39238fd1498Szrj // 151. can't currently clear() empty container
39338fd1498Szrj __glibcxx_check_erase_range(__first, __last);
39438fd1498Szrj for (_Base_const_iterator __victim = __first.base();
39538fd1498Szrj __victim != __last.base(); ++__victim)
39638fd1498Szrj {
39738fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
39838fd1498Szrj _M_message(__gnu_debug::__msg_valid_range)
39938fd1498Szrj ._M_iterator(__first, "first")
40038fd1498Szrj ._M_iterator(__last, "last"));
40138fd1498Szrj this->_M_invalidate_if(_Equal(__victim));
40238fd1498Szrj }
40338fd1498Szrj return iterator(_Base::erase(__first.base(), __last.base()), this);
40438fd1498Szrj }
40538fd1498Szrj #else
40638fd1498Szrj void
40738fd1498Szrj erase(iterator __first, iterator __last)
40838fd1498Szrj {
40938fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
41038fd1498Szrj // 151. can't currently clear() empty container
41138fd1498Szrj __glibcxx_check_erase_range(__first, __last);
41238fd1498Szrj for (_Base_iterator __victim = __first.base();
41338fd1498Szrj __victim != __last.base(); ++__victim)
41438fd1498Szrj {
41538fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
41638fd1498Szrj _M_message(__gnu_debug::__msg_valid_range)
41738fd1498Szrj ._M_iterator(__first, "first")
41838fd1498Szrj ._M_iterator(__last, "last"));
41938fd1498Szrj this->_M_invalidate_if(_Equal(__victim));
42038fd1498Szrj }
42138fd1498Szrj _Base::erase(__first.base(), __last.base());
42238fd1498Szrj }
42338fd1498Szrj #endif
42438fd1498Szrj
42538fd1498Szrj void
42638fd1498Szrj swap(multimap& __x)
42738fd1498Szrj _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
42838fd1498Szrj {
42938fd1498Szrj _Safe::_M_swap(__x);
43038fd1498Szrj _Base::swap(__x);
43138fd1498Szrj }
43238fd1498Szrj
43338fd1498Szrj void
43438fd1498Szrj clear() _GLIBCXX_NOEXCEPT
43538fd1498Szrj {
43638fd1498Szrj this->_M_invalidate_all();
43738fd1498Szrj _Base::clear();
43838fd1498Szrj }
43938fd1498Szrj
44038fd1498Szrj // observers:
44138fd1498Szrj using _Base::key_comp;
44238fd1498Szrj using _Base::value_comp;
44338fd1498Szrj
44438fd1498Szrj // 23.3.1.3 multimap operations:
44538fd1498Szrj iterator
44638fd1498Szrj find(const key_type& __x)
44738fd1498Szrj { return iterator(_Base::find(__x), this); }
44838fd1498Szrj
44938fd1498Szrj #if __cplusplus > 201103L
45038fd1498Szrj template<typename _Kt,
45138fd1498Szrj typename _Req =
45238fd1498Szrj typename __has_is_transparent<_Compare, _Kt>::type>
45338fd1498Szrj iterator
45438fd1498Szrj find(const _Kt& __x)
45538fd1498Szrj { return { _Base::find(__x), this }; }
45638fd1498Szrj #endif
45738fd1498Szrj
45838fd1498Szrj const_iterator
45938fd1498Szrj find(const key_type& __x) const
46038fd1498Szrj { return const_iterator(_Base::find(__x), this); }
46138fd1498Szrj
46238fd1498Szrj #if __cplusplus > 201103L
46338fd1498Szrj template<typename _Kt,
46438fd1498Szrj typename _Req =
46538fd1498Szrj typename __has_is_transparent<_Compare, _Kt>::type>
46638fd1498Szrj const_iterator
46738fd1498Szrj find(const _Kt& __x) const
46838fd1498Szrj { return { _Base::find(__x), this }; }
46938fd1498Szrj #endif
47038fd1498Szrj
47138fd1498Szrj using _Base::count;
47238fd1498Szrj
47338fd1498Szrj iterator
47438fd1498Szrj lower_bound(const key_type& __x)
47538fd1498Szrj { return iterator(_Base::lower_bound(__x), this); }
47638fd1498Szrj
47738fd1498Szrj #if __cplusplus > 201103L
47838fd1498Szrj template<typename _Kt,
47938fd1498Szrj typename _Req =
48038fd1498Szrj typename __has_is_transparent<_Compare, _Kt>::type>
48138fd1498Szrj iterator
48238fd1498Szrj lower_bound(const _Kt& __x)
48338fd1498Szrj { return { _Base::lower_bound(__x), this }; }
48438fd1498Szrj #endif
48538fd1498Szrj
48638fd1498Szrj const_iterator
48738fd1498Szrj lower_bound(const key_type& __x) const
48838fd1498Szrj { return const_iterator(_Base::lower_bound(__x), this); }
48938fd1498Szrj
49038fd1498Szrj #if __cplusplus > 201103L
49138fd1498Szrj template<typename _Kt,
49238fd1498Szrj typename _Req =
49338fd1498Szrj typename __has_is_transparent<_Compare, _Kt>::type>
49438fd1498Szrj const_iterator
49538fd1498Szrj lower_bound(const _Kt& __x) const
49638fd1498Szrj { return { _Base::lower_bound(__x), this }; }
49738fd1498Szrj #endif
49838fd1498Szrj
49938fd1498Szrj iterator
50038fd1498Szrj upper_bound(const key_type& __x)
50138fd1498Szrj { return iterator(_Base::upper_bound(__x), this); }
50238fd1498Szrj
50338fd1498Szrj #if __cplusplus > 201103L
50438fd1498Szrj template<typename _Kt,
50538fd1498Szrj typename _Req =
50638fd1498Szrj typename __has_is_transparent<_Compare, _Kt>::type>
50738fd1498Szrj iterator
50838fd1498Szrj upper_bound(const _Kt& __x)
50938fd1498Szrj { return { _Base::upper_bound(__x), this }; }
51038fd1498Szrj #endif
51138fd1498Szrj
51238fd1498Szrj const_iterator
51338fd1498Szrj upper_bound(const key_type& __x) const
51438fd1498Szrj { return const_iterator(_Base::upper_bound(__x), this); }
51538fd1498Szrj
51638fd1498Szrj #if __cplusplus > 201103L
51738fd1498Szrj template<typename _Kt,
51838fd1498Szrj typename _Req =
51938fd1498Szrj typename __has_is_transparent<_Compare, _Kt>::type>
52038fd1498Szrj const_iterator
52138fd1498Szrj upper_bound(const _Kt& __x) const
52238fd1498Szrj { return { _Base::upper_bound(__x), this }; }
52338fd1498Szrj #endif
52438fd1498Szrj
52538fd1498Szrj std::pair<iterator,iterator>
52638fd1498Szrj equal_range(const key_type& __x)
52738fd1498Szrj {
52838fd1498Szrj std::pair<_Base_iterator, _Base_iterator> __res =
52938fd1498Szrj _Base::equal_range(__x);
53038fd1498Szrj return std::make_pair(iterator(__res.first, this),
53138fd1498Szrj iterator(__res.second, this));
53238fd1498Szrj }
53338fd1498Szrj
53438fd1498Szrj #if __cplusplus > 201103L
53538fd1498Szrj template<typename _Kt,
53638fd1498Szrj typename _Req =
53738fd1498Szrj typename __has_is_transparent<_Compare, _Kt>::type>
53838fd1498Szrj std::pair<iterator, iterator>
53938fd1498Szrj equal_range(const _Kt& __x)
54038fd1498Szrj {
54138fd1498Szrj auto __res = _Base::equal_range(__x);
54238fd1498Szrj return { { __res.first, this }, { __res.second, this } };
54338fd1498Szrj }
54438fd1498Szrj #endif
54538fd1498Szrj
54638fd1498Szrj std::pair<const_iterator,const_iterator>
54738fd1498Szrj equal_range(const key_type& __x) const
54838fd1498Szrj {
54938fd1498Szrj std::pair<_Base_const_iterator, _Base_const_iterator> __res =
55038fd1498Szrj _Base::equal_range(__x);
55138fd1498Szrj return std::make_pair(const_iterator(__res.first, this),
55238fd1498Szrj const_iterator(__res.second, this));
55338fd1498Szrj }
55438fd1498Szrj
55538fd1498Szrj #if __cplusplus > 201103L
55638fd1498Szrj template<typename _Kt,
55738fd1498Szrj typename _Req =
55838fd1498Szrj typename __has_is_transparent<_Compare, _Kt>::type>
55938fd1498Szrj std::pair<const_iterator, const_iterator>
56038fd1498Szrj equal_range(const _Kt& __x) const
56138fd1498Szrj {
56238fd1498Szrj auto __res = _Base::equal_range(__x);
56338fd1498Szrj return { { __res.first, this }, { __res.second, this } };
56438fd1498Szrj }
56538fd1498Szrj #endif
56638fd1498Szrj
56738fd1498Szrj _Base&
56838fd1498Szrj _M_base() _GLIBCXX_NOEXCEPT { return *this; }
56938fd1498Szrj
57038fd1498Szrj const _Base&
57138fd1498Szrj _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
57238fd1498Szrj };
57338fd1498Szrj
57438fd1498Szrj #if __cpp_deduction_guides >= 201606
57538fd1498Szrj
57638fd1498Szrj template<typename _InputIterator,
57738fd1498Szrj typename _Compare = less<__iter_key_t<_InputIterator>>,
57838fd1498Szrj typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
57938fd1498Szrj typename = _RequireInputIter<_InputIterator>,
58038fd1498Szrj typename = _RequireAllocator<_Allocator>>
58138fd1498Szrj multimap(_InputIterator, _InputIterator,
58238fd1498Szrj _Compare = _Compare(), _Allocator = _Allocator())
58338fd1498Szrj -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
58438fd1498Szrj _Compare, _Allocator>;
58538fd1498Szrj
58638fd1498Szrj template<typename _Key, typename _Tp, typename _Compare = less<_Key>,
58738fd1498Szrj typename _Allocator = allocator<pair<const _Key, _Tp>>,
58838fd1498Szrj typename = _RequireAllocator<_Allocator>>
58938fd1498Szrj multimap(initializer_list<pair<_Key, _Tp>>,
59038fd1498Szrj _Compare = _Compare(), _Allocator = _Allocator())
59138fd1498Szrj -> multimap<_Key, _Tp, _Compare, _Allocator>;
59238fd1498Szrj
59338fd1498Szrj template<typename _InputIterator, typename _Allocator,
59438fd1498Szrj typename = _RequireInputIter<_InputIterator>,
59538fd1498Szrj typename = _RequireAllocator<_Allocator>>
59638fd1498Szrj multimap(_InputIterator, _InputIterator, _Allocator)
59738fd1498Szrj -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
59838fd1498Szrj less<__iter_key_t<_InputIterator>>, _Allocator>;
59938fd1498Szrj
60038fd1498Szrj template<typename _Key, typename _Tp, typename _Allocator,
60138fd1498Szrj typename = _RequireAllocator<_Allocator>>
60238fd1498Szrj multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
60338fd1498Szrj -> multimap<_Key, _Tp, less<_Key>, _Allocator>;
60438fd1498Szrj
60538fd1498Szrj #endif
60638fd1498Szrj
60738fd1498Szrj template<typename _Key, typename _Tp,
60838fd1498Szrj typename _Compare, typename _Allocator>
60938fd1498Szrj inline bool
61038fd1498Szrj operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
61138fd1498Szrj const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
61238fd1498Szrj { return __lhs._M_base() == __rhs._M_base(); }
61338fd1498Szrj
61438fd1498Szrj template<typename _Key, typename _Tp,
61538fd1498Szrj typename _Compare, typename _Allocator>
61638fd1498Szrj inline bool
61738fd1498Szrj operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
61838fd1498Szrj const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
61938fd1498Szrj { return __lhs._M_base() != __rhs._M_base(); }
62038fd1498Szrj
62138fd1498Szrj template<typename _Key, typename _Tp,
62238fd1498Szrj typename _Compare, typename _Allocator>
62338fd1498Szrj inline bool
62438fd1498Szrj operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
62538fd1498Szrj const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
62638fd1498Szrj { return __lhs._M_base() < __rhs._M_base(); }
62738fd1498Szrj
62838fd1498Szrj template<typename _Key, typename _Tp,
62938fd1498Szrj typename _Compare, typename _Allocator>
63038fd1498Szrj inline bool
63138fd1498Szrj operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
63238fd1498Szrj const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
63338fd1498Szrj { return __lhs._M_base() <= __rhs._M_base(); }
63438fd1498Szrj
63538fd1498Szrj template<typename _Key, typename _Tp,
63638fd1498Szrj typename _Compare, typename _Allocator>
63738fd1498Szrj inline bool
63838fd1498Szrj operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
63938fd1498Szrj const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
64038fd1498Szrj { return __lhs._M_base() >= __rhs._M_base(); }
64138fd1498Szrj
64238fd1498Szrj template<typename _Key, typename _Tp,
64338fd1498Szrj typename _Compare, typename _Allocator>
64438fd1498Szrj inline bool
64538fd1498Szrj operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
64638fd1498Szrj const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
64738fd1498Szrj { return __lhs._M_base() > __rhs._M_base(); }
64838fd1498Szrj
64938fd1498Szrj template<typename _Key, typename _Tp,
65038fd1498Szrj typename _Compare, typename _Allocator>
65138fd1498Szrj inline void
65238fd1498Szrj swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
65338fd1498Szrj multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
65438fd1498Szrj _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
65538fd1498Szrj { __lhs.swap(__rhs); }
65638fd1498Szrj
65738fd1498Szrj } // namespace __debug
65838fd1498Szrj } // namespace std
65938fd1498Szrj
66038fd1498Szrj #endif
661