1ffeaf689SAlexander Kabaev // Debugging multiset implementation -*- C++ -*- 2ffeaf689SAlexander Kabaev 3*f8a1b7d9SAlexander Kabaev // Copyright (C) 2003, 2004, 2005 4ffeaf689SAlexander Kabaev // Free Software Foundation, Inc. 5ffeaf689SAlexander Kabaev // 6ffeaf689SAlexander Kabaev // This file is part of the GNU ISO C++ Library. This library is free 7ffeaf689SAlexander Kabaev // software; you can redistribute it and/or modify it under the 8ffeaf689SAlexander Kabaev // terms of the GNU General Public License as published by the 9ffeaf689SAlexander Kabaev // Free Software Foundation; either version 2, or (at your option) 10ffeaf689SAlexander Kabaev // any later version. 11ffeaf689SAlexander Kabaev 12ffeaf689SAlexander Kabaev // This library is distributed in the hope that it will be useful, 13ffeaf689SAlexander Kabaev // but WITHOUT ANY WARRANTY; without even the implied warranty of 14ffeaf689SAlexander Kabaev // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15ffeaf689SAlexander Kabaev // GNU General Public License for more details. 16ffeaf689SAlexander Kabaev 17ffeaf689SAlexander Kabaev // You should have received a copy of the GNU General Public License along 18ffeaf689SAlexander Kabaev // with this library; see the file COPYING. If not, write to the Free 19*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20ffeaf689SAlexander Kabaev // USA. 21ffeaf689SAlexander Kabaev 22ffeaf689SAlexander Kabaev // As a special exception, you may use this file as part of a free software 23ffeaf689SAlexander Kabaev // library without restriction. Specifically, if other files instantiate 24ffeaf689SAlexander Kabaev // templates or use macros or inline functions from this file, or you compile 25ffeaf689SAlexander Kabaev // this file and link it with other files to produce an executable, this 26ffeaf689SAlexander Kabaev // file does not by itself cause the resulting executable to be covered by 27ffeaf689SAlexander Kabaev // the GNU General Public License. This exception does not however 28ffeaf689SAlexander Kabaev // invalidate any other reasons why the executable file might be covered by 29ffeaf689SAlexander Kabaev // the GNU General Public License. 30ffeaf689SAlexander Kabaev 31*f8a1b7d9SAlexander Kabaev /** @file debug/multiset.h 32*f8a1b7d9SAlexander Kabaev * This file is a GNU debug extension to the Standard C++ Library. 33*f8a1b7d9SAlexander Kabaev */ 34*f8a1b7d9SAlexander Kabaev 35ffeaf689SAlexander Kabaev #ifndef _GLIBCXX_DEBUG_MULTISET_H 36ffeaf689SAlexander Kabaev #define _GLIBCXX_DEBUG_MULTISET_H 1 37ffeaf689SAlexander Kabaev 38ffeaf689SAlexander Kabaev #include <debug/safe_sequence.h> 39ffeaf689SAlexander Kabaev #include <debug/safe_iterator.h> 40ffeaf689SAlexander Kabaev #include <utility> 41ffeaf689SAlexander Kabaev 42*f8a1b7d9SAlexander Kabaev namespace std 43*f8a1b7d9SAlexander Kabaev { 44*f8a1b7d9SAlexander Kabaev namespace __debug 45ffeaf689SAlexander Kabaev { 46ffeaf689SAlexander Kabaev template<typename _Key, typename _Compare = std::less<_Key>, 47ffeaf689SAlexander Kabaev typename _Allocator = std::allocator<_Key> > 48ffeaf689SAlexander Kabaev class multiset 49ffeaf689SAlexander Kabaev : public _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator>, 50ffeaf689SAlexander Kabaev public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> > 51ffeaf689SAlexander Kabaev { 52ffeaf689SAlexander Kabaev typedef _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator> _Base; 53ffeaf689SAlexander Kabaev typedef __gnu_debug::_Safe_sequence<multiset> _Safe_base; 54ffeaf689SAlexander Kabaev 55ffeaf689SAlexander Kabaev public: 56ffeaf689SAlexander Kabaev // types: 57ffeaf689SAlexander Kabaev typedef _Key key_type; 58ffeaf689SAlexander Kabaev typedef _Key value_type; 59ffeaf689SAlexander Kabaev typedef _Compare key_compare; 60ffeaf689SAlexander Kabaev typedef _Compare value_compare; 61ffeaf689SAlexander Kabaev typedef _Allocator allocator_type; 62*f8a1b7d9SAlexander Kabaev typedef typename _Base::reference reference; 63*f8a1b7d9SAlexander Kabaev typedef typename _Base::const_reference const_reference; 64ffeaf689SAlexander Kabaev 65ffeaf689SAlexander Kabaev typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multiset> 66ffeaf689SAlexander Kabaev iterator; 67ffeaf689SAlexander Kabaev typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, 68ffeaf689SAlexander Kabaev multiset> const_iterator; 69ffeaf689SAlexander Kabaev 70ffeaf689SAlexander Kabaev typedef typename _Base::size_type size_type; 71ffeaf689SAlexander Kabaev typedef typename _Base::difference_type difference_type; 72*f8a1b7d9SAlexander Kabaev typedef typename _Base::pointer pointer; 73*f8a1b7d9SAlexander Kabaev typedef typename _Base::const_pointer const_pointer; 74ffeaf689SAlexander Kabaev typedef std::reverse_iterator<iterator> reverse_iterator; 75ffeaf689SAlexander Kabaev typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 76ffeaf689SAlexander Kabaev 77ffeaf689SAlexander Kabaev // 23.3.3.1 construct/copy/destroy: 78ffeaf689SAlexander Kabaev explicit multiset(const _Compare& __comp = _Compare(), 79ffeaf689SAlexander Kabaev const _Allocator& __a = _Allocator()) _Base(__comp,__a)80ffeaf689SAlexander Kabaev : _Base(__comp, __a) { } 81ffeaf689SAlexander Kabaev 82ffeaf689SAlexander Kabaev template<typename _InputIterator> 83ffeaf689SAlexander Kabaev multiset(_InputIterator __first, _InputIterator __last, 84ffeaf689SAlexander Kabaev const _Compare& __comp = _Compare(), 85ffeaf689SAlexander Kabaev const _Allocator& __a = _Allocator()) _Base(__gnu_debug::__check_valid_range (__first,__last),__last,__comp,__a)86ffeaf689SAlexander Kabaev : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, 87ffeaf689SAlexander Kabaev __comp, __a) { } 88ffeaf689SAlexander Kabaev multiset(const multiset<_Key,_Compare,_Allocator> & __x)89ffeaf689SAlexander Kabaev multiset(const multiset<_Key,_Compare,_Allocator>& __x) 90ffeaf689SAlexander Kabaev : _Base(__x), _Safe_base() { } 91ffeaf689SAlexander Kabaev multiset(const _Base & __x)92ffeaf689SAlexander Kabaev multiset(const _Base& __x) : _Base(__x), _Safe_base() { } 93ffeaf689SAlexander Kabaev ~multiset()94ffeaf689SAlexander Kabaev ~multiset() { } 95ffeaf689SAlexander Kabaev 96ffeaf689SAlexander Kabaev multiset<_Key,_Compare,_Allocator>& 97ffeaf689SAlexander Kabaev operator=(const multiset<_Key,_Compare,_Allocator>& __x) 98ffeaf689SAlexander Kabaev { 99ffeaf689SAlexander Kabaev *static_cast<_Base*>(this) = __x; 100ffeaf689SAlexander Kabaev this->_M_invalidate_all(); 101ffeaf689SAlexander Kabaev return *this; 102ffeaf689SAlexander Kabaev } 103ffeaf689SAlexander Kabaev 104ffeaf689SAlexander Kabaev using _Base::get_allocator; 105ffeaf689SAlexander Kabaev 106ffeaf689SAlexander Kabaev // iterators: 107ffeaf689SAlexander Kabaev iterator begin()108ffeaf689SAlexander Kabaev begin() 109ffeaf689SAlexander Kabaev { return iterator(_Base::begin(), this); } 110ffeaf689SAlexander Kabaev 111ffeaf689SAlexander Kabaev const_iterator begin()112ffeaf689SAlexander Kabaev begin() const 113ffeaf689SAlexander Kabaev { return const_iterator(_Base::begin(), this); } 114ffeaf689SAlexander Kabaev 115ffeaf689SAlexander Kabaev iterator end()116ffeaf689SAlexander Kabaev end() 117ffeaf689SAlexander Kabaev { return iterator(_Base::end(), this); } 118ffeaf689SAlexander Kabaev 119ffeaf689SAlexander Kabaev const_iterator end()120ffeaf689SAlexander Kabaev end() const 121ffeaf689SAlexander Kabaev { return const_iterator(_Base::end(), this); } 122ffeaf689SAlexander Kabaev 123ffeaf689SAlexander Kabaev reverse_iterator rbegin()124ffeaf689SAlexander Kabaev rbegin() 125ffeaf689SAlexander Kabaev { return reverse_iterator(end()); } 126ffeaf689SAlexander Kabaev 127ffeaf689SAlexander Kabaev const_reverse_iterator rbegin()128ffeaf689SAlexander Kabaev rbegin() const 129ffeaf689SAlexander Kabaev { return const_reverse_iterator(end()); } 130ffeaf689SAlexander Kabaev 131ffeaf689SAlexander Kabaev reverse_iterator rend()132ffeaf689SAlexander Kabaev rend() 133ffeaf689SAlexander Kabaev { return reverse_iterator(begin()); } 134ffeaf689SAlexander Kabaev 135ffeaf689SAlexander Kabaev const_reverse_iterator rend()136ffeaf689SAlexander Kabaev rend() const 137ffeaf689SAlexander Kabaev { return const_reverse_iterator(begin()); } 138ffeaf689SAlexander Kabaev 139ffeaf689SAlexander Kabaev // capacity: 140ffeaf689SAlexander Kabaev using _Base::empty; 141ffeaf689SAlexander Kabaev using _Base::size; 142ffeaf689SAlexander Kabaev using _Base::max_size; 143ffeaf689SAlexander Kabaev 144ffeaf689SAlexander Kabaev // modifiers: 145ffeaf689SAlexander Kabaev iterator insert(const value_type & __x)146ffeaf689SAlexander Kabaev insert(const value_type& __x) 147ffeaf689SAlexander Kabaev { return iterator(_Base::insert(__x), this); } 148ffeaf689SAlexander Kabaev 149ffeaf689SAlexander Kabaev iterator insert(iterator __position,const value_type & __x)150ffeaf689SAlexander Kabaev insert(iterator __position, const value_type& __x) 151ffeaf689SAlexander Kabaev { 152ffeaf689SAlexander Kabaev __glibcxx_check_insert(__position); 153ffeaf689SAlexander Kabaev return iterator(_Base::insert(__position.base(), __x), this); 154ffeaf689SAlexander Kabaev } 155ffeaf689SAlexander Kabaev 156ffeaf689SAlexander Kabaev template<typename _InputIterator> 157ffeaf689SAlexander Kabaev void insert(_InputIterator __first,_InputIterator __last)158ffeaf689SAlexander Kabaev insert(_InputIterator __first, _InputIterator __last) 159ffeaf689SAlexander Kabaev { 160ffeaf689SAlexander Kabaev __glibcxx_check_valid_range(__first, __last); 161ffeaf689SAlexander Kabaev _Base::insert(__first, __last); 162ffeaf689SAlexander Kabaev } 163ffeaf689SAlexander Kabaev 164ffeaf689SAlexander Kabaev void erase(iterator __position)165ffeaf689SAlexander Kabaev erase(iterator __position) 166ffeaf689SAlexander Kabaev { 167ffeaf689SAlexander Kabaev __glibcxx_check_erase(__position); 168ffeaf689SAlexander Kabaev __position._M_invalidate(); 169ffeaf689SAlexander Kabaev _Base::erase(__position.base()); 170ffeaf689SAlexander Kabaev } 171ffeaf689SAlexander Kabaev 172ffeaf689SAlexander Kabaev size_type erase(const key_type & __x)173ffeaf689SAlexander Kabaev erase(const key_type& __x) 174ffeaf689SAlexander Kabaev { 175ffeaf689SAlexander Kabaev std::pair<iterator, iterator> __victims = this->equal_range(__x); 176ffeaf689SAlexander Kabaev size_type __count = 0; 177ffeaf689SAlexander Kabaev while (__victims.first != __victims.second) 178ffeaf689SAlexander Kabaev { 179ffeaf689SAlexander Kabaev iterator __victim = __victims.first++; 180ffeaf689SAlexander Kabaev __victim._M_invalidate(); 181ffeaf689SAlexander Kabaev _Base::erase(__victim.base()); 182ffeaf689SAlexander Kabaev ++__count; 183ffeaf689SAlexander Kabaev } 184ffeaf689SAlexander Kabaev return __count; 185ffeaf689SAlexander Kabaev } 186ffeaf689SAlexander Kabaev 187ffeaf689SAlexander Kabaev void erase(iterator __first,iterator __last)188ffeaf689SAlexander Kabaev erase(iterator __first, iterator __last) 189ffeaf689SAlexander Kabaev { 190ffeaf689SAlexander Kabaev // _GLIBCXX_RESOLVE_LIB_DEFECTS 191ffeaf689SAlexander Kabaev // 151. can't currently clear() empty container 192ffeaf689SAlexander Kabaev __glibcxx_check_erase_range(__first, __last); 193ffeaf689SAlexander Kabaev while (__first != __last) 194ffeaf689SAlexander Kabaev this->erase(__first++); 195ffeaf689SAlexander Kabaev } 196ffeaf689SAlexander Kabaev 197ffeaf689SAlexander Kabaev void swap(multiset<_Key,_Compare,_Allocator> & __x)198ffeaf689SAlexander Kabaev swap(multiset<_Key,_Compare,_Allocator>& __x) 199ffeaf689SAlexander Kabaev { 200ffeaf689SAlexander Kabaev _Base::swap(__x); 201ffeaf689SAlexander Kabaev this->_M_swap(__x); 202ffeaf689SAlexander Kabaev } 203ffeaf689SAlexander Kabaev 204ffeaf689SAlexander Kabaev void clear()205ffeaf689SAlexander Kabaev clear() 206ffeaf689SAlexander Kabaev { this->erase(begin(), end()); } 207ffeaf689SAlexander Kabaev 208ffeaf689SAlexander Kabaev // observers: 209ffeaf689SAlexander Kabaev using _Base::key_comp; 210ffeaf689SAlexander Kabaev using _Base::value_comp; 211ffeaf689SAlexander Kabaev 212ffeaf689SAlexander Kabaev // multiset operations: 213ffeaf689SAlexander Kabaev iterator find(const key_type & __x)214ffeaf689SAlexander Kabaev find(const key_type& __x) 215ffeaf689SAlexander Kabaev { return iterator(_Base::find(__x), this); } 216ffeaf689SAlexander Kabaev 217ffeaf689SAlexander Kabaev // _GLIBCXX_RESOLVE_LIB_DEFECTS 218ffeaf689SAlexander Kabaev // 214. set::find() missing const overload 219ffeaf689SAlexander Kabaev const_iterator find(const key_type & __x)220ffeaf689SAlexander Kabaev find(const key_type& __x) const 221ffeaf689SAlexander Kabaev { return const_iterator(_Base::find(__x), this); } 222ffeaf689SAlexander Kabaev 223ffeaf689SAlexander Kabaev using _Base::count; 224ffeaf689SAlexander Kabaev 225ffeaf689SAlexander Kabaev iterator lower_bound(const key_type & __x)226ffeaf689SAlexander Kabaev lower_bound(const key_type& __x) 227ffeaf689SAlexander Kabaev { return iterator(_Base::lower_bound(__x), this); } 228ffeaf689SAlexander Kabaev 229ffeaf689SAlexander Kabaev // _GLIBCXX_RESOLVE_LIB_DEFECTS 230ffeaf689SAlexander Kabaev // 214. set::find() missing const overload 231ffeaf689SAlexander Kabaev const_iterator lower_bound(const key_type & __x)232ffeaf689SAlexander Kabaev lower_bound(const key_type& __x) const 233ffeaf689SAlexander Kabaev { return const_iterator(_Base::lower_bound(__x), this); } 234ffeaf689SAlexander Kabaev 235ffeaf689SAlexander Kabaev iterator upper_bound(const key_type & __x)236ffeaf689SAlexander Kabaev upper_bound(const key_type& __x) 237ffeaf689SAlexander Kabaev { return iterator(_Base::upper_bound(__x), this); } 238ffeaf689SAlexander Kabaev 239ffeaf689SAlexander Kabaev // _GLIBCXX_RESOLVE_LIB_DEFECTS 240ffeaf689SAlexander Kabaev // 214. set::find() missing const overload 241ffeaf689SAlexander Kabaev const_iterator upper_bound(const key_type & __x)242ffeaf689SAlexander Kabaev upper_bound(const key_type& __x) const 243ffeaf689SAlexander Kabaev { return const_iterator(_Base::upper_bound(__x), this); } 244ffeaf689SAlexander Kabaev 245ffeaf689SAlexander Kabaev std::pair<iterator,iterator> equal_range(const key_type & __x)246ffeaf689SAlexander Kabaev equal_range(const key_type& __x) 247ffeaf689SAlexander Kabaev { 248ffeaf689SAlexander Kabaev typedef typename _Base::iterator _Base_iterator; 249ffeaf689SAlexander Kabaev std::pair<_Base_iterator, _Base_iterator> __res = 250ffeaf689SAlexander Kabaev _Base::equal_range(__x); 251ffeaf689SAlexander Kabaev return std::make_pair(iterator(__res.first, this), 252ffeaf689SAlexander Kabaev iterator(__res.second, this)); 253ffeaf689SAlexander Kabaev } 254ffeaf689SAlexander Kabaev 255ffeaf689SAlexander Kabaev // _GLIBCXX_RESOLVE_LIB_DEFECTS 256ffeaf689SAlexander Kabaev // 214. set::find() missing const overload 257ffeaf689SAlexander Kabaev std::pair<const_iterator,const_iterator> equal_range(const key_type & __x)258ffeaf689SAlexander Kabaev equal_range(const key_type& __x) const 259ffeaf689SAlexander Kabaev { 260ffeaf689SAlexander Kabaev typedef typename _Base::const_iterator _Base_iterator; 261ffeaf689SAlexander Kabaev std::pair<_Base_iterator, _Base_iterator> __res = 262ffeaf689SAlexander Kabaev _Base::equal_range(__x); 263ffeaf689SAlexander Kabaev return std::make_pair(const_iterator(__res.first, this), 264ffeaf689SAlexander Kabaev const_iterator(__res.second, this)); 265ffeaf689SAlexander Kabaev } 266ffeaf689SAlexander Kabaev 267ffeaf689SAlexander Kabaev _Base& _M_base()268ffeaf689SAlexander Kabaev _M_base() { return *this; } 269ffeaf689SAlexander Kabaev 270ffeaf689SAlexander Kabaev const _Base& _M_base()271ffeaf689SAlexander Kabaev _M_base() const { return *this; } 272ffeaf689SAlexander Kabaev 273ffeaf689SAlexander Kabaev private: 274ffeaf689SAlexander Kabaev void _M_invalidate_all()275ffeaf689SAlexander Kabaev _M_invalidate_all() 276ffeaf689SAlexander Kabaev { 277ffeaf689SAlexander Kabaev typedef typename _Base::const_iterator _Base_const_iterator; 278ffeaf689SAlexander Kabaev typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; 279ffeaf689SAlexander Kabaev this->_M_invalidate_if(_Not_equal(_M_base().end())); 280ffeaf689SAlexander Kabaev } 281ffeaf689SAlexander Kabaev }; 282ffeaf689SAlexander Kabaev 283ffeaf689SAlexander Kabaev template<typename _Key, typename _Compare, typename _Allocator> 284ffeaf689SAlexander Kabaev inline bool 285ffeaf689SAlexander Kabaev operator==(const multiset<_Key,_Compare,_Allocator>& __lhs, 286ffeaf689SAlexander Kabaev const multiset<_Key,_Compare,_Allocator>& __rhs) 287ffeaf689SAlexander Kabaev { return __lhs._M_base() == __rhs._M_base(); } 288ffeaf689SAlexander Kabaev 289ffeaf689SAlexander Kabaev template<typename _Key, typename _Compare, typename _Allocator> 290ffeaf689SAlexander Kabaev inline bool 291ffeaf689SAlexander Kabaev operator!=(const multiset<_Key,_Compare,_Allocator>& __lhs, 292ffeaf689SAlexander Kabaev const multiset<_Key,_Compare,_Allocator>& __rhs) 293ffeaf689SAlexander Kabaev { return __lhs._M_base() != __rhs._M_base(); } 294ffeaf689SAlexander Kabaev 295ffeaf689SAlexander Kabaev template<typename _Key, typename _Compare, typename _Allocator> 296ffeaf689SAlexander Kabaev inline bool 297ffeaf689SAlexander Kabaev operator<(const multiset<_Key,_Compare,_Allocator>& __lhs, 298ffeaf689SAlexander Kabaev const multiset<_Key,_Compare,_Allocator>& __rhs) 299ffeaf689SAlexander Kabaev { return __lhs._M_base() < __rhs._M_base(); } 300ffeaf689SAlexander Kabaev 301ffeaf689SAlexander Kabaev template<typename _Key, typename _Compare, typename _Allocator> 302ffeaf689SAlexander Kabaev inline bool 303ffeaf689SAlexander Kabaev operator<=(const multiset<_Key,_Compare,_Allocator>& __lhs, 304ffeaf689SAlexander Kabaev const multiset<_Key,_Compare,_Allocator>& __rhs) 305ffeaf689SAlexander Kabaev { return __lhs._M_base() <= __rhs._M_base(); } 306ffeaf689SAlexander Kabaev 307ffeaf689SAlexander Kabaev template<typename _Key, typename _Compare, typename _Allocator> 308ffeaf689SAlexander Kabaev inline bool 309ffeaf689SAlexander Kabaev operator>=(const multiset<_Key,_Compare,_Allocator>& __lhs, 310ffeaf689SAlexander Kabaev const multiset<_Key,_Compare,_Allocator>& __rhs) 311ffeaf689SAlexander Kabaev { return __lhs._M_base() >= __rhs._M_base(); } 312ffeaf689SAlexander Kabaev 313ffeaf689SAlexander Kabaev template<typename _Key, typename _Compare, typename _Allocator> 314ffeaf689SAlexander Kabaev inline bool 315ffeaf689SAlexander Kabaev operator>(const multiset<_Key,_Compare,_Allocator>& __lhs, 316ffeaf689SAlexander Kabaev const multiset<_Key,_Compare,_Allocator>& __rhs) 317ffeaf689SAlexander Kabaev { return __lhs._M_base() > __rhs._M_base(); } 318ffeaf689SAlexander Kabaev 319ffeaf689SAlexander Kabaev template<typename _Key, typename _Compare, typename _Allocator> 320ffeaf689SAlexander Kabaev void swap(multiset<_Key,_Compare,_Allocator> & __x,multiset<_Key,_Compare,_Allocator> & __y)321ffeaf689SAlexander Kabaev swap(multiset<_Key,_Compare,_Allocator>& __x, 322ffeaf689SAlexander Kabaev multiset<_Key,_Compare,_Allocator>& __y) 323ffeaf689SAlexander Kabaev { return __x.swap(__y); } 324*f8a1b7d9SAlexander Kabaev } // namespace __debug 325*f8a1b7d9SAlexander Kabaev } // namespace std 326ffeaf689SAlexander Kabaev 327ffeaf689SAlexander Kabaev #endif 328