1// Hashing map implementation -*- C++ -*- 2 3// Copyright (C) 2001-2013 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 3, or (at your option) 9// any later version. 10 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License and 21// a copy of the GCC Runtime Library Exception along with this program; 22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23// <http://www.gnu.org/licenses/>. 24 25/* 26 * Copyright (c) 1996 27 * Silicon Graphics Computer Systems, Inc. 28 * 29 * Permission to use, copy, modify, distribute and sell this software 30 * and its documentation for any purpose is hereby granted without fee, 31 * provided that the above copyright notice appear in all copies and 32 * that both that copyright notice and this permission notice appear 33 * in supporting documentation. Silicon Graphics makes no 34 * representations about the suitability of this software for any 35 * purpose. It is provided "as is" without express or implied warranty. 36 * 37 * 38 * Copyright (c) 1994 39 * Hewlett-Packard Company 40 * 41 * Permission to use, copy, modify, distribute and sell this software 42 * and its documentation for any purpose is hereby granted without fee, 43 * provided that the above copyright notice appear in all copies and 44 * that both that copyright notice and this permission notice appear 45 * in supporting documentation. Hewlett-Packard Company makes no 46 * representations about the suitability of this software for any 47 * purpose. It is provided "as is" without express or implied warranty. 48 * 49 */ 50 51/** @file backward/hash_map 52 * This file is a GNU extension to the Standard C++ Library (possibly 53 * containing extensions from the HP/SGI STL subset). 54 */ 55 56#ifndef _BACKWARD_HASH_MAP 57#define _BACKWARD_HASH_MAP 1 58 59#ifndef _GLIBCXX_PERMIT_BACKWARD_HASH 60#include "backward_warning.h" 61#endif 62 63#include <bits/c++config.h> 64#include <backward/hashtable.h> 65#include <bits/concept_check.h> 66 67namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 68{ 69_GLIBCXX_BEGIN_NAMESPACE_VERSION 70 71 using std::equal_to; 72 using std::allocator; 73 using std::pair; 74 using std::_Select1st; 75 76 /** 77 * This is an SGI extension. 78 * @ingroup SGIextensions 79 * @doctodo 80 */ 81 template<class _Key, class _Tp, class _HashFn = hash<_Key>, 82 class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > 83 class hash_map 84 { 85 private: 86 typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn, 87 _Select1st<pair<const _Key, _Tp> >, 88 _EqualKey, _Alloc> _Ht; 89 90 _Ht _M_ht; 91 92 public: 93 typedef typename _Ht::key_type key_type; 94 typedef _Tp data_type; 95 typedef _Tp mapped_type; 96 typedef typename _Ht::value_type value_type; 97 typedef typename _Ht::hasher hasher; 98 typedef typename _Ht::key_equal key_equal; 99 100 typedef typename _Ht::size_type size_type; 101 typedef typename _Ht::difference_type difference_type; 102 typedef typename _Ht::pointer pointer; 103 typedef typename _Ht::const_pointer const_pointer; 104 typedef typename _Ht::reference reference; 105 typedef typename _Ht::const_reference const_reference; 106 107 typedef typename _Ht::iterator iterator; 108 typedef typename _Ht::const_iterator const_iterator; 109 110 typedef typename _Ht::allocator_type allocator_type; 111 112 hasher 113 hash_funct() const 114 { return _M_ht.hash_funct(); } 115 116 key_equal 117 key_eq() const 118 { return _M_ht.key_eq(); } 119 120 allocator_type 121 get_allocator() const 122 { return _M_ht.get_allocator(); } 123 124 hash_map() 125 : _M_ht(100, hasher(), key_equal(), allocator_type()) {} 126 127 explicit 128 hash_map(size_type __n) 129 : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} 130 131 hash_map(size_type __n, const hasher& __hf) 132 : _M_ht(__n, __hf, key_equal(), allocator_type()) {} 133 134 hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, 135 const allocator_type& __a = allocator_type()) 136 : _M_ht(__n, __hf, __eql, __a) {} 137 138 template<class _InputIterator> 139 hash_map(_InputIterator __f, _InputIterator __l) 140 : _M_ht(100, hasher(), key_equal(), allocator_type()) 141 { _M_ht.insert_unique(__f, __l); } 142 143 template<class _InputIterator> 144 hash_map(_InputIterator __f, _InputIterator __l, size_type __n) 145 : _M_ht(__n, hasher(), key_equal(), allocator_type()) 146 { _M_ht.insert_unique(__f, __l); } 147 148 template<class _InputIterator> 149 hash_map(_InputIterator __f, _InputIterator __l, size_type __n, 150 const hasher& __hf) 151 : _M_ht(__n, __hf, key_equal(), allocator_type()) 152 { _M_ht.insert_unique(__f, __l); } 153 154 template<class _InputIterator> 155 hash_map(_InputIterator __f, _InputIterator __l, size_type __n, 156 const hasher& __hf, const key_equal& __eql, 157 const allocator_type& __a = allocator_type()) 158 : _M_ht(__n, __hf, __eql, __a) 159 { _M_ht.insert_unique(__f, __l); } 160 161 size_type 162 size() const 163 { return _M_ht.size(); } 164 165 size_type 166 max_size() const 167 { return _M_ht.max_size(); } 168 169 bool 170 empty() const 171 { return _M_ht.empty(); } 172 173 void 174 swap(hash_map& __hs) 175 { _M_ht.swap(__hs._M_ht); } 176 177 template<class _K1, class _T1, class _HF, class _EqK, class _Al> 178 friend bool 179 operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, 180 const hash_map<_K1, _T1, _HF, _EqK, _Al>&); 181 182 iterator 183 begin() 184 { return _M_ht.begin(); } 185 186 iterator 187 end() 188 { return _M_ht.end(); } 189 190 const_iterator 191 begin() const 192 { return _M_ht.begin(); } 193 194 const_iterator 195 end() const 196 { return _M_ht.end(); } 197 198 pair<iterator, bool> 199 insert(const value_type& __obj) 200 { return _M_ht.insert_unique(__obj); } 201 202 template<class _InputIterator> 203 void 204 insert(_InputIterator __f, _InputIterator __l) 205 { _M_ht.insert_unique(__f, __l); } 206 207 pair<iterator, bool> 208 insert_noresize(const value_type& __obj) 209 { return _M_ht.insert_unique_noresize(__obj); } 210 211 iterator 212 find(const key_type& __key) 213 { return _M_ht.find(__key); } 214 215 const_iterator 216 find(const key_type& __key) const 217 { return _M_ht.find(__key); } 218 219 _Tp& 220 operator[](const key_type& __key) 221 { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } 222 223 size_type 224 count(const key_type& __key) const 225 { return _M_ht.count(__key); } 226 227 pair<iterator, iterator> 228 equal_range(const key_type& __key) 229 { return _M_ht.equal_range(__key); } 230 231 pair<const_iterator, const_iterator> 232 equal_range(const key_type& __key) const 233 { return _M_ht.equal_range(__key); } 234 235 size_type 236 erase(const key_type& __key) 237 {return _M_ht.erase(__key); } 238 239 void 240 erase(iterator __it) 241 { _M_ht.erase(__it); } 242 243 void 244 erase(iterator __f, iterator __l) 245 { _M_ht.erase(__f, __l); } 246 247 void 248 clear() 249 { _M_ht.clear(); } 250 251 void 252 resize(size_type __hint) 253 { _M_ht.resize(__hint); } 254 255 size_type 256 bucket_count() const 257 { return _M_ht.bucket_count(); } 258 259 size_type 260 max_bucket_count() const 261 { return _M_ht.max_bucket_count(); } 262 263 size_type 264 elems_in_bucket(size_type __n) const 265 { return _M_ht.elems_in_bucket(__n); } 266 }; 267 268 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> 269 inline bool 270 operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, 271 const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) 272 { return __hm1._M_ht == __hm2._M_ht; } 273 274 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> 275 inline bool 276 operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, 277 const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) 278 { return !(__hm1 == __hm2); } 279 280 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> 281 inline void 282 swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, 283 hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) 284 { __hm1.swap(__hm2); } 285 286 287 /** 288 * This is an SGI extension. 289 * @ingroup SGIextensions 290 * @doctodo 291 */ 292 template<class _Key, class _Tp, 293 class _HashFn = hash<_Key>, 294 class _EqualKey = equal_to<_Key>, 295 class _Alloc = allocator<_Tp> > 296 class hash_multimap 297 { 298 // concept requirements 299 __glibcxx_class_requires(_Key, _SGIAssignableConcept) 300 __glibcxx_class_requires(_Tp, _SGIAssignableConcept) 301 __glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept) 302 __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept) 303 304 private: 305 typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFn, 306 _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> 307 _Ht; 308 309 _Ht _M_ht; 310 311 public: 312 typedef typename _Ht::key_type key_type; 313 typedef _Tp data_type; 314 typedef _Tp mapped_type; 315 typedef typename _Ht::value_type value_type; 316 typedef typename _Ht::hasher hasher; 317 typedef typename _Ht::key_equal key_equal; 318 319 typedef typename _Ht::size_type size_type; 320 typedef typename _Ht::difference_type difference_type; 321 typedef typename _Ht::pointer pointer; 322 typedef typename _Ht::const_pointer const_pointer; 323 typedef typename _Ht::reference reference; 324 typedef typename _Ht::const_reference const_reference; 325 326 typedef typename _Ht::iterator iterator; 327 typedef typename _Ht::const_iterator const_iterator; 328 329 typedef typename _Ht::allocator_type allocator_type; 330 331 hasher 332 hash_funct() const 333 { return _M_ht.hash_funct(); } 334 335 key_equal 336 key_eq() const 337 { return _M_ht.key_eq(); } 338 339 allocator_type 340 get_allocator() const 341 { return _M_ht.get_allocator(); } 342 343 hash_multimap() 344 : _M_ht(100, hasher(), key_equal(), allocator_type()) {} 345 346 explicit 347 hash_multimap(size_type __n) 348 : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} 349 350 hash_multimap(size_type __n, const hasher& __hf) 351 : _M_ht(__n, __hf, key_equal(), allocator_type()) {} 352 353 hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, 354 const allocator_type& __a = allocator_type()) 355 : _M_ht(__n, __hf, __eql, __a) {} 356 357 template<class _InputIterator> 358 hash_multimap(_InputIterator __f, _InputIterator __l) 359 : _M_ht(100, hasher(), key_equal(), allocator_type()) 360 { _M_ht.insert_equal(__f, __l); } 361 362 template<class _InputIterator> 363 hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) 364 : _M_ht(__n, hasher(), key_equal(), allocator_type()) 365 { _M_ht.insert_equal(__f, __l); } 366 367 template<class _InputIterator> 368 hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, 369 const hasher& __hf) 370 : _M_ht(__n, __hf, key_equal(), allocator_type()) 371 { _M_ht.insert_equal(__f, __l); } 372 373 template<class _InputIterator> 374 hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, 375 const hasher& __hf, const key_equal& __eql, 376 const allocator_type& __a = allocator_type()) 377 : _M_ht(__n, __hf, __eql, __a) 378 { _M_ht.insert_equal(__f, __l); } 379 380 size_type 381 size() const 382 { return _M_ht.size(); } 383 384 size_type 385 max_size() const 386 { return _M_ht.max_size(); } 387 388 bool 389 empty() const 390 { return _M_ht.empty(); } 391 392 void 393 swap(hash_multimap& __hs) 394 { _M_ht.swap(__hs._M_ht); } 395 396 template<class _K1, class _T1, class _HF, class _EqK, class _Al> 397 friend bool 398 operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, 399 const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); 400 401 iterator 402 begin() 403 { return _M_ht.begin(); } 404 405 iterator 406 end() 407 { return _M_ht.end(); } 408 409 const_iterator 410 begin() const 411 { return _M_ht.begin(); } 412 413 const_iterator 414 end() const 415 { return _M_ht.end(); } 416 417 iterator 418 insert(const value_type& __obj) 419 { return _M_ht.insert_equal(__obj); } 420 421 template<class _InputIterator> 422 void 423 insert(_InputIterator __f, _InputIterator __l) 424 { _M_ht.insert_equal(__f,__l); } 425 426 iterator 427 insert_noresize(const value_type& __obj) 428 { return _M_ht.insert_equal_noresize(__obj); } 429 430 iterator 431 find(const key_type& __key) 432 { return _M_ht.find(__key); } 433 434 const_iterator 435 find(const key_type& __key) const 436 { return _M_ht.find(__key); } 437 438 size_type 439 count(const key_type& __key) const 440 { return _M_ht.count(__key); } 441 442 pair<iterator, iterator> 443 equal_range(const key_type& __key) 444 { return _M_ht.equal_range(__key); } 445 446 pair<const_iterator, const_iterator> 447 equal_range(const key_type& __key) const 448 { return _M_ht.equal_range(__key); } 449 450 size_type 451 erase(const key_type& __key) 452 { return _M_ht.erase(__key); } 453 454 void 455 erase(iterator __it) 456 { _M_ht.erase(__it); } 457 458 void 459 erase(iterator __f, iterator __l) 460 { _M_ht.erase(__f, __l); } 461 462 void 463 clear() 464 { _M_ht.clear(); } 465 466 void 467 resize(size_type __hint) 468 { _M_ht.resize(__hint); } 469 470 size_type 471 bucket_count() const 472 { return _M_ht.bucket_count(); } 473 474 size_type 475 max_bucket_count() const 476 { return _M_ht.max_bucket_count(); } 477 478 size_type 479 elems_in_bucket(size_type __n) const 480 { return _M_ht.elems_in_bucket(__n); } 481 }; 482 483 template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> 484 inline bool 485 operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, 486 const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) 487 { return __hm1._M_ht == __hm2._M_ht; } 488 489 template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> 490 inline bool 491 operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, 492 const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) 493 { return !(__hm1 == __hm2); } 494 495 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> 496 inline void 497 swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, 498 hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) 499 { __hm1.swap(__hm2); } 500 501_GLIBCXX_END_NAMESPACE_VERSION 502} // namespace 503 504namespace std _GLIBCXX_VISIBILITY(default) 505{ 506_GLIBCXX_BEGIN_NAMESPACE_VERSION 507 508 // Specialization of insert_iterator so that it will work for hash_map 509 // and hash_multimap. 510 template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> 511 class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, 512 _EqKey, _Alloc> > 513 { 514 protected: 515 typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> 516 _Container; 517 _Container* container; 518 519 public: 520 typedef _Container container_type; 521 typedef output_iterator_tag iterator_category; 522 typedef void value_type; 523 typedef void difference_type; 524 typedef void pointer; 525 typedef void reference; 526 527 insert_iterator(_Container& __x) 528 : container(&__x) {} 529 530 insert_iterator(_Container& __x, typename _Container::iterator) 531 : container(&__x) {} 532 533 insert_iterator<_Container>& 534 operator=(const typename _Container::value_type& __value) 535 { 536 container->insert(__value); 537 return *this; 538 } 539 540 insert_iterator<_Container>& 541 operator*() 542 { return *this; } 543 544 insert_iterator<_Container>& 545 operator++() { return *this; } 546 547 insert_iterator<_Container>& 548 operator++(int) 549 { return *this; } 550 }; 551 552 template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> 553 class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, 554 _EqKey, _Alloc> > 555 { 556 protected: 557 typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> 558 _Container; 559 _Container* container; 560 typename _Container::iterator iter; 561 562 public: 563 typedef _Container container_type; 564 typedef output_iterator_tag iterator_category; 565 typedef void value_type; 566 typedef void difference_type; 567 typedef void pointer; 568 typedef void reference; 569 570 insert_iterator(_Container& __x) 571 : container(&__x) {} 572 573 insert_iterator(_Container& __x, typename _Container::iterator) 574 : container(&__x) {} 575 576 insert_iterator<_Container>& 577 operator=(const typename _Container::value_type& __value) 578 { 579 container->insert(__value); 580 return *this; 581 } 582 583 insert_iterator<_Container>& 584 operator*() 585 { return *this; } 586 587 insert_iterator<_Container>& 588 operator++() 589 { return *this; } 590 591 insert_iterator<_Container>& 592 operator++(int) 593 { return *this; } 594 }; 595 596_GLIBCXX_END_NAMESPACE_VERSION 597} // namespace 598 599#endif 600