1ffeaf689SAlexander Kabaev // Debugging hash_map 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_map.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_MAP_H 36ffeaf689SAlexander Kabaev #define _GLIBCXX_DEBUG_HASH_MAP_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_map 50*f8a1b7d9SAlexander Kabaev : public _GLIBCXX_EXT::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>, 51ffeaf689SAlexander Kabaev public __gnu_debug::_Safe_sequence<hash_map<_Value, _Tp, _HashFcn, 52ffeaf689SAlexander Kabaev _EqualKey, _Alloc> > 53ffeaf689SAlexander Kabaev { 54*f8a1b7d9SAlexander Kabaev typedef _GLIBCXX_EXT::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc> 55ffeaf689SAlexander Kabaev _Base; 56ffeaf689SAlexander Kabaev typedef __gnu_debug::_Safe_sequence<hash_map> _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, hash_map> 73ffeaf689SAlexander Kabaev iterator; 74ffeaf689SAlexander Kabaev typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, 75ffeaf689SAlexander Kabaev hash_map> 76ffeaf689SAlexander Kabaev const_iterator; 77ffeaf689SAlexander Kabaev 78ffeaf689SAlexander Kabaev typedef typename _Base::allocator_type allocator_type; 79ffeaf689SAlexander Kabaev 80ffeaf689SAlexander Kabaev using _Base::hash_funct; 81ffeaf689SAlexander Kabaev using _Base::key_eq; 82ffeaf689SAlexander Kabaev using _Base::get_allocator; 83ffeaf689SAlexander Kabaev hash_map()84ffeaf689SAlexander Kabaev hash_map() { } 85ffeaf689SAlexander Kabaev hash_map(size_type __n)86ffeaf689SAlexander Kabaev explicit hash_map(size_type __n) : _Base(__n) { } 87ffeaf689SAlexander Kabaev hash_map(size_type __n,const hasher & __hf)88ffeaf689SAlexander Kabaev hash_map(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } 89ffeaf689SAlexander Kabaev 90ffeaf689SAlexander Kabaev hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, 91ffeaf689SAlexander Kabaev const allocator_type& __a = allocator_type()) _Base(__n,__hf,__eql,__a)92ffeaf689SAlexander Kabaev : _Base(__n, __hf, __eql, __a) { } 93ffeaf689SAlexander Kabaev 94ffeaf689SAlexander Kabaev template<typename _InputIterator> hash_map(_InputIterator __f,_InputIterator __l)95ffeaf689SAlexander Kabaev hash_map(_InputIterator __f, _InputIterator __l) 96ffeaf689SAlexander Kabaev : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } 97ffeaf689SAlexander Kabaev 98ffeaf689SAlexander Kabaev template<typename _InputIterator> hash_map(_InputIterator __f,_InputIterator __l,size_type __n)99ffeaf689SAlexander Kabaev hash_map(_InputIterator __f, _InputIterator __l, size_type __n) 100ffeaf689SAlexander Kabaev : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } 101ffeaf689SAlexander Kabaev 102ffeaf689SAlexander Kabaev template<typename _InputIterator> hash_map(_InputIterator __f,_InputIterator __l,size_type __n,const hasher & __hf)103ffeaf689SAlexander Kabaev hash_map(_InputIterator __f, _InputIterator __l, size_type __n, 104ffeaf689SAlexander Kabaev const hasher& __hf) 105ffeaf689SAlexander Kabaev : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } 106ffeaf689SAlexander Kabaev 107ffeaf689SAlexander Kabaev template<typename _InputIterator> 108ffeaf689SAlexander Kabaev hash_map(_InputIterator __f, _InputIterator __l, size_type __n, 109ffeaf689SAlexander Kabaev const hasher& __hf, const key_equal& __eql, 110ffeaf689SAlexander Kabaev const allocator_type& __a = allocator_type()) _Base(__gnu_debug::__check_valid_range (__f,__l),__l,__n,__hf,__eql,__a)111ffeaf689SAlexander Kabaev : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, 112ffeaf689SAlexander Kabaev __eql, __a) { } 113ffeaf689SAlexander Kabaev hash_map(const _Base & __x)114ffeaf689SAlexander Kabaev hash_map(const _Base& __x) : _Base(__x), _Safe_base() { } 115ffeaf689SAlexander Kabaev 116ffeaf689SAlexander Kabaev using _Base::size; 117ffeaf689SAlexander Kabaev using _Base::max_size; 118ffeaf689SAlexander Kabaev using _Base::empty; 119ffeaf689SAlexander Kabaev 120ffeaf689SAlexander Kabaev void swap(hash_map & __x)121ffeaf689SAlexander Kabaev swap(hash_map& __x) 122ffeaf689SAlexander Kabaev { 123ffeaf689SAlexander Kabaev _Base::swap(__x); 124ffeaf689SAlexander Kabaev this->_M_swap(__x); 125ffeaf689SAlexander Kabaev } 126ffeaf689SAlexander Kabaev 127ffeaf689SAlexander Kabaev iterator begin()128ffeaf689SAlexander Kabaev begin() { return iterator(_Base::begin(), this); } 129ffeaf689SAlexander Kabaev 130ffeaf689SAlexander Kabaev iterator end()131ffeaf689SAlexander Kabaev end() { return iterator(_Base::end(), this); } 132ffeaf689SAlexander Kabaev 133ffeaf689SAlexander Kabaev const_iterator begin()134ffeaf689SAlexander Kabaev begin() const 135ffeaf689SAlexander Kabaev { return const_iterator(_Base::begin(), this); } 136ffeaf689SAlexander Kabaev 137ffeaf689SAlexander Kabaev const_iterator end()138ffeaf689SAlexander Kabaev end() const 139ffeaf689SAlexander Kabaev { return const_iterator(_Base::end(), this); } 140ffeaf689SAlexander Kabaev 141ffeaf689SAlexander Kabaev std::pair<iterator, bool> insert(const value_type & __obj)142ffeaf689SAlexander Kabaev insert(const value_type& __obj) 143ffeaf689SAlexander Kabaev { 144ffeaf689SAlexander Kabaev std::pair<typename _Base::iterator, bool> __res = _Base::insert(__obj); 145ffeaf689SAlexander Kabaev return std::make_pair(iterator(__res.first, this), __res.second); 146ffeaf689SAlexander Kabaev } 147ffeaf689SAlexander Kabaev 148*f8a1b7d9SAlexander Kabaev void insert(const value_type * __first,const value_type * __last)149*f8a1b7d9SAlexander Kabaev insert(const value_type* __first, const value_type* __last) 150*f8a1b7d9SAlexander Kabaev { 151*f8a1b7d9SAlexander Kabaev __glibcxx_check_valid_range(__first, __last); 152*f8a1b7d9SAlexander Kabaev _Base::insert(__first, __last); 153*f8a1b7d9SAlexander Kabaev } 154*f8a1b7d9SAlexander Kabaev 155ffeaf689SAlexander Kabaev template<typename _InputIterator> 156ffeaf689SAlexander Kabaev void insert(_InputIterator __first,_InputIterator __last)157ffeaf689SAlexander Kabaev insert(_InputIterator __first, _InputIterator __last) 158ffeaf689SAlexander Kabaev { 159ffeaf689SAlexander Kabaev __glibcxx_check_valid_range(__first, __last); 160ffeaf689SAlexander Kabaev _Base::insert(__first.base(), __last.base()); 161ffeaf689SAlexander Kabaev } 162ffeaf689SAlexander Kabaev 163ffeaf689SAlexander Kabaev 164ffeaf689SAlexander Kabaev std::pair<iterator, bool> insert_noresize(const value_type & __obj)165ffeaf689SAlexander Kabaev insert_noresize(const value_type& __obj) 166ffeaf689SAlexander Kabaev { 167ffeaf689SAlexander Kabaev std::pair<typename _Base::iterator, bool> __res = 168ffeaf689SAlexander Kabaev _Base::insert_noresize(__obj); 169ffeaf689SAlexander Kabaev return std::make_pair(iterator(__res.first, this), __res.second); 170ffeaf689SAlexander Kabaev } 171ffeaf689SAlexander Kabaev 172ffeaf689SAlexander Kabaev iterator find(const key_type & __key)173ffeaf689SAlexander Kabaev find(const key_type& __key) 174ffeaf689SAlexander Kabaev { return iterator(_Base::find(__key), this); } 175ffeaf689SAlexander Kabaev 176ffeaf689SAlexander Kabaev const_iterator find(const key_type & __key)177ffeaf689SAlexander Kabaev find(const key_type& __key) const 178ffeaf689SAlexander Kabaev { return const_iterator(_Base::find(__key), this); } 179ffeaf689SAlexander Kabaev 180ffeaf689SAlexander Kabaev using _Base::operator[]; 181ffeaf689SAlexander Kabaev using _Base::count; 182ffeaf689SAlexander Kabaev 183ffeaf689SAlexander Kabaev std::pair<iterator, iterator> equal_range(const key_type & __key)184ffeaf689SAlexander Kabaev equal_range(const key_type& __key) 185ffeaf689SAlexander Kabaev { 186ffeaf689SAlexander Kabaev typedef typename _Base::iterator _Base_iterator; 187ffeaf689SAlexander Kabaev std::pair<_Base_iterator, _Base_iterator> __res = 188ffeaf689SAlexander Kabaev _Base::equal_range(__key); 189ffeaf689SAlexander Kabaev return std::make_pair(iterator(__res.first, this), 190ffeaf689SAlexander Kabaev iterator(__res.second, this)); 191ffeaf689SAlexander Kabaev } 192ffeaf689SAlexander Kabaev 193ffeaf689SAlexander Kabaev std::pair<const_iterator, const_iterator> equal_range(const key_type & __key)194ffeaf689SAlexander Kabaev equal_range(const key_type& __key) const 195ffeaf689SAlexander Kabaev { 196ffeaf689SAlexander Kabaev typedef typename _Base::const_iterator _Base_iterator; 197ffeaf689SAlexander Kabaev std::pair<_Base_iterator, _Base_iterator> __res = 198ffeaf689SAlexander Kabaev _Base::equal_range(__key); 199ffeaf689SAlexander Kabaev return std::make_pair(const_iterator(__res.first, this), 200ffeaf689SAlexander Kabaev const_iterator(__res.second, this)); 201ffeaf689SAlexander Kabaev } 202ffeaf689SAlexander Kabaev 203ffeaf689SAlexander Kabaev size_type erase(const key_type & __key)204ffeaf689SAlexander Kabaev erase(const key_type& __key) 205ffeaf689SAlexander Kabaev { 206ffeaf689SAlexander Kabaev iterator __victim(_Base::find(__key), this); 207ffeaf689SAlexander Kabaev if (__victim != end()) 208ffeaf689SAlexander Kabaev return this->erase(__victim), 1; 209ffeaf689SAlexander Kabaev else 210ffeaf689SAlexander Kabaev return 0; 211ffeaf689SAlexander Kabaev } 212ffeaf689SAlexander Kabaev 213ffeaf689SAlexander Kabaev void erase(iterator __it)214ffeaf689SAlexander Kabaev erase(iterator __it) 215ffeaf689SAlexander Kabaev { 216ffeaf689SAlexander Kabaev __glibcxx_check_erase(__it); 217ffeaf689SAlexander Kabaev __it._M_invalidate(); 218ffeaf689SAlexander Kabaev _Base::erase(__it.base()); 219ffeaf689SAlexander Kabaev } 220ffeaf689SAlexander Kabaev 221ffeaf689SAlexander Kabaev void erase(iterator __first,iterator __last)222ffeaf689SAlexander Kabaev erase(iterator __first, iterator __last) 223ffeaf689SAlexander Kabaev { 224ffeaf689SAlexander Kabaev __glibcxx_check_erase_range(__first, __last); 225ffeaf689SAlexander Kabaev for (iterator __tmp = __first; __tmp != __last;) 226ffeaf689SAlexander Kabaev { 227ffeaf689SAlexander Kabaev iterator __victim = __tmp++; 228ffeaf689SAlexander Kabaev __victim._M_invalidate(); 229ffeaf689SAlexander Kabaev } 230ffeaf689SAlexander Kabaev _Base::erase(__first.base(), __last.base()); 231ffeaf689SAlexander Kabaev } 232ffeaf689SAlexander Kabaev 233ffeaf689SAlexander Kabaev void clear()234ffeaf689SAlexander Kabaev clear() 235ffeaf689SAlexander Kabaev { 236ffeaf689SAlexander Kabaev _Base::clear(); 237ffeaf689SAlexander Kabaev this->_M_invalidate_all(); 238ffeaf689SAlexander Kabaev } 239ffeaf689SAlexander Kabaev 240ffeaf689SAlexander Kabaev using _Base::resize; 241ffeaf689SAlexander Kabaev using _Base::bucket_count; 242ffeaf689SAlexander Kabaev using _Base::max_bucket_count; 243ffeaf689SAlexander Kabaev using _Base::elems_in_bucket; 244ffeaf689SAlexander Kabaev 245ffeaf689SAlexander Kabaev _Base& _M_base()246ffeaf689SAlexander Kabaev _M_base() { return *this; } 247ffeaf689SAlexander Kabaev 248ffeaf689SAlexander Kabaev const _Base& _M_base()249ffeaf689SAlexander Kabaev _M_base() const { return *this; } 250ffeaf689SAlexander Kabaev 251ffeaf689SAlexander Kabaev private: 252ffeaf689SAlexander Kabaev void _M_invalidate_all()253ffeaf689SAlexander Kabaev _M_invalidate_all() 254ffeaf689SAlexander Kabaev { 255ffeaf689SAlexander Kabaev typedef typename _Base::const_iterator _Base_const_iterator; 256ffeaf689SAlexander Kabaev typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; 257ffeaf689SAlexander Kabaev this->_M_invalidate_if(_Not_equal(_M_base().end())); 258ffeaf689SAlexander Kabaev } 259ffeaf689SAlexander Kabaev }; 260ffeaf689SAlexander Kabaev 261ffeaf689SAlexander Kabaev template<typename _Value, typename _Tp, typename _HashFcn, 262ffeaf689SAlexander Kabaev typename _EqualKey, typename _Alloc> 263ffeaf689SAlexander Kabaev inline bool 264ffeaf689SAlexander Kabaev operator==(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, 265ffeaf689SAlexander Kabaev const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) 266ffeaf689SAlexander Kabaev { return __x._M_base() == __y._M_base(); } 267ffeaf689SAlexander Kabaev 268ffeaf689SAlexander Kabaev template<typename _Value, typename _Tp, typename _HashFcn, 269ffeaf689SAlexander Kabaev typename _EqualKey, typename _Alloc> 270ffeaf689SAlexander Kabaev inline bool 271ffeaf689SAlexander Kabaev operator!=(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, 272ffeaf689SAlexander Kabaev const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) 273ffeaf689SAlexander Kabaev { return __x._M_base() != __y._M_base(); } 274ffeaf689SAlexander Kabaev 275ffeaf689SAlexander Kabaev template<typename _Value, typename _Tp, typename _HashFcn, 276ffeaf689SAlexander Kabaev typename _EqualKey, typename _Alloc> 277ffeaf689SAlexander Kabaev inline void swap(hash_map<_Value,_Tp,_HashFcn,_EqualKey,_Alloc> & __x,hash_map<_Value,_Tp,_HashFcn,_EqualKey,_Alloc> & __y)278ffeaf689SAlexander Kabaev swap(hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, 279ffeaf689SAlexander Kabaev hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) 280ffeaf689SAlexander Kabaev { __x.swap(__y); } 281*f8a1b7d9SAlexander Kabaev } // namespace __debug 282*f8a1b7d9SAlexander Kabaev } // namespace __gnu_cxx 283ffeaf689SAlexander Kabaev 284ffeaf689SAlexander Kabaev #endif 285