1ffeaf689SAlexander Kabaev // Debugging hash_multimap implementation -*- C++ -*- 2ffeaf689SAlexander Kabaev 3*f8a1b7d9SAlexander Kabaev // Copyright (C) 2003, 2005, 2006 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/hash_multimap.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_HASH_MULTIMAP_H 36ffeaf689SAlexander Kabaev #define _GLIBCXX_DEBUG_HASH_MULTIMAP_H 1 37ffeaf689SAlexander Kabaev 38ffeaf689SAlexander Kabaev #include <debug/safe_sequence.h> 39ffeaf689SAlexander Kabaev #include <debug/safe_iterator.h> 40ffeaf689SAlexander Kabaev 41*f8a1b7d9SAlexander Kabaev namespace __gnu_cxx 42*f8a1b7d9SAlexander Kabaev { 43*f8a1b7d9SAlexander Kabaev namespace __debug 44ffeaf689SAlexander Kabaev { 45ffeaf689SAlexander Kabaev template<typename _Value, typename _Tp, 46ffeaf689SAlexander Kabaev typename _HashFcn = __gnu_cxx::hash<_Value>, 47ffeaf689SAlexander Kabaev typename _EqualKey = std::equal_to<_Value>, 48ffeaf689SAlexander Kabaev typename _Alloc = std::allocator<_Value> > 49ffeaf689SAlexander Kabaev class hash_multimap 50*f8a1b7d9SAlexander Kabaev : public _GLIBCXX_EXT::hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>, 51ffeaf689SAlexander Kabaev public __gnu_debug::_Safe_sequence<hash_multimap<_Value, _Tp, _HashFcn, 52ffeaf689SAlexander Kabaev _EqualKey, _Alloc> > 53ffeaf689SAlexander Kabaev { 54*f8a1b7d9SAlexander Kabaev typedef _GLIBCXX_EXT::hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc> 55ffeaf689SAlexander Kabaev _Base; 56ffeaf689SAlexander Kabaev typedef __gnu_debug::_Safe_sequence<hash_multimap> _Safe_base; 57ffeaf689SAlexander Kabaev 58ffeaf689SAlexander Kabaev public: 59ffeaf689SAlexander Kabaev typedef typename _Base::key_type key_type; 60ffeaf689SAlexander Kabaev typedef typename _Base::data_type data_type; 61ffeaf689SAlexander Kabaev typedef typename _Base::mapped_type mapped_type; 62ffeaf689SAlexander Kabaev typedef typename _Base::value_type value_type; 63ffeaf689SAlexander Kabaev typedef typename _Base::hasher hasher; 64ffeaf689SAlexander Kabaev typedef typename _Base::key_equal key_equal; 65ffeaf689SAlexander Kabaev typedef typename _Base::size_type size_type; 66ffeaf689SAlexander Kabaev typedef typename _Base::difference_type difference_type; 67ffeaf689SAlexander Kabaev typedef typename _Base::pointer pointer; 68ffeaf689SAlexander Kabaev typedef typename _Base::const_pointer const_pointer; 69ffeaf689SAlexander Kabaev typedef typename _Base::reference reference; 70ffeaf689SAlexander Kabaev typedef typename _Base::const_reference const_reference; 71ffeaf689SAlexander Kabaev 72ffeaf689SAlexander Kabaev typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, 73ffeaf689SAlexander Kabaev hash_multimap> iterator; 74ffeaf689SAlexander Kabaev typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, 75ffeaf689SAlexander Kabaev hash_multimap> const_iterator; 76ffeaf689SAlexander Kabaev 77ffeaf689SAlexander Kabaev typedef typename _Base::allocator_type allocator_type; 78ffeaf689SAlexander Kabaev 79ffeaf689SAlexander Kabaev using _Base::hash_funct; 80ffeaf689SAlexander Kabaev using _Base::key_eq; 81ffeaf689SAlexander Kabaev using _Base::get_allocator; 82ffeaf689SAlexander Kabaev hash_multimap()83ffeaf689SAlexander Kabaev hash_multimap() { } 84ffeaf689SAlexander Kabaev hash_multimap(size_type __n)85ffeaf689SAlexander Kabaev explicit hash_multimap(size_type __n) : _Base(__n) { } 86ffeaf689SAlexander Kabaev hash_multimap(size_type __n,const hasher & __hf)87ffeaf689SAlexander Kabaev hash_multimap(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } 88ffeaf689SAlexander Kabaev 89ffeaf689SAlexander Kabaev hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, 90ffeaf689SAlexander Kabaev const allocator_type& __a = allocator_type()) _Base(__n,__hf,__eql,__a)91ffeaf689SAlexander Kabaev : _Base(__n, __hf, __eql, __a) { } 92ffeaf689SAlexander Kabaev 93ffeaf689SAlexander Kabaev template<typename _InputIterator> hash_multimap(_InputIterator __f,_InputIterator __l)94ffeaf689SAlexander Kabaev hash_multimap(_InputIterator __f, _InputIterator __l) 95ffeaf689SAlexander Kabaev : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } 96ffeaf689SAlexander Kabaev 97ffeaf689SAlexander Kabaev template<typename _InputIterator> hash_multimap(_InputIterator __f,_InputIterator __l,size_type __n)98ffeaf689SAlexander Kabaev hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) 99ffeaf689SAlexander Kabaev : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } 100ffeaf689SAlexander Kabaev 101ffeaf689SAlexander Kabaev template<typename _InputIterator> hash_multimap(_InputIterator __f,_InputIterator __l,size_type __n,const hasher & __hf)102ffeaf689SAlexander Kabaev hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, 103ffeaf689SAlexander Kabaev const hasher& __hf) 104ffeaf689SAlexander Kabaev : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } 105ffeaf689SAlexander Kabaev 106ffeaf689SAlexander Kabaev template<typename _InputIterator> 107ffeaf689SAlexander Kabaev hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, 108ffeaf689SAlexander Kabaev const hasher& __hf, const key_equal& __eql, 109ffeaf689SAlexander Kabaev const allocator_type& __a = allocator_type()) _Base(__gnu_debug::__check_valid_range (__f,__l),__l,__n,__hf,__eql,__a)110ffeaf689SAlexander Kabaev : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, 111ffeaf689SAlexander Kabaev __eql, __a) { } 112ffeaf689SAlexander Kabaev 113ffeaf689SAlexander Kabaev using _Base::size; 114ffeaf689SAlexander Kabaev using _Base::max_size; 115ffeaf689SAlexander Kabaev using _Base::empty; 116ffeaf689SAlexander Kabaev 117ffeaf689SAlexander Kabaev void swap(hash_multimap & __x)118ffeaf689SAlexander Kabaev swap(hash_multimap& __x) 119ffeaf689SAlexander Kabaev { 120ffeaf689SAlexander Kabaev _Base::swap(__x); 121ffeaf689SAlexander Kabaev this->_M_swap(__x); 122ffeaf689SAlexander Kabaev } 123ffeaf689SAlexander Kabaev 124ffeaf689SAlexander Kabaev iterator begin()125ffeaf689SAlexander Kabaev begin() { return iterator(_Base::begin(), this); } 126ffeaf689SAlexander Kabaev 127ffeaf689SAlexander Kabaev iterator end()128ffeaf689SAlexander Kabaev end() { return iterator(_Base::end(), this); } 129ffeaf689SAlexander Kabaev 130ffeaf689SAlexander Kabaev const_iterator begin()131ffeaf689SAlexander Kabaev begin() const 132ffeaf689SAlexander Kabaev { return const_iterator(_Base::begin(), this); } 133ffeaf689SAlexander Kabaev 134ffeaf689SAlexander Kabaev const_iterator end()135ffeaf689SAlexander Kabaev end() const 136ffeaf689SAlexander Kabaev { return const_iterator(_Base::end(), this); } 137ffeaf689SAlexander Kabaev 138ffeaf689SAlexander Kabaev iterator insert(const value_type & __obj)139ffeaf689SAlexander Kabaev insert(const value_type& __obj) 140ffeaf689SAlexander Kabaev { return iterator(_Base::insert(__obj), this); } 141ffeaf689SAlexander Kabaev 142ffeaf689SAlexander Kabaev template <typename _InputIterator> 143ffeaf689SAlexander Kabaev void insert(_InputIterator __first,_InputIterator __last)144ffeaf689SAlexander Kabaev insert(_InputIterator __first, _InputIterator __last) 145ffeaf689SAlexander Kabaev { 146ffeaf689SAlexander Kabaev __glibcxx_check_valid_range(__first, __last); 147ffeaf689SAlexander Kabaev _Base::insert(__first.base(), __last.base()); 148ffeaf689SAlexander Kabaev } 149ffeaf689SAlexander Kabaev 150ffeaf689SAlexander Kabaev iterator insert_noresize(const value_type & __obj)151ffeaf689SAlexander Kabaev insert_noresize(const value_type& __obj) 152ffeaf689SAlexander Kabaev { return iterator(_Base::insert_noresize(__obj), this); } 153ffeaf689SAlexander Kabaev 154ffeaf689SAlexander Kabaev iterator find(const key_type & __key)155ffeaf689SAlexander Kabaev find(const key_type& __key) 156ffeaf689SAlexander Kabaev { return iterator(_Base::find(__key), this); } 157ffeaf689SAlexander Kabaev 158ffeaf689SAlexander Kabaev const_iterator find(const key_type & __key)159ffeaf689SAlexander Kabaev find(const key_type& __key) const 160ffeaf689SAlexander Kabaev { return const_iterator(_Base::find(__key), this); } 161ffeaf689SAlexander Kabaev 162ffeaf689SAlexander Kabaev using _Base::count; 163ffeaf689SAlexander Kabaev 164ffeaf689SAlexander Kabaev std::pair<iterator, iterator> equal_range(const key_type & __key)165ffeaf689SAlexander Kabaev equal_range(const key_type& __key) 166ffeaf689SAlexander Kabaev { 167ffeaf689SAlexander Kabaev typedef typename _Base::iterator _Base_iterator; 168ffeaf689SAlexander Kabaev std::pair<_Base_iterator, _Base_iterator> __res = 169ffeaf689SAlexander Kabaev _Base::equal_range(__key); 170ffeaf689SAlexander Kabaev return std::make_pair(iterator(__res.first, this), 171ffeaf689SAlexander Kabaev iterator(__res.second, this)); 172ffeaf689SAlexander Kabaev } 173ffeaf689SAlexander Kabaev 174ffeaf689SAlexander Kabaev std::pair<const_iterator, const_iterator> equal_range(const key_type & __key)175ffeaf689SAlexander Kabaev equal_range(const key_type& __key) const 176ffeaf689SAlexander Kabaev { 177ffeaf689SAlexander Kabaev typedef typename _Base::const_iterator _Base_iterator; 178ffeaf689SAlexander Kabaev std::pair<_Base_iterator, _Base_iterator> __res = 179ffeaf689SAlexander Kabaev _Base::equal_range(__key); 180ffeaf689SAlexander Kabaev return std::make_pair(const_iterator(__res.first, this), 181ffeaf689SAlexander Kabaev const_iterator(__res.second, this)); 182ffeaf689SAlexander Kabaev } 183ffeaf689SAlexander Kabaev 184ffeaf689SAlexander Kabaev size_type erase(const key_type & __key)185ffeaf689SAlexander Kabaev erase(const key_type& __key) 186ffeaf689SAlexander Kabaev { 187ffeaf689SAlexander Kabaev std::pair<iterator, iterator> __victims = this->equal_range(__key); 188*f8a1b7d9SAlexander Kabaev std::size_t __num_victims = 0; 189ffeaf689SAlexander Kabaev while (__victims.first != __victims.second) 190ffeaf689SAlexander Kabaev { 191ffeaf689SAlexander Kabaev this->erase(__victims.first++); 192ffeaf689SAlexander Kabaev ++__num_victims; 193ffeaf689SAlexander Kabaev } 194ffeaf689SAlexander Kabaev return __num_victims; 195ffeaf689SAlexander Kabaev } 196ffeaf689SAlexander Kabaev 197ffeaf689SAlexander Kabaev void erase(iterator __it)198ffeaf689SAlexander Kabaev erase(iterator __it) 199ffeaf689SAlexander Kabaev { 200ffeaf689SAlexander Kabaev __glibcxx_check_erase(__it); 201ffeaf689SAlexander Kabaev __it._M_invalidate(); 202ffeaf689SAlexander Kabaev _Base::erase(__it.base()); 203ffeaf689SAlexander Kabaev } 204ffeaf689SAlexander Kabaev 205ffeaf689SAlexander Kabaev void erase(iterator __first,iterator __last)206ffeaf689SAlexander Kabaev erase(iterator __first, iterator __last) 207ffeaf689SAlexander Kabaev { 208ffeaf689SAlexander Kabaev __glibcxx_check_erase_range(__first, __last); 209ffeaf689SAlexander Kabaev for (iterator __tmp = __first; __tmp != __last;) 210ffeaf689SAlexander Kabaev { 211ffeaf689SAlexander Kabaev iterator __victim = __tmp++; 212ffeaf689SAlexander Kabaev __victim._M_invalidate(); 213ffeaf689SAlexander Kabaev } 214ffeaf689SAlexander Kabaev _Base::erase(__first.base(), __last.base()); 215ffeaf689SAlexander Kabaev } 216ffeaf689SAlexander Kabaev 217ffeaf689SAlexander Kabaev void clear()218ffeaf689SAlexander Kabaev clear() 219ffeaf689SAlexander Kabaev { 220ffeaf689SAlexander Kabaev _Base::clear(); 221ffeaf689SAlexander Kabaev this->_M_invalidate_all(); 222ffeaf689SAlexander Kabaev } 223ffeaf689SAlexander Kabaev 224ffeaf689SAlexander Kabaev using _Base::resize; 225ffeaf689SAlexander Kabaev using _Base::bucket_count; 226ffeaf689SAlexander Kabaev using _Base::max_bucket_count; 227ffeaf689SAlexander Kabaev using _Base::elems_in_bucket; 228ffeaf689SAlexander Kabaev 229ffeaf689SAlexander Kabaev _Base& _M_base()230ffeaf689SAlexander Kabaev _M_base() { return *this; } 231ffeaf689SAlexander Kabaev 232ffeaf689SAlexander Kabaev const _Base& _M_base()233ffeaf689SAlexander Kabaev _M_base() const { return *this; } 234ffeaf689SAlexander Kabaev 235ffeaf689SAlexander Kabaev private: 236ffeaf689SAlexander Kabaev void _M_invalidate_all()237ffeaf689SAlexander Kabaev _M_invalidate_all() 238ffeaf689SAlexander Kabaev { 239ffeaf689SAlexander Kabaev typedef typename _Base::const_iterator _Base_const_iterator; 240ffeaf689SAlexander Kabaev typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; 241ffeaf689SAlexander Kabaev this->_M_invalidate_if(_Not_equal(_M_base().end())); 242ffeaf689SAlexander Kabaev } 243ffeaf689SAlexander Kabaev }; 244ffeaf689SAlexander Kabaev 245ffeaf689SAlexander Kabaev template<typename _Value, typename _Tp, typename _HashFcn, 246ffeaf689SAlexander Kabaev typename _EqualKey, typename _Alloc> 247ffeaf689SAlexander Kabaev inline bool 248ffeaf689SAlexander Kabaev operator==(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, 249ffeaf689SAlexander Kabaev const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) 250ffeaf689SAlexander Kabaev { return __x._M_base() == __y._M_base(); } 251ffeaf689SAlexander Kabaev 252ffeaf689SAlexander Kabaev template<typename _Value, typename _Tp, typename _HashFcn, 253ffeaf689SAlexander Kabaev typename _EqualKey, typename _Alloc> 254ffeaf689SAlexander Kabaev inline bool 255ffeaf689SAlexander Kabaev operator!=(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, 256ffeaf689SAlexander Kabaev const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) 257ffeaf689SAlexander Kabaev { return __x._M_base() != __y._M_base(); } 258ffeaf689SAlexander Kabaev 259ffeaf689SAlexander Kabaev template<typename _Value, typename _Tp, typename _HashFcn, 260ffeaf689SAlexander Kabaev typename _EqualKey, typename _Alloc> 261ffeaf689SAlexander Kabaev inline void swap(hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc> & __x,hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc> & __y)262ffeaf689SAlexander Kabaev swap(hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, 263ffeaf689SAlexander Kabaev hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) 264ffeaf689SAlexander Kabaev { __x.swap(__y); } 265*f8a1b7d9SAlexander Kabaev } // namespace __debug 266*f8a1b7d9SAlexander Kabaev } // namespace __gnu_cxx 267ffeaf689SAlexander Kabaev 268ffeaf689SAlexander Kabaev #endif 269