libstdc++
multimap.h
Go to the documentation of this file.
00001 // Debugging multimap implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2019 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file debug/multimap.h
00026  *  This file is a GNU debug extension to the Standard C++ Library.
00027  */
00028 
00029 #ifndef _GLIBCXX_DEBUG_MULTIMAP_H
00030 #define _GLIBCXX_DEBUG_MULTIMAP_H 1
00031 
00032 #include <debug/safe_sequence.h>
00033 #include <debug/safe_container.h>
00034 #include <debug/safe_iterator.h>
00035 #include <utility>
00036 
00037 namespace std _GLIBCXX_VISIBILITY(default)
00038 {
00039 namespace __debug
00040 {
00041   /// Class std::multimap with safety/checking/debug instrumentation.
00042   template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
00043            typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
00044     class multimap
00045       : public __gnu_debug::_Safe_container<
00046         multimap<_Key, _Tp, _Compare, _Allocator>, _Allocator,
00047         __gnu_debug::_Safe_node_sequence>,
00048         public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>
00049     {
00050       typedef _GLIBCXX_STD_C::multimap<
00051         _Key, _Tp, _Compare, _Allocator>                        _Base;
00052       typedef __gnu_debug::_Safe_container<
00053         multimap, _Allocator, __gnu_debug::_Safe_node_sequence> _Safe;
00054 
00055       typedef typename _Base::const_iterator    _Base_const_iterator;
00056       typedef typename _Base::iterator          _Base_iterator;
00057       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
00058 
00059       template<typename _ItT, typename _SeqT, typename _CatT>
00060         friend class ::__gnu_debug::_Safe_iterator;
00061 
00062     public:
00063       // types:
00064       typedef _Key                                      key_type;
00065       typedef _Tp                                       mapped_type;
00066       typedef std::pair<const _Key, _Tp>                value_type;
00067       typedef _Compare                                  key_compare;
00068       typedef _Allocator                                allocator_type;
00069       typedef typename _Base::reference                 reference;
00070       typedef typename _Base::const_reference           const_reference;
00071 
00072       typedef __gnu_debug::_Safe_iterator<_Base_iterator, multimap>
00073                                                         iterator;
00074       typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
00075                                           multimap>     const_iterator;
00076 
00077       typedef typename _Base::size_type                 size_type;
00078       typedef typename _Base::difference_type           difference_type;
00079       typedef typename _Base::pointer                   pointer;
00080       typedef typename _Base::const_pointer             const_pointer;
00081       typedef std::reverse_iterator<iterator>           reverse_iterator;
00082       typedef std::reverse_iterator<const_iterator>     const_reverse_iterator;
00083 
00084       // 23.3.1.1 construct/copy/destroy:
00085 
00086 #if __cplusplus < 201103L
00087       multimap() : _Base() { }
00088 
00089       multimap(const multimap& __x)
00090       : _Base(__x) { }
00091 
00092       ~multimap() { }
00093 #else
00094       multimap() = default;
00095       multimap(const multimap&) = default;
00096       multimap(multimap&&) = default;
00097 
00098       multimap(initializer_list<value_type> __l,
00099                const _Compare& __c = _Compare(),
00100                const allocator_type& __a = allocator_type())
00101       : _Base(__l, __c, __a) { }
00102 
00103       explicit
00104       multimap(const allocator_type& __a)
00105       : _Base(__a) { }
00106 
00107       multimap(const multimap& __m, const allocator_type& __a)
00108       : _Base(__m, __a) { }
00109 
00110       multimap(multimap&& __m, const allocator_type& __a)
00111       noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) )
00112       : _Safe(std::move(__m._M_safe()), __a),
00113         _Base(std::move(__m._M_base()), __a) { }
00114 
00115       multimap(initializer_list<value_type> __l, const allocator_type& __a)
00116       : _Base(__l, __a) { }
00117 
00118       template<typename _InputIterator>
00119         multimap(_InputIterator __first, _InputIterator __last,
00120                  const allocator_type& __a)
00121         : _Base(__gnu_debug::__base(
00122                   __glibcxx_check_valid_constructor_range(__first, __last)),
00123                 __gnu_debug::__base(__last), __a) { }
00124 
00125       ~multimap() = default;
00126 #endif
00127 
00128       explicit multimap(const _Compare& __comp,
00129                         const _Allocator& __a = _Allocator())
00130       : _Base(__comp, __a) { }
00131 
00132       template<typename _InputIterator>
00133       multimap(_InputIterator __first, _InputIterator __last,
00134                const _Compare& __comp = _Compare(),
00135                const _Allocator& __a = _Allocator())
00136         : _Base(__gnu_debug::__base(
00137                   __glibcxx_check_valid_constructor_range(__first, __last)),
00138                 __gnu_debug::__base(__last),
00139               __comp, __a) { }
00140 
00141       multimap(const _Base& __x)
00142       : _Base(__x) { }
00143 
00144 #if __cplusplus < 201103L
00145       multimap&
00146       operator=(const multimap& __x)
00147       {
00148         this->_M_safe() = __x;
00149         _M_base() = __x;
00150         return *this;
00151       }
00152 #else
00153       multimap&
00154       operator=(const multimap&) = default;
00155 
00156       multimap&
00157       operator=(multimap&&) = default;
00158 
00159       multimap&
00160       operator=(initializer_list<value_type> __l)
00161       {
00162         _M_base() = __l;
00163         this->_M_invalidate_all();
00164         return *this;
00165       }
00166 #endif
00167 
00168       using _Base::get_allocator;
00169 
00170       // iterators:
00171       iterator
00172       begin() _GLIBCXX_NOEXCEPT
00173       { return iterator(_Base::begin(), this); }
00174 
00175       const_iterator
00176       begin() const _GLIBCXX_NOEXCEPT
00177       { return const_iterator(_Base::begin(), this); }
00178 
00179       iterator
00180       end() _GLIBCXX_NOEXCEPT
00181       { return iterator(_Base::end(), this); }
00182 
00183       const_iterator
00184       end() const _GLIBCXX_NOEXCEPT
00185       { return const_iterator(_Base::end(), this); }
00186 
00187       reverse_iterator
00188       rbegin() _GLIBCXX_NOEXCEPT
00189       { return reverse_iterator(end()); }
00190 
00191       const_reverse_iterator
00192       rbegin() const _GLIBCXX_NOEXCEPT
00193       { return const_reverse_iterator(end()); }
00194 
00195       reverse_iterator
00196       rend() _GLIBCXX_NOEXCEPT
00197       { return reverse_iterator(begin()); }
00198 
00199       const_reverse_iterator
00200       rend() const _GLIBCXX_NOEXCEPT
00201       { return const_reverse_iterator(begin()); }
00202 
00203 #if __cplusplus >= 201103L
00204       const_iterator
00205       cbegin() const noexcept
00206       { return const_iterator(_Base::begin(), this); }
00207 
00208       const_iterator
00209       cend() const noexcept
00210       { return const_iterator(_Base::end(), this); }
00211 
00212       const_reverse_iterator
00213       crbegin() const noexcept
00214       { return const_reverse_iterator(end()); }
00215 
00216       const_reverse_iterator
00217       crend() const noexcept
00218       { return const_reverse_iterator(begin()); }
00219 #endif
00220 
00221       // capacity:
00222       using _Base::empty;
00223       using _Base::size;
00224       using _Base::max_size;
00225 
00226       // modifiers:
00227 #if __cplusplus >= 201103L
00228       template<typename... _Args>
00229         iterator
00230         emplace(_Args&&... __args)
00231         { return { _Base::emplace(std::forward<_Args>(__args)...), this }; }
00232 
00233       template<typename... _Args>
00234         iterator
00235         emplace_hint(const_iterator __pos, _Args&&... __args)
00236         {
00237           __glibcxx_check_insert(__pos);
00238           return
00239             {
00240               _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...),
00241               this
00242             };
00243         }
00244 #endif
00245 
00246       iterator
00247       insert(const value_type& __x)
00248       { return iterator(_Base::insert(__x), this); }
00249 
00250 #if __cplusplus >= 201103L
00251       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00252       // 2354. Unnecessary copying when inserting into maps with braced-init
00253       iterator
00254       insert(value_type&& __x)
00255       { return { _Base::insert(std::move(__x)), this }; }
00256 
00257       template<typename _Pair, typename = typename
00258                std::enable_if<std::is_constructible<value_type,
00259                                                     _Pair&&>::value>::type>
00260         iterator
00261         insert(_Pair&& __x)
00262         { return { _Base::insert(std::forward<_Pair>(__x)), this }; }
00263 #endif
00264 
00265 #if __cplusplus >= 201103L
00266       void
00267       insert(std::initializer_list<value_type> __list)
00268       { _Base::insert(__list); }
00269 #endif
00270 
00271       iterator
00272 #if __cplusplus >= 201103L
00273       insert(const_iterator __position, const value_type& __x)
00274 #else
00275       insert(iterator __position, const value_type& __x)
00276 #endif
00277       {
00278         __glibcxx_check_insert(__position);
00279         return iterator(_Base::insert(__position.base(), __x), this);
00280       }
00281 
00282 #if __cplusplus >= 201103L
00283       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00284       // 2354. Unnecessary copying when inserting into maps with braced-init
00285       iterator
00286       insert(const_iterator __position, value_type&& __x)
00287       {
00288         __glibcxx_check_insert(__position);
00289         return { _Base::insert(__position.base(), std::move(__x)), this };
00290       }
00291 
00292       template<typename _Pair, typename = typename
00293                std::enable_if<std::is_constructible<value_type,
00294                                                     _Pair&&>::value>::type>
00295         iterator
00296         insert(const_iterator __position, _Pair&& __x)
00297         {
00298           __glibcxx_check_insert(__position);
00299           return
00300             {
00301               _Base::insert(__position.base(), std::forward<_Pair>(__x)),
00302               this
00303             };
00304         }
00305 #endif
00306 
00307       template<typename _InputIterator>
00308         void
00309         insert(_InputIterator __first, _InputIterator __last)
00310         {
00311           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
00312           __glibcxx_check_valid_range2(__first, __last, __dist);
00313 
00314           if (__dist.second >= __gnu_debug::__dp_sign)
00315             _Base::insert(__gnu_debug::__unsafe(__first),
00316                           __gnu_debug::__unsafe(__last));
00317           else
00318             _Base::insert(__first, __last);
00319         }
00320 
00321 #if __cplusplus > 201402L
00322       using node_type = typename _Base::node_type;
00323 
00324       node_type
00325       extract(const_iterator __position)
00326       {
00327         __glibcxx_check_erase(__position);
00328         this->_M_invalidate_if(_Equal(__position.base()));
00329         return _Base::extract(__position.base());
00330       }
00331 
00332       node_type
00333       extract(const key_type& __key)
00334       {
00335         const auto __position = find(__key);
00336         if (__position != end())
00337           return extract(__position);
00338         return {};
00339       }
00340 
00341       iterator
00342       insert(node_type&& __nh)
00343       { return { _Base::insert(std::move(__nh)), this }; }
00344 
00345       iterator
00346       insert(const_iterator __hint, node_type&& __nh)
00347       {
00348         __glibcxx_check_insert(__hint);
00349         return { _Base::insert(__hint.base(), std::move(__nh)), this };
00350       }
00351 
00352       using _Base::merge;
00353 #endif // C++17
00354 
00355 #if __cplusplus >= 201103L
00356       iterator
00357       erase(const_iterator __position)
00358       {
00359         __glibcxx_check_erase(__position);
00360         this->_M_invalidate_if(_Equal(__position.base()));
00361         return { _Base::erase(__position.base()), this };
00362       }
00363 
00364       _GLIBCXX_ABI_TAG_CXX11
00365       iterator
00366       erase(iterator __position)
00367       { return erase(const_iterator(__position)); }
00368 #else
00369       void
00370       erase(iterator __position)
00371       {
00372         __glibcxx_check_erase(__position);
00373         this->_M_invalidate_if(_Equal(__position.base()));
00374         _Base::erase(__position.base());
00375       }
00376 #endif
00377 
00378       size_type
00379       erase(const key_type& __x)
00380       {
00381         std::pair<_Base_iterator, _Base_iterator> __victims =
00382           _Base::equal_range(__x);
00383         size_type __count = 0;
00384         _Base_iterator __victim = __victims.first;
00385         while (__victim !=  __victims.second)
00386           {
00387             this->_M_invalidate_if(_Equal(__victim));
00388             _Base::erase(__victim++);
00389             ++__count;
00390           }
00391         return __count;
00392       }
00393 
00394 #if __cplusplus >= 201103L
00395       iterator
00396       erase(const_iterator __first, const_iterator __last)
00397       {
00398         // _GLIBCXX_RESOLVE_LIB_DEFECTS
00399         // 151. can't currently clear() empty container
00400         __glibcxx_check_erase_range(__first, __last);
00401         for (_Base_const_iterator __victim = __first.base();
00402              __victim != __last.base(); ++__victim)
00403           {
00404             _GLIBCXX_DEBUG_VERIFY(__victim != _Base::cend(),
00405                                   _M_message(__gnu_debug::__msg_valid_range)
00406                                   ._M_iterator(__first, "first")
00407                                   ._M_iterator(__last, "last"));
00408             this->_M_invalidate_if(_Equal(__victim));
00409           }
00410 
00411         return { _Base::erase(__first.base(), __last.base()), this };
00412       }
00413 #else
00414       void
00415       erase(iterator __first, iterator __last)
00416       {
00417         // _GLIBCXX_RESOLVE_LIB_DEFECTS
00418         // 151. can't currently clear() empty container
00419         __glibcxx_check_erase_range(__first, __last);
00420         for (_Base_iterator __victim = __first.base();
00421              __victim != __last.base(); ++__victim)
00422           {
00423             _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
00424                                   _M_message(__gnu_debug::__msg_valid_range)
00425                                   ._M_iterator(__first, "first")
00426                                   ._M_iterator(__last, "last"));
00427             this->_M_invalidate_if(_Equal(__victim));
00428           }
00429         _Base::erase(__first.base(), __last.base());
00430       }
00431 #endif
00432 
00433       void
00434       swap(multimap& __x)
00435       _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
00436       {
00437         _Safe::_M_swap(__x);
00438         _Base::swap(__x);
00439       }
00440 
00441       void
00442       clear() _GLIBCXX_NOEXCEPT
00443       {
00444         this->_M_invalidate_all();
00445         _Base::clear();
00446       }
00447 
00448       // observers:
00449       using _Base::key_comp;
00450       using _Base::value_comp;
00451 
00452       // 23.3.1.3 multimap operations:
00453       iterator
00454       find(const key_type& __x)
00455       { return iterator(_Base::find(__x), this); }
00456 
00457 #if __cplusplus > 201103L
00458       template<typename _Kt,
00459                typename _Req =
00460                  typename __has_is_transparent<_Compare, _Kt>::type>
00461         iterator
00462         find(const _Kt& __x)
00463         { return { _Base::find(__x), this }; }
00464 #endif
00465 
00466       const_iterator
00467       find(const key_type& __x) const
00468       { return const_iterator(_Base::find(__x), this); }
00469 
00470 #if __cplusplus > 201103L
00471       template<typename _Kt,
00472                typename _Req =
00473                  typename __has_is_transparent<_Compare, _Kt>::type>
00474         const_iterator
00475         find(const _Kt& __x) const
00476         { return { _Base::find(__x), this }; }
00477 #endif
00478 
00479       using _Base::count;
00480 
00481       iterator
00482       lower_bound(const key_type& __x)
00483       { return iterator(_Base::lower_bound(__x), this); }
00484 
00485 #if __cplusplus > 201103L
00486       template<typename _Kt,
00487                typename _Req =
00488                  typename __has_is_transparent<_Compare, _Kt>::type>
00489         iterator
00490         lower_bound(const _Kt& __x)
00491         { return { _Base::lower_bound(__x), this }; }
00492 #endif
00493 
00494       const_iterator
00495       lower_bound(const key_type& __x) const
00496       { return const_iterator(_Base::lower_bound(__x), this); }
00497 
00498 #if __cplusplus > 201103L
00499       template<typename _Kt,
00500                typename _Req =
00501                  typename __has_is_transparent<_Compare, _Kt>::type>
00502         const_iterator
00503         lower_bound(const _Kt& __x) const
00504         { return { _Base::lower_bound(__x), this }; }
00505 #endif
00506 
00507       iterator
00508       upper_bound(const key_type& __x)
00509       { return iterator(_Base::upper_bound(__x), this); }
00510 
00511 #if __cplusplus > 201103L
00512       template<typename _Kt,
00513                typename _Req =
00514                  typename __has_is_transparent<_Compare, _Kt>::type>
00515         iterator
00516         upper_bound(const _Kt& __x)
00517         { return { _Base::upper_bound(__x), this }; }
00518 #endif
00519 
00520       const_iterator
00521       upper_bound(const key_type& __x) const
00522       { return const_iterator(_Base::upper_bound(__x), this); }
00523 
00524 #if __cplusplus > 201103L
00525       template<typename _Kt,
00526                typename _Req =
00527                  typename __has_is_transparent<_Compare, _Kt>::type>
00528         const_iterator
00529         upper_bound(const _Kt& __x) const
00530         { return { _Base::upper_bound(__x), this }; }
00531 #endif
00532 
00533       std::pair<iterator,iterator>
00534       equal_range(const key_type& __x)
00535       {
00536         std::pair<_Base_iterator, _Base_iterator> __res =
00537         _Base::equal_range(__x);
00538         return std::make_pair(iterator(__res.first, this),
00539                               iterator(__res.second, this));
00540       }
00541 
00542 #if __cplusplus > 201103L
00543       template<typename _Kt,
00544                typename _Req =
00545                  typename __has_is_transparent<_Compare, _Kt>::type>
00546         std::pair<iterator, iterator>
00547         equal_range(const _Kt& __x)
00548         {
00549           auto __res = _Base::equal_range(__x);
00550           return { { __res.first, this }, { __res.second, this } };
00551         }
00552 #endif
00553 
00554       std::pair<const_iterator,const_iterator>
00555       equal_range(const key_type& __x) const
00556       {
00557         std::pair<_Base_const_iterator, _Base_const_iterator> __res =
00558           _Base::equal_range(__x);
00559         return std::make_pair(const_iterator(__res.first, this),
00560                               const_iterator(__res.second, this));
00561       }
00562 
00563 #if __cplusplus > 201103L
00564       template<typename _Kt,
00565                typename _Req =
00566                  typename __has_is_transparent<_Compare, _Kt>::type>
00567         std::pair<const_iterator, const_iterator>
00568         equal_range(const _Kt& __x) const
00569         {
00570           auto __res = _Base::equal_range(__x);
00571           return { { __res.first, this }, { __res.second, this } };
00572         }
00573 #endif
00574 
00575       _Base&
00576       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
00577 
00578       const _Base&
00579       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
00580     };
00581 
00582 #if __cpp_deduction_guides >= 201606
00583 
00584   template<typename _InputIterator,
00585            typename _Compare = less<__iter_key_t<_InputIterator>>,
00586            typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
00587            typename = _RequireInputIter<_InputIterator>,
00588            typename = _RequireNotAllocator<_Compare>,
00589            typename = _RequireAllocator<_Allocator>>
00590     multimap(_InputIterator, _InputIterator,
00591              _Compare = _Compare(), _Allocator = _Allocator())
00592     -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
00593                 _Compare, _Allocator>;
00594 
00595   template<typename _Key, typename _Tp, typename _Compare = less<_Key>,
00596            typename _Allocator = allocator<pair<const _Key, _Tp>>,
00597            typename = _RequireNotAllocator<_Compare>,
00598            typename = _RequireAllocator<_Allocator>>
00599     multimap(initializer_list<pair<_Key, _Tp>>,
00600              _Compare = _Compare(), _Allocator = _Allocator())
00601     -> multimap<_Key, _Tp, _Compare, _Allocator>;
00602 
00603   template<typename _InputIterator, typename _Allocator,
00604            typename = _RequireInputIter<_InputIterator>,
00605            typename = _RequireAllocator<_Allocator>>
00606     multimap(_InputIterator, _InputIterator, _Allocator)
00607     -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
00608     less<__iter_key_t<_InputIterator>>, _Allocator>;
00609 
00610   template<typename _Key, typename _Tp, typename _Allocator,
00611            typename = _RequireAllocator<_Allocator>>
00612     multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
00613     -> multimap<_Key, _Tp, less<_Key>, _Allocator>;
00614 
00615 #endif
00616 
00617   template<typename _Key, typename _Tp,
00618            typename _Compare, typename _Allocator>
00619     inline bool
00620     operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00621                const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00622     { return __lhs._M_base() == __rhs._M_base(); }
00623 
00624   template<typename _Key, typename _Tp,
00625            typename _Compare, typename _Allocator>
00626     inline bool
00627     operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00628                const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00629     { return __lhs._M_base() != __rhs._M_base(); }
00630 
00631   template<typename _Key, typename _Tp,
00632            typename _Compare, typename _Allocator>
00633     inline bool
00634     operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00635               const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00636     { return __lhs._M_base() < __rhs._M_base(); }
00637 
00638   template<typename _Key, typename _Tp,
00639            typename _Compare, typename _Allocator>
00640     inline bool
00641     operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00642                const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00643     { return __lhs._M_base() <= __rhs._M_base(); }
00644 
00645   template<typename _Key, typename _Tp,
00646            typename _Compare, typename _Allocator>
00647     inline bool
00648     operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00649                const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00650     { return __lhs._M_base() >= __rhs._M_base(); }
00651 
00652   template<typename _Key, typename _Tp,
00653            typename _Compare, typename _Allocator>
00654     inline bool
00655     operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00656               const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00657     { return __lhs._M_base() > __rhs._M_base(); }
00658 
00659   template<typename _Key, typename _Tp,
00660            typename _Compare, typename _Allocator>
00661     inline void
00662     swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00663          multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00664     _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
00665     { __lhs.swap(__rhs); }
00666 
00667 } // namespace __debug
00668 } // namespace std
00669 
00670 #endif