libstdc++
|
00001 // Hashing map implementation -*- C++ -*- 00002 00003 // Copyright (C) 2001, 2002, 2004, 2005, 2006, 2009, 2010 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /* 00027 * Copyright (c) 1996 00028 * Silicon Graphics Computer Systems, Inc. 00029 * 00030 * Permission to use, copy, modify, distribute and sell this software 00031 * and its documentation for any purpose is hereby granted without fee, 00032 * provided that the above copyright notice appear in all copies and 00033 * that both that copyright notice and this permission notice appear 00034 * in supporting documentation. Silicon Graphics makes no 00035 * representations about the suitability of this software for any 00036 * purpose. It is provided "as is" without express or implied warranty. 00037 * 00038 * 00039 * Copyright (c) 1994 00040 * Hewlett-Packard Company 00041 * 00042 * Permission to use, copy, modify, distribute and sell this software 00043 * and its documentation for any purpose is hereby granted without fee, 00044 * provided that the above copyright notice appear in all copies and 00045 * that both that copyright notice and this permission notice appear 00046 * in supporting documentation. Hewlett-Packard Company makes no 00047 * representations about the suitability of this software for any 00048 * purpose. It is provided "as is" without express or implied warranty. 00049 * 00050 */ 00051 00052 /** @file backward/hash_map 00053 * This file is a GNU extension to the Standard C++ Library (possibly 00054 * containing extensions from the HP/SGI STL subset). 00055 */ 00056 00057 #ifndef _BACKWARD_HASH_MAP 00058 #define _BACKWARD_HASH_MAP 1 00059 00060 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH 00061 #include "backward_warning.h" 00062 #endif 00063 00064 #include <bits/c++config.h> 00065 #include <backward/hashtable.h> 00066 #include <bits/concept_check.h> 00067 00068 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00069 { 00070 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00071 00072 using std::equal_to; 00073 using std::allocator; 00074 using std::pair; 00075 using std::_Select1st; 00076 00077 /** 00078 * This is an SGI extension. 00079 * @ingroup SGIextensions 00080 * @doctodo 00081 */ 00082 template<class _Key, class _Tp, class _HashFn = hash<_Key>, 00083 class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > 00084 class hash_map 00085 { 00086 private: 00087 typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn, 00088 _Select1st<pair<const _Key, _Tp> >, 00089 _EqualKey, _Alloc> _Ht; 00090 00091 _Ht _M_ht; 00092 00093 public: 00094 typedef typename _Ht::key_type key_type; 00095 typedef _Tp data_type; 00096 typedef _Tp mapped_type; 00097 typedef typename _Ht::value_type value_type; 00098 typedef typename _Ht::hasher hasher; 00099 typedef typename _Ht::key_equal key_equal; 00100 00101 typedef typename _Ht::size_type size_type; 00102 typedef typename _Ht::difference_type difference_type; 00103 typedef typename _Ht::pointer pointer; 00104 typedef typename _Ht::const_pointer const_pointer; 00105 typedef typename _Ht::reference reference; 00106 typedef typename _Ht::const_reference const_reference; 00107 00108 typedef typename _Ht::iterator iterator; 00109 typedef typename _Ht::const_iterator const_iterator; 00110 00111 typedef typename _Ht::allocator_type allocator_type; 00112 00113 hasher 00114 hash_funct() const 00115 { return _M_ht.hash_funct(); } 00116 00117 key_equal 00118 key_eq() const 00119 { return _M_ht.key_eq(); } 00120 00121 allocator_type 00122 get_allocator() const 00123 { return _M_ht.get_allocator(); } 00124 00125 hash_map() 00126 : _M_ht(100, hasher(), key_equal(), allocator_type()) {} 00127 00128 explicit 00129 hash_map(size_type __n) 00130 : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} 00131 00132 hash_map(size_type __n, const hasher& __hf) 00133 : _M_ht(__n, __hf, key_equal(), allocator_type()) {} 00134 00135 hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, 00136 const allocator_type& __a = allocator_type()) 00137 : _M_ht(__n, __hf, __eql, __a) {} 00138 00139 template<class _InputIterator> 00140 hash_map(_InputIterator __f, _InputIterator __l) 00141 : _M_ht(100, hasher(), key_equal(), allocator_type()) 00142 { _M_ht.insert_unique(__f, __l); } 00143 00144 template<class _InputIterator> 00145 hash_map(_InputIterator __f, _InputIterator __l, size_type __n) 00146 : _M_ht(__n, hasher(), key_equal(), allocator_type()) 00147 { _M_ht.insert_unique(__f, __l); } 00148 00149 template<class _InputIterator> 00150 hash_map(_InputIterator __f, _InputIterator __l, size_type __n, 00151 const hasher& __hf) 00152 : _M_ht(__n, __hf, key_equal(), allocator_type()) 00153 { _M_ht.insert_unique(__f, __l); } 00154 00155 template<class _InputIterator> 00156 hash_map(_InputIterator __f, _InputIterator __l, size_type __n, 00157 const hasher& __hf, const key_equal& __eql, 00158 const allocator_type& __a = allocator_type()) 00159 : _M_ht(__n, __hf, __eql, __a) 00160 { _M_ht.insert_unique(__f, __l); } 00161 00162 size_type 00163 size() const 00164 { return _M_ht.size(); } 00165 00166 size_type 00167 max_size() const 00168 { return _M_ht.max_size(); } 00169 00170 bool 00171 empty() const 00172 { return _M_ht.empty(); } 00173 00174 void 00175 swap(hash_map& __hs) 00176 { _M_ht.swap(__hs._M_ht); } 00177 00178 template<class _K1, class _T1, class _HF, class _EqK, class _Al> 00179 friend bool 00180 operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, 00181 const hash_map<_K1, _T1, _HF, _EqK, _Al>&); 00182 00183 iterator 00184 begin() 00185 { return _M_ht.begin(); } 00186 00187 iterator 00188 end() 00189 { return _M_ht.end(); } 00190 00191 const_iterator 00192 begin() const 00193 { return _M_ht.begin(); } 00194 00195 const_iterator 00196 end() const 00197 { return _M_ht.end(); } 00198 00199 pair<iterator, bool> 00200 insert(const value_type& __obj) 00201 { return _M_ht.insert_unique(__obj); } 00202 00203 template<class _InputIterator> 00204 void 00205 insert(_InputIterator __f, _InputIterator __l) 00206 { _M_ht.insert_unique(__f, __l); } 00207 00208 pair<iterator, bool> 00209 insert_noresize(const value_type& __obj) 00210 { return _M_ht.insert_unique_noresize(__obj); } 00211 00212 iterator 00213 find(const key_type& __key) 00214 { return _M_ht.find(__key); } 00215 00216 const_iterator 00217 find(const key_type& __key) const 00218 { return _M_ht.find(__key); } 00219 00220 _Tp& 00221 operator[](const key_type& __key) 00222 { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } 00223 00224 size_type 00225 count(const key_type& __key) const 00226 { return _M_ht.count(__key); } 00227 00228 pair<iterator, iterator> 00229 equal_range(const key_type& __key) 00230 { return _M_ht.equal_range(__key); } 00231 00232 pair<const_iterator, const_iterator> 00233 equal_range(const key_type& __key) const 00234 { return _M_ht.equal_range(__key); } 00235 00236 size_type 00237 erase(const key_type& __key) 00238 {return _M_ht.erase(__key); } 00239 00240 void 00241 erase(iterator __it) 00242 { _M_ht.erase(__it); } 00243 00244 void 00245 erase(iterator __f, iterator __l) 00246 { _M_ht.erase(__f, __l); } 00247 00248 void 00249 clear() 00250 { _M_ht.clear(); } 00251 00252 void 00253 resize(size_type __hint) 00254 { _M_ht.resize(__hint); } 00255 00256 size_type 00257 bucket_count() const 00258 { return _M_ht.bucket_count(); } 00259 00260 size_type 00261 max_bucket_count() const 00262 { return _M_ht.max_bucket_count(); } 00263 00264 size_type 00265 elems_in_bucket(size_type __n) const 00266 { return _M_ht.elems_in_bucket(__n); } 00267 }; 00268 00269 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> 00270 inline bool 00271 operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, 00272 const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) 00273 { return __hm1._M_ht == __hm2._M_ht; } 00274 00275 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> 00276 inline bool 00277 operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, 00278 const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) 00279 { return !(__hm1 == __hm2); } 00280 00281 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> 00282 inline void 00283 swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, 00284 hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) 00285 { __hm1.swap(__hm2); } 00286 00287 00288 /** 00289 * This is an SGI extension. 00290 * @ingroup SGIextensions 00291 * @doctodo 00292 */ 00293 template<class _Key, class _Tp, 00294 class _HashFn = hash<_Key>, 00295 class _EqualKey = equal_to<_Key>, 00296 class _Alloc = allocator<_Tp> > 00297 class hash_multimap 00298 { 00299 // concept requirements 00300 __glibcxx_class_requires(_Key, _SGIAssignableConcept) 00301 __glibcxx_class_requires(_Tp, _SGIAssignableConcept) 00302 __glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept) 00303 __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept) 00304 00305 private: 00306 typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFn, 00307 _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> 00308 _Ht; 00309 00310 _Ht _M_ht; 00311 00312 public: 00313 typedef typename _Ht::key_type key_type; 00314 typedef _Tp data_type; 00315 typedef _Tp mapped_type; 00316 typedef typename _Ht::value_type value_type; 00317 typedef typename _Ht::hasher hasher; 00318 typedef typename _Ht::key_equal key_equal; 00319 00320 typedef typename _Ht::size_type size_type; 00321 typedef typename _Ht::difference_type difference_type; 00322 typedef typename _Ht::pointer pointer; 00323 typedef typename _Ht::const_pointer const_pointer; 00324 typedef typename _Ht::reference reference; 00325 typedef typename _Ht::const_reference const_reference; 00326 00327 typedef typename _Ht::iterator iterator; 00328 typedef typename _Ht::const_iterator const_iterator; 00329 00330 typedef typename _Ht::allocator_type allocator_type; 00331 00332 hasher 00333 hash_funct() const 00334 { return _M_ht.hash_funct(); } 00335 00336 key_equal 00337 key_eq() const 00338 { return _M_ht.key_eq(); } 00339 00340 allocator_type 00341 get_allocator() const 00342 { return _M_ht.get_allocator(); } 00343 00344 hash_multimap() 00345 : _M_ht(100, hasher(), key_equal(), allocator_type()) {} 00346 00347 explicit 00348 hash_multimap(size_type __n) 00349 : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} 00350 00351 hash_multimap(size_type __n, const hasher& __hf) 00352 : _M_ht(__n, __hf, key_equal(), allocator_type()) {} 00353 00354 hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, 00355 const allocator_type& __a = allocator_type()) 00356 : _M_ht(__n, __hf, __eql, __a) {} 00357 00358 template<class _InputIterator> 00359 hash_multimap(_InputIterator __f, _InputIterator __l) 00360 : _M_ht(100, hasher(), key_equal(), allocator_type()) 00361 { _M_ht.insert_equal(__f, __l); } 00362 00363 template<class _InputIterator> 00364 hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) 00365 : _M_ht(__n, hasher(), key_equal(), allocator_type()) 00366 { _M_ht.insert_equal(__f, __l); } 00367 00368 template<class _InputIterator> 00369 hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, 00370 const hasher& __hf) 00371 : _M_ht(__n, __hf, key_equal(), allocator_type()) 00372 { _M_ht.insert_equal(__f, __l); } 00373 00374 template<class _InputIterator> 00375 hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, 00376 const hasher& __hf, const key_equal& __eql, 00377 const allocator_type& __a = allocator_type()) 00378 : _M_ht(__n, __hf, __eql, __a) 00379 { _M_ht.insert_equal(__f, __l); } 00380 00381 size_type 00382 size() const 00383 { return _M_ht.size(); } 00384 00385 size_type 00386 max_size() const 00387 { return _M_ht.max_size(); } 00388 00389 bool 00390 empty() const 00391 { return _M_ht.empty(); } 00392 00393 void 00394 swap(hash_multimap& __hs) 00395 { _M_ht.swap(__hs._M_ht); } 00396 00397 template<class _K1, class _T1, class _HF, class _EqK, class _Al> 00398 friend bool 00399 operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, 00400 const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); 00401 00402 iterator 00403 begin() 00404 { return _M_ht.begin(); } 00405 00406 iterator 00407 end() 00408 { return _M_ht.end(); } 00409 00410 const_iterator 00411 begin() const 00412 { return _M_ht.begin(); } 00413 00414 const_iterator 00415 end() const 00416 { return _M_ht.end(); } 00417 00418 iterator 00419 insert(const value_type& __obj) 00420 { return _M_ht.insert_equal(__obj); } 00421 00422 template<class _InputIterator> 00423 void 00424 insert(_InputIterator __f, _InputIterator __l) 00425 { _M_ht.insert_equal(__f,__l); } 00426 00427 iterator 00428 insert_noresize(const value_type& __obj) 00429 { return _M_ht.insert_equal_noresize(__obj); } 00430 00431 iterator 00432 find(const key_type& __key) 00433 { return _M_ht.find(__key); } 00434 00435 const_iterator 00436 find(const key_type& __key) const 00437 { return _M_ht.find(__key); } 00438 00439 size_type 00440 count(const key_type& __key) const 00441 { return _M_ht.count(__key); } 00442 00443 pair<iterator, iterator> 00444 equal_range(const key_type& __key) 00445 { return _M_ht.equal_range(__key); } 00446 00447 pair<const_iterator, const_iterator> 00448 equal_range(const key_type& __key) const 00449 { return _M_ht.equal_range(__key); } 00450 00451 size_type 00452 erase(const key_type& __key) 00453 { return _M_ht.erase(__key); } 00454 00455 void 00456 erase(iterator __it) 00457 { _M_ht.erase(__it); } 00458 00459 void 00460 erase(iterator __f, iterator __l) 00461 { _M_ht.erase(__f, __l); } 00462 00463 void 00464 clear() 00465 { _M_ht.clear(); } 00466 00467 void 00468 resize(size_type __hint) 00469 { _M_ht.resize(__hint); } 00470 00471 size_type 00472 bucket_count() const 00473 { return _M_ht.bucket_count(); } 00474 00475 size_type 00476 max_bucket_count() const 00477 { return _M_ht.max_bucket_count(); } 00478 00479 size_type 00480 elems_in_bucket(size_type __n) const 00481 { return _M_ht.elems_in_bucket(__n); } 00482 }; 00483 00484 template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> 00485 inline bool 00486 operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, 00487 const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) 00488 { return __hm1._M_ht == __hm2._M_ht; } 00489 00490 template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> 00491 inline bool 00492 operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, 00493 const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) 00494 { return !(__hm1 == __hm2); } 00495 00496 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> 00497 inline void 00498 swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, 00499 hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) 00500 { __hm1.swap(__hm2); } 00501 00502 _GLIBCXX_END_NAMESPACE_VERSION 00503 } // namespace 00504 00505 namespace std _GLIBCXX_VISIBILITY(default) 00506 { 00507 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00508 00509 // Specialization of insert_iterator so that it will work for hash_map 00510 // and hash_multimap. 00511 template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> 00512 class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, 00513 _EqKey, _Alloc> > 00514 { 00515 protected: 00516 typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> 00517 _Container; 00518 _Container* container; 00519 00520 public: 00521 typedef _Container container_type; 00522 typedef output_iterator_tag iterator_category; 00523 typedef void value_type; 00524 typedef void difference_type; 00525 typedef void pointer; 00526 typedef void reference; 00527 00528 insert_iterator(_Container& __x) 00529 : container(&__x) {} 00530 00531 insert_iterator(_Container& __x, typename _Container::iterator) 00532 : container(&__x) {} 00533 00534 insert_iterator<_Container>& 00535 operator=(const typename _Container::value_type& __value) 00536 { 00537 container->insert(__value); 00538 return *this; 00539 } 00540 00541 insert_iterator<_Container>& 00542 operator*() 00543 { return *this; } 00544 00545 insert_iterator<_Container>& 00546 operator++() { return *this; } 00547 00548 insert_iterator<_Container>& 00549 operator++(int) 00550 { return *this; } 00551 }; 00552 00553 template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> 00554 class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, 00555 _EqKey, _Alloc> > 00556 { 00557 protected: 00558 typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> 00559 _Container; 00560 _Container* container; 00561 typename _Container::iterator iter; 00562 00563 public: 00564 typedef _Container container_type; 00565 typedef output_iterator_tag iterator_category; 00566 typedef void value_type; 00567 typedef void difference_type; 00568 typedef void pointer; 00569 typedef void reference; 00570 00571 insert_iterator(_Container& __x) 00572 : container(&__x) {} 00573 00574 insert_iterator(_Container& __x, typename _Container::iterator) 00575 : container(&__x) {} 00576 00577 insert_iterator<_Container>& 00578 operator=(const typename _Container::value_type& __value) 00579 { 00580 container->insert(__value); 00581 return *this; 00582 } 00583 00584 insert_iterator<_Container>& 00585 operator*() 00586 { return *this; } 00587 00588 insert_iterator<_Container>& 00589 operator++() 00590 { return *this; } 00591 00592 insert_iterator<_Container>& 00593 operator++(int) 00594 { return *this; } 00595 }; 00596 00597 _GLIBCXX_END_NAMESPACE_VERSION 00598 } // namespace 00599 00600 #endif