1*e4b17023SJohn Marino // Debugging multiset implementation -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 4*e4b17023SJohn Marino // Free Software Foundation, Inc. 5*e4b17023SJohn Marino // 6*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 7*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the 8*e4b17023SJohn Marino // terms of the GNU General Public License as published by the 9*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option) 10*e4b17023SJohn Marino // any later version. 11*e4b17023SJohn Marino 12*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, 13*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of 14*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*e4b17023SJohn Marino // GNU General Public License for more details. 16*e4b17023SJohn Marino 17*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 18*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 19*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 20*e4b17023SJohn Marino 21*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 22*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 23*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 25*e4b17023SJohn Marino 26*e4b17023SJohn Marino /** @file debug/multiset.h 27*e4b17023SJohn Marino * This file is a GNU debug extension to the Standard C++ Library. 28*e4b17023SJohn Marino */ 29*e4b17023SJohn Marino 30*e4b17023SJohn Marino #ifndef _GLIBCXX_DEBUG_MULTISET_H 31*e4b17023SJohn Marino #define _GLIBCXX_DEBUG_MULTISET_H 1 32*e4b17023SJohn Marino 33*e4b17023SJohn Marino #include <debug/safe_sequence.h> 34*e4b17023SJohn Marino #include <debug/safe_iterator.h> 35*e4b17023SJohn Marino #include <utility> 36*e4b17023SJohn Marino 37*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default) 38*e4b17023SJohn Marino { 39*e4b17023SJohn Marino namespace __debug 40*e4b17023SJohn Marino { 41*e4b17023SJohn Marino /// Class std::multiset with safety/checking/debug instrumentation. 42*e4b17023SJohn Marino template<typename _Key, typename _Compare = std::less<_Key>, 43*e4b17023SJohn Marino typename _Allocator = std::allocator<_Key> > 44*e4b17023SJohn Marino class multiset 45*e4b17023SJohn Marino : public _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator>, 46*e4b17023SJohn Marino public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> > 47*e4b17023SJohn Marino { 48*e4b17023SJohn Marino typedef _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator> _Base; 49*e4b17023SJohn Marino 50*e4b17023SJohn Marino typedef typename _Base::const_iterator _Base_const_iterator; 51*e4b17023SJohn Marino typedef typename _Base::iterator _Base_iterator; 52*e4b17023SJohn Marino typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; 53*e4b17023SJohn Marino public: 54*e4b17023SJohn Marino // types: 55*e4b17023SJohn Marino typedef _Key key_type; 56*e4b17023SJohn Marino typedef _Key value_type; 57*e4b17023SJohn Marino typedef _Compare key_compare; 58*e4b17023SJohn Marino typedef _Compare value_compare; 59*e4b17023SJohn Marino typedef _Allocator allocator_type; 60*e4b17023SJohn Marino typedef typename _Base::reference reference; 61*e4b17023SJohn Marino typedef typename _Base::const_reference const_reference; 62*e4b17023SJohn Marino 63*e4b17023SJohn Marino typedef __gnu_debug::_Safe_iterator<_Base_iterator, multiset> 64*e4b17023SJohn Marino iterator; 65*e4b17023SJohn Marino typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, 66*e4b17023SJohn Marino multiset> const_iterator; 67*e4b17023SJohn Marino 68*e4b17023SJohn Marino typedef typename _Base::size_type size_type; 69*e4b17023SJohn Marino typedef typename _Base::difference_type difference_type; 70*e4b17023SJohn Marino typedef typename _Base::pointer pointer; 71*e4b17023SJohn Marino typedef typename _Base::const_pointer const_pointer; 72*e4b17023SJohn Marino typedef std::reverse_iterator<iterator> reverse_iterator; 73*e4b17023SJohn Marino typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 74*e4b17023SJohn Marino 75*e4b17023SJohn Marino // 23.3.3.1 construct/copy/destroy: 76*e4b17023SJohn Marino explicit multiset(const _Compare& __comp = _Compare(), 77*e4b17023SJohn Marino const _Allocator& __a = _Allocator()) 78*e4b17023SJohn Marino : _Base(__comp, __a) { } 79*e4b17023SJohn Marino 80*e4b17023SJohn Marino template<typename _InputIterator> 81*e4b17023SJohn Marino multiset(_InputIterator __first, _InputIterator __last, 82*e4b17023SJohn Marino const _Compare& __comp = _Compare(), 83*e4b17023SJohn Marino const _Allocator& __a = _Allocator()) 84*e4b17023SJohn Marino : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, 85*e4b17023SJohn Marino __last)), 86*e4b17023SJohn Marino __gnu_debug::__base(__last), 87*e4b17023SJohn Marino __comp, __a) { } 88*e4b17023SJohn Marino 89*e4b17023SJohn Marino multiset(const multiset& __x) 90*e4b17023SJohn Marino : _Base(__x) { } 91*e4b17023SJohn Marino 92*e4b17023SJohn Marino multiset(const _Base& __x) 93*e4b17023SJohn Marino : _Base(__x) { } 94*e4b17023SJohn Marino 95*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 96*e4b17023SJohn Marino multiset(multiset&& __x) 97*e4b17023SJohn Marino noexcept(is_nothrow_copy_constructible<_Compare>::value) 98*e4b17023SJohn Marino : _Base(std::move(__x)) 99*e4b17023SJohn Marino { this->_M_swap(__x); } 100*e4b17023SJohn Marino 101*e4b17023SJohn Marino multiset(initializer_list<value_type> __l, 102*e4b17023SJohn Marino const _Compare& __comp = _Compare(), 103*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 104*e4b17023SJohn Marino : _Base(__l, __comp, __a) { } 105*e4b17023SJohn Marino #endif 106*e4b17023SJohn Marino 107*e4b17023SJohn Marino ~multiset() _GLIBCXX_NOEXCEPT { } 108*e4b17023SJohn Marino 109*e4b17023SJohn Marino multiset& 110*e4b17023SJohn Marino operator=(const multiset& __x) 111*e4b17023SJohn Marino { 112*e4b17023SJohn Marino *static_cast<_Base*>(this) = __x; 113*e4b17023SJohn Marino this->_M_invalidate_all(); 114*e4b17023SJohn Marino return *this; 115*e4b17023SJohn Marino } 116*e4b17023SJohn Marino 117*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 118*e4b17023SJohn Marino multiset& 119*e4b17023SJohn Marino operator=(multiset&& __x) 120*e4b17023SJohn Marino { 121*e4b17023SJohn Marino // NB: DR 1204. 122*e4b17023SJohn Marino // NB: DR 675. 123*e4b17023SJohn Marino clear(); 124*e4b17023SJohn Marino swap(__x); 125*e4b17023SJohn Marino return *this; 126*e4b17023SJohn Marino } 127*e4b17023SJohn Marino 128*e4b17023SJohn Marino multiset& 129*e4b17023SJohn Marino operator=(initializer_list<value_type> __l) 130*e4b17023SJohn Marino { 131*e4b17023SJohn Marino this->clear(); 132*e4b17023SJohn Marino this->insert(__l); 133*e4b17023SJohn Marino return *this; 134*e4b17023SJohn Marino } 135*e4b17023SJohn Marino #endif 136*e4b17023SJohn Marino 137*e4b17023SJohn Marino using _Base::get_allocator; 138*e4b17023SJohn Marino 139*e4b17023SJohn Marino // iterators: 140*e4b17023SJohn Marino iterator 141*e4b17023SJohn Marino begin() _GLIBCXX_NOEXCEPT 142*e4b17023SJohn Marino { return iterator(_Base::begin(), this); } 143*e4b17023SJohn Marino 144*e4b17023SJohn Marino const_iterator 145*e4b17023SJohn Marino begin() const _GLIBCXX_NOEXCEPT 146*e4b17023SJohn Marino { return const_iterator(_Base::begin(), this); } 147*e4b17023SJohn Marino 148*e4b17023SJohn Marino iterator 149*e4b17023SJohn Marino end() _GLIBCXX_NOEXCEPT 150*e4b17023SJohn Marino { return iterator(_Base::end(), this); } 151*e4b17023SJohn Marino 152*e4b17023SJohn Marino const_iterator 153*e4b17023SJohn Marino end() const _GLIBCXX_NOEXCEPT 154*e4b17023SJohn Marino { return const_iterator(_Base::end(), this); } 155*e4b17023SJohn Marino 156*e4b17023SJohn Marino reverse_iterator 157*e4b17023SJohn Marino rbegin() _GLIBCXX_NOEXCEPT 158*e4b17023SJohn Marino { return reverse_iterator(end()); } 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino const_reverse_iterator 161*e4b17023SJohn Marino rbegin() const _GLIBCXX_NOEXCEPT 162*e4b17023SJohn Marino { return const_reverse_iterator(end()); } 163*e4b17023SJohn Marino 164*e4b17023SJohn Marino reverse_iterator 165*e4b17023SJohn Marino rend() _GLIBCXX_NOEXCEPT 166*e4b17023SJohn Marino { return reverse_iterator(begin()); } 167*e4b17023SJohn Marino 168*e4b17023SJohn Marino const_reverse_iterator 169*e4b17023SJohn Marino rend() const _GLIBCXX_NOEXCEPT 170*e4b17023SJohn Marino { return const_reverse_iterator(begin()); } 171*e4b17023SJohn Marino 172*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 173*e4b17023SJohn Marino const_iterator 174*e4b17023SJohn Marino cbegin() const noexcept 175*e4b17023SJohn Marino { return const_iterator(_Base::begin(), this); } 176*e4b17023SJohn Marino 177*e4b17023SJohn Marino const_iterator 178*e4b17023SJohn Marino cend() const noexcept 179*e4b17023SJohn Marino { return const_iterator(_Base::end(), this); } 180*e4b17023SJohn Marino 181*e4b17023SJohn Marino const_reverse_iterator 182*e4b17023SJohn Marino crbegin() const noexcept 183*e4b17023SJohn Marino { return const_reverse_iterator(end()); } 184*e4b17023SJohn Marino 185*e4b17023SJohn Marino const_reverse_iterator 186*e4b17023SJohn Marino crend() const noexcept 187*e4b17023SJohn Marino { return const_reverse_iterator(begin()); } 188*e4b17023SJohn Marino #endif 189*e4b17023SJohn Marino 190*e4b17023SJohn Marino // capacity: 191*e4b17023SJohn Marino using _Base::empty; 192*e4b17023SJohn Marino using _Base::size; 193*e4b17023SJohn Marino using _Base::max_size; 194*e4b17023SJohn Marino 195*e4b17023SJohn Marino // modifiers: 196*e4b17023SJohn Marino iterator 197*e4b17023SJohn Marino insert(const value_type& __x) 198*e4b17023SJohn Marino { return iterator(_Base::insert(__x), this); } 199*e4b17023SJohn Marino 200*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 201*e4b17023SJohn Marino iterator 202*e4b17023SJohn Marino insert(value_type&& __x) 203*e4b17023SJohn Marino { return iterator(_Base::insert(std::move(__x)), this); } 204*e4b17023SJohn Marino #endif 205*e4b17023SJohn Marino 206*e4b17023SJohn Marino iterator 207*e4b17023SJohn Marino insert(const_iterator __position, const value_type& __x) 208*e4b17023SJohn Marino { 209*e4b17023SJohn Marino __glibcxx_check_insert(__position); 210*e4b17023SJohn Marino return iterator(_Base::insert(__position.base(), __x), this); 211*e4b17023SJohn Marino } 212*e4b17023SJohn Marino 213*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 214*e4b17023SJohn Marino iterator 215*e4b17023SJohn Marino insert(const_iterator __position, value_type&& __x) 216*e4b17023SJohn Marino { 217*e4b17023SJohn Marino __glibcxx_check_insert(__position); 218*e4b17023SJohn Marino return iterator(_Base::insert(__position.base(), std::move(__x)), 219*e4b17023SJohn Marino this); 220*e4b17023SJohn Marino } 221*e4b17023SJohn Marino #endif 222*e4b17023SJohn Marino 223*e4b17023SJohn Marino template<typename _InputIterator> 224*e4b17023SJohn Marino void 225*e4b17023SJohn Marino insert(_InputIterator __first, _InputIterator __last) 226*e4b17023SJohn Marino { 227*e4b17023SJohn Marino __glibcxx_check_valid_range(__first, __last); 228*e4b17023SJohn Marino _Base::insert(__gnu_debug::__base(__first), 229*e4b17023SJohn Marino __gnu_debug::__base(__last)); 230*e4b17023SJohn Marino } 231*e4b17023SJohn Marino 232*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 233*e4b17023SJohn Marino void 234*e4b17023SJohn Marino insert(initializer_list<value_type> __l) 235*e4b17023SJohn Marino { _Base::insert(__l); } 236*e4b17023SJohn Marino #endif 237*e4b17023SJohn Marino 238*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 239*e4b17023SJohn Marino iterator 240*e4b17023SJohn Marino erase(const_iterator __position) 241*e4b17023SJohn Marino { 242*e4b17023SJohn Marino __glibcxx_check_erase(__position); 243*e4b17023SJohn Marino this->_M_invalidate_if(_Equal(__position.base())); 244*e4b17023SJohn Marino return iterator(_Base::erase(__position.base()), this); 245*e4b17023SJohn Marino } 246*e4b17023SJohn Marino #else 247*e4b17023SJohn Marino void 248*e4b17023SJohn Marino erase(iterator __position) 249*e4b17023SJohn Marino { 250*e4b17023SJohn Marino __glibcxx_check_erase(__position); 251*e4b17023SJohn Marino this->_M_invalidate_if(_Equal(__position.base())); 252*e4b17023SJohn Marino _Base::erase(__position.base()); 253*e4b17023SJohn Marino } 254*e4b17023SJohn Marino #endif 255*e4b17023SJohn Marino 256*e4b17023SJohn Marino size_type 257*e4b17023SJohn Marino erase(const key_type& __x) 258*e4b17023SJohn Marino { 259*e4b17023SJohn Marino std::pair<_Base_iterator, _Base_iterator> __victims = 260*e4b17023SJohn Marino _Base::equal_range(__x); 261*e4b17023SJohn Marino size_type __count = 0; 262*e4b17023SJohn Marino _Base_iterator __victim = __victims.first; 263*e4b17023SJohn Marino while (__victim != __victims.second) 264*e4b17023SJohn Marino { 265*e4b17023SJohn Marino this->_M_invalidate_if(_Equal(__victim)); 266*e4b17023SJohn Marino _Base::erase(__victim++); 267*e4b17023SJohn Marino ++__count; 268*e4b17023SJohn Marino } 269*e4b17023SJohn Marino return __count; 270*e4b17023SJohn Marino } 271*e4b17023SJohn Marino 272*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 273*e4b17023SJohn Marino iterator 274*e4b17023SJohn Marino erase(const_iterator __first, const_iterator __last) 275*e4b17023SJohn Marino { 276*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 277*e4b17023SJohn Marino // 151. can't currently clear() empty container 278*e4b17023SJohn Marino __glibcxx_check_erase_range(__first, __last); 279*e4b17023SJohn Marino for (_Base_const_iterator __victim = __first.base(); 280*e4b17023SJohn Marino __victim != __last.base(); ++__victim) 281*e4b17023SJohn Marino { 282*e4b17023SJohn Marino _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(), 283*e4b17023SJohn Marino _M_message(__gnu_debug::__msg_valid_range) 284*e4b17023SJohn Marino ._M_iterator(__first, "first") 285*e4b17023SJohn Marino ._M_iterator(__last, "last")); 286*e4b17023SJohn Marino this->_M_invalidate_if(_Equal(__victim)); 287*e4b17023SJohn Marino } 288*e4b17023SJohn Marino return iterator(_Base::erase(__first.base(), __last.base()), this); 289*e4b17023SJohn Marino } 290*e4b17023SJohn Marino #else 291*e4b17023SJohn Marino void 292*e4b17023SJohn Marino erase(iterator __first, iterator __last) 293*e4b17023SJohn Marino { 294*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 295*e4b17023SJohn Marino // 151. can't currently clear() empty container 296*e4b17023SJohn Marino __glibcxx_check_erase_range(__first, __last); 297*e4b17023SJohn Marino for (_Base_iterator __victim = __first.base(); 298*e4b17023SJohn Marino __victim != __last.base(); ++__victim) 299*e4b17023SJohn Marino { 300*e4b17023SJohn Marino _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(), 301*e4b17023SJohn Marino _M_message(__gnu_debug::__msg_valid_range) 302*e4b17023SJohn Marino ._M_iterator(__first, "first") 303*e4b17023SJohn Marino ._M_iterator(__last, "last")); 304*e4b17023SJohn Marino this->_M_invalidate_if(_Equal(__victim)); 305*e4b17023SJohn Marino } 306*e4b17023SJohn Marino _Base::erase(__first.base(), __last.base()); 307*e4b17023SJohn Marino } 308*e4b17023SJohn Marino #endif 309*e4b17023SJohn Marino 310*e4b17023SJohn Marino void 311*e4b17023SJohn Marino swap(multiset& __x) 312*e4b17023SJohn Marino { 313*e4b17023SJohn Marino _Base::swap(__x); 314*e4b17023SJohn Marino this->_M_swap(__x); 315*e4b17023SJohn Marino } 316*e4b17023SJohn Marino 317*e4b17023SJohn Marino void 318*e4b17023SJohn Marino clear() _GLIBCXX_NOEXCEPT 319*e4b17023SJohn Marino { 320*e4b17023SJohn Marino this->_M_invalidate_all(); 321*e4b17023SJohn Marino _Base::clear(); 322*e4b17023SJohn Marino } 323*e4b17023SJohn Marino 324*e4b17023SJohn Marino // observers: 325*e4b17023SJohn Marino using _Base::key_comp; 326*e4b17023SJohn Marino using _Base::value_comp; 327*e4b17023SJohn Marino 328*e4b17023SJohn Marino // multiset operations: 329*e4b17023SJohn Marino iterator 330*e4b17023SJohn Marino find(const key_type& __x) 331*e4b17023SJohn Marino { return iterator(_Base::find(__x), this); } 332*e4b17023SJohn Marino 333*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 334*e4b17023SJohn Marino // 214. set::find() missing const overload 335*e4b17023SJohn Marino const_iterator 336*e4b17023SJohn Marino find(const key_type& __x) const 337*e4b17023SJohn Marino { return const_iterator(_Base::find(__x), this); } 338*e4b17023SJohn Marino 339*e4b17023SJohn Marino using _Base::count; 340*e4b17023SJohn Marino 341*e4b17023SJohn Marino iterator 342*e4b17023SJohn Marino lower_bound(const key_type& __x) 343*e4b17023SJohn Marino { return iterator(_Base::lower_bound(__x), this); } 344*e4b17023SJohn Marino 345*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 346*e4b17023SJohn Marino // 214. set::find() missing const overload 347*e4b17023SJohn Marino const_iterator 348*e4b17023SJohn Marino lower_bound(const key_type& __x) const 349*e4b17023SJohn Marino { return const_iterator(_Base::lower_bound(__x), this); } 350*e4b17023SJohn Marino 351*e4b17023SJohn Marino iterator 352*e4b17023SJohn Marino upper_bound(const key_type& __x) 353*e4b17023SJohn Marino { return iterator(_Base::upper_bound(__x), this); } 354*e4b17023SJohn Marino 355*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 356*e4b17023SJohn Marino // 214. set::find() missing const overload 357*e4b17023SJohn Marino const_iterator 358*e4b17023SJohn Marino upper_bound(const key_type& __x) const 359*e4b17023SJohn Marino { return const_iterator(_Base::upper_bound(__x), this); } 360*e4b17023SJohn Marino 361*e4b17023SJohn Marino std::pair<iterator,iterator> 362*e4b17023SJohn Marino equal_range(const key_type& __x) 363*e4b17023SJohn Marino { 364*e4b17023SJohn Marino std::pair<_Base_iterator, _Base_iterator> __res = 365*e4b17023SJohn Marino _Base::equal_range(__x); 366*e4b17023SJohn Marino return std::make_pair(iterator(__res.first, this), 367*e4b17023SJohn Marino iterator(__res.second, this)); 368*e4b17023SJohn Marino } 369*e4b17023SJohn Marino 370*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 371*e4b17023SJohn Marino // 214. set::find() missing const overload 372*e4b17023SJohn Marino std::pair<const_iterator,const_iterator> 373*e4b17023SJohn Marino equal_range(const key_type& __x) const 374*e4b17023SJohn Marino { 375*e4b17023SJohn Marino std::pair<_Base_const_iterator, _Base_const_iterator> __res = 376*e4b17023SJohn Marino _Base::equal_range(__x); 377*e4b17023SJohn Marino return std::make_pair(const_iterator(__res.first, this), 378*e4b17023SJohn Marino const_iterator(__res.second, this)); 379*e4b17023SJohn Marino } 380*e4b17023SJohn Marino 381*e4b17023SJohn Marino _Base& 382*e4b17023SJohn Marino _M_base() _GLIBCXX_NOEXCEPT { return *this; } 383*e4b17023SJohn Marino 384*e4b17023SJohn Marino const _Base& 385*e4b17023SJohn Marino _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 386*e4b17023SJohn Marino 387*e4b17023SJohn Marino private: 388*e4b17023SJohn Marino void 389*e4b17023SJohn Marino _M_invalidate_all() 390*e4b17023SJohn Marino { 391*e4b17023SJohn Marino typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; 392*e4b17023SJohn Marino this->_M_invalidate_if(_Not_equal(_Base::end())); 393*e4b17023SJohn Marino } 394*e4b17023SJohn Marino }; 395*e4b17023SJohn Marino 396*e4b17023SJohn Marino template<typename _Key, typename _Compare, typename _Allocator> 397*e4b17023SJohn Marino inline bool 398*e4b17023SJohn Marino operator==(const multiset<_Key, _Compare, _Allocator>& __lhs, 399*e4b17023SJohn Marino const multiset<_Key, _Compare, _Allocator>& __rhs) 400*e4b17023SJohn Marino { return __lhs._M_base() == __rhs._M_base(); } 401*e4b17023SJohn Marino 402*e4b17023SJohn Marino template<typename _Key, typename _Compare, typename _Allocator> 403*e4b17023SJohn Marino inline bool 404*e4b17023SJohn Marino operator!=(const multiset<_Key, _Compare, _Allocator>& __lhs, 405*e4b17023SJohn Marino const multiset<_Key, _Compare, _Allocator>& __rhs) 406*e4b17023SJohn Marino { return __lhs._M_base() != __rhs._M_base(); } 407*e4b17023SJohn Marino 408*e4b17023SJohn Marino template<typename _Key, typename _Compare, typename _Allocator> 409*e4b17023SJohn Marino inline bool 410*e4b17023SJohn Marino operator<(const multiset<_Key, _Compare, _Allocator>& __lhs, 411*e4b17023SJohn Marino const multiset<_Key, _Compare, _Allocator>& __rhs) 412*e4b17023SJohn Marino { return __lhs._M_base() < __rhs._M_base(); } 413*e4b17023SJohn Marino 414*e4b17023SJohn Marino template<typename _Key, typename _Compare, typename _Allocator> 415*e4b17023SJohn Marino inline bool 416*e4b17023SJohn Marino operator<=(const multiset<_Key, _Compare, _Allocator>& __lhs, 417*e4b17023SJohn Marino const multiset<_Key, _Compare, _Allocator>& __rhs) 418*e4b17023SJohn Marino { return __lhs._M_base() <= __rhs._M_base(); } 419*e4b17023SJohn Marino 420*e4b17023SJohn Marino template<typename _Key, typename _Compare, typename _Allocator> 421*e4b17023SJohn Marino inline bool 422*e4b17023SJohn Marino operator>=(const multiset<_Key, _Compare, _Allocator>& __lhs, 423*e4b17023SJohn Marino const multiset<_Key, _Compare, _Allocator>& __rhs) 424*e4b17023SJohn Marino { return __lhs._M_base() >= __rhs._M_base(); } 425*e4b17023SJohn Marino 426*e4b17023SJohn Marino template<typename _Key, typename _Compare, typename _Allocator> 427*e4b17023SJohn Marino inline bool 428*e4b17023SJohn Marino operator>(const multiset<_Key, _Compare, _Allocator>& __lhs, 429*e4b17023SJohn Marino const multiset<_Key, _Compare, _Allocator>& __rhs) 430*e4b17023SJohn Marino { return __lhs._M_base() > __rhs._M_base(); } 431*e4b17023SJohn Marino 432*e4b17023SJohn Marino template<typename _Key, typename _Compare, typename _Allocator> 433*e4b17023SJohn Marino void 434*e4b17023SJohn Marino swap(multiset<_Key, _Compare, _Allocator>& __x, 435*e4b17023SJohn Marino multiset<_Key, _Compare, _Allocator>& __y) 436*e4b17023SJohn Marino { return __x.swap(__y); } 437*e4b17023SJohn Marino 438*e4b17023SJohn Marino } // namespace __debug 439*e4b17023SJohn Marino } // namespace std 440*e4b17023SJohn Marino 441*e4b17023SJohn Marino #endif 442