1// Hashing set implementation -*- C++ -*- 2 3// Copyright (C) 2001-2020 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_set 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_SET 57#define _BACKWARD_HASH_SET 1 58 59#ifndef _GLIBCXX_PERMIT_BACKWARD_HASH 60#include <backward/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::_Identity; 75 76 /** 77 * This is an SGI extension. 78 * @ingroup SGIextensions 79 * @doctodo 80 */ 81 template<class _Value, class _HashFcn = hash<_Value>, 82 class _EqualKey = equal_to<_Value>, 83 class _Alloc = allocator<_Value> > 84 class hash_set 85 { 86 // concept requirements 87 __glibcxx_class_requires(_Value, _SGIAssignableConcept) 88 __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) 89 __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) 90 91 typedef __alloc_traits<_Alloc> _Alloc_traits; 92 93 private: 94 typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, 95 _EqualKey, _Alloc> _Ht; 96 _Ht _M_ht; 97 98 public: 99 typedef typename _Ht::key_type key_type; 100 typedef typename _Ht::value_type value_type; 101 typedef typename _Ht::hasher hasher; 102 typedef typename _Ht::key_equal key_equal; 103 104 typedef typename _Ht::size_type size_type; 105 typedef typename _Ht::difference_type difference_type; 106 typedef typename _Alloc_traits::pointer pointer; 107 typedef typename _Alloc_traits::const_pointer const_pointer; 108 typedef typename _Alloc_traits::reference reference; 109 typedef typename _Alloc_traits::const_reference const_reference; 110 111 typedef typename _Ht::const_iterator iterator; 112 typedef typename _Ht::const_iterator const_iterator; 113 114 typedef typename _Ht::allocator_type allocator_type; 115 116 hasher 117 hash_funct() const 118 { return _M_ht.hash_funct(); } 119 120 key_equal 121 key_eq() const 122 { return _M_ht.key_eq(); } 123 124 allocator_type 125 get_allocator() const 126 { return _M_ht.get_allocator(); } 127 128 hash_set() 129 : _M_ht(100, hasher(), key_equal(), allocator_type()) {} 130 131 explicit 132 hash_set(size_type __n) 133 : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} 134 135 hash_set(size_type __n, const hasher& __hf) 136 : _M_ht(__n, __hf, key_equal(), allocator_type()) {} 137 138 hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, 139 const allocator_type& __a = allocator_type()) 140 : _M_ht(__n, __hf, __eql, __a) {} 141 142 template<class _InputIterator> 143 hash_set(_InputIterator __f, _InputIterator __l) 144 : _M_ht(100, hasher(), key_equal(), allocator_type()) 145 { _M_ht.insert_unique(__f, __l); } 146 147 template<class _InputIterator> 148 hash_set(_InputIterator __f, _InputIterator __l, size_type __n) 149 : _M_ht(__n, hasher(), key_equal(), allocator_type()) 150 { _M_ht.insert_unique(__f, __l); } 151 152 template<class _InputIterator> 153 hash_set(_InputIterator __f, _InputIterator __l, size_type __n, 154 const hasher& __hf) 155 : _M_ht(__n, __hf, key_equal(), allocator_type()) 156 { _M_ht.insert_unique(__f, __l); } 157 158 template<class _InputIterator> 159 hash_set(_InputIterator __f, _InputIterator __l, size_type __n, 160 const hasher& __hf, const key_equal& __eql, 161 const allocator_type& __a = allocator_type()) 162 : _M_ht(__n, __hf, __eql, __a) 163 { _M_ht.insert_unique(__f, __l); } 164 165 size_type 166 size() const 167 { return _M_ht.size(); } 168 169 size_type 170 max_size() const 171 { return _M_ht.max_size(); } 172 173 _GLIBCXX_NODISCARD bool 174 empty() const 175 { return _M_ht.empty(); } 176 177 void 178 swap(hash_set& __hs) 179 { _M_ht.swap(__hs._M_ht); } 180 181 template<class _Val, class _HF, class _EqK, class _Al> 182 friend bool 183 operator==(const hash_set<_Val, _HF, _EqK, _Al>&, 184 const hash_set<_Val, _HF, _EqK, _Al>&); 185 186 iterator 187 begin() const 188 { return _M_ht.begin(); } 189 190 iterator 191 end() const 192 { return _M_ht.end(); } 193 194 pair<iterator, bool> 195 insert(const value_type& __obj) 196 { 197 pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj); 198 return pair<iterator,bool>(__p.first, __p.second); 199 } 200 201 template<class _InputIterator> 202 void 203 insert(_InputIterator __f, _InputIterator __l) 204 { _M_ht.insert_unique(__f, __l); } 205 206 pair<iterator, bool> 207 insert_noresize(const value_type& __obj) 208 { 209 pair<typename _Ht::iterator, bool> __p 210 = _M_ht.insert_unique_noresize(__obj); 211 return pair<iterator, bool>(__p.first, __p.second); 212 } 213 214 iterator 215 find(const key_type& __key) const 216 { return _M_ht.find(__key); } 217 218 size_type 219 count(const key_type& __key) const 220 { return _M_ht.count(__key); } 221 222 pair<iterator, iterator> 223 equal_range(const key_type& __key) const 224 { return _M_ht.equal_range(__key); } 225 226 size_type 227 erase(const key_type& __key) 228 {return _M_ht.erase(__key); } 229 230 void 231 erase(iterator __it) 232 { _M_ht.erase(__it); } 233 234 void 235 erase(iterator __f, iterator __l) 236 { _M_ht.erase(__f, __l); } 237 238 void 239 clear() 240 { _M_ht.clear(); } 241 242 void 243 resize(size_type __hint) 244 { _M_ht.resize(__hint); } 245 246 size_type 247 bucket_count() const 248 { return _M_ht.bucket_count(); } 249 250 size_type 251 max_bucket_count() const 252 { return _M_ht.max_bucket_count(); } 253 254 size_type 255 elems_in_bucket(size_type __n) const 256 { return _M_ht.elems_in_bucket(__n); } 257 }; 258 259 template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> 260 inline bool 261 operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, 262 const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) 263 { return __hs1._M_ht == __hs2._M_ht; } 264 265 template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> 266 inline bool 267 operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, 268 const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) 269 { return !(__hs1 == __hs2); } 270 271 template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> 272 inline void 273 swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, 274 hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) 275 { __hs1.swap(__hs2); } 276 277 278 /** 279 * This is an SGI extension. 280 * @ingroup SGIextensions 281 * @doctodo 282 */ 283 template<class _Value, 284 class _HashFcn = hash<_Value>, 285 class _EqualKey = equal_to<_Value>, 286 class _Alloc = allocator<_Value> > 287 class hash_multiset 288 { 289 // concept requirements 290 __glibcxx_class_requires(_Value, _SGIAssignableConcept) 291 __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) 292 __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) 293 294 private: 295 typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, 296 _EqualKey, _Alloc> _Ht; 297 _Ht _M_ht; 298 299 public: 300 typedef typename _Ht::key_type key_type; 301 typedef typename _Ht::value_type value_type; 302 typedef typename _Ht::hasher hasher; 303 typedef typename _Ht::key_equal key_equal; 304 305 typedef typename _Ht::size_type size_type; 306 typedef typename _Ht::difference_type difference_type; 307 typedef typename _Alloc::pointer pointer; 308 typedef typename _Alloc::const_pointer const_pointer; 309 typedef typename _Alloc::reference reference; 310 typedef typename _Alloc::const_reference const_reference; 311 312 typedef typename _Ht::const_iterator iterator; 313 typedef typename _Ht::const_iterator const_iterator; 314 315 typedef typename _Ht::allocator_type allocator_type; 316 317 hasher 318 hash_funct() const 319 { return _M_ht.hash_funct(); } 320 321 key_equal 322 key_eq() const 323 { return _M_ht.key_eq(); } 324 325 allocator_type 326 get_allocator() const 327 { return _M_ht.get_allocator(); } 328 329 hash_multiset() 330 : _M_ht(100, hasher(), key_equal(), allocator_type()) {} 331 332 explicit 333 hash_multiset(size_type __n) 334 : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} 335 336 hash_multiset(size_type __n, const hasher& __hf) 337 : _M_ht(__n, __hf, key_equal(), allocator_type()) {} 338 339 hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, 340 const allocator_type& __a = allocator_type()) 341 : _M_ht(__n, __hf, __eql, __a) {} 342 343 template<class _InputIterator> 344 hash_multiset(_InputIterator __f, _InputIterator __l) 345 : _M_ht(100, hasher(), key_equal(), allocator_type()) 346 { _M_ht.insert_equal(__f, __l); } 347 348 template<class _InputIterator> 349 hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) 350 : _M_ht(__n, hasher(), key_equal(), allocator_type()) 351 { _M_ht.insert_equal(__f, __l); } 352 353 template<class _InputIterator> 354 hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, 355 const hasher& __hf) 356 : _M_ht(__n, __hf, key_equal(), allocator_type()) 357 { _M_ht.insert_equal(__f, __l); } 358 359 template<class _InputIterator> 360 hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, 361 const hasher& __hf, const key_equal& __eql, 362 const allocator_type& __a = allocator_type()) 363 : _M_ht(__n, __hf, __eql, __a) 364 { _M_ht.insert_equal(__f, __l); } 365 366 size_type 367 size() const 368 { return _M_ht.size(); } 369 370 size_type 371 max_size() const 372 { return _M_ht.max_size(); } 373 374 _GLIBCXX_NODISCARD bool 375 empty() const 376 { return _M_ht.empty(); } 377 378 void 379 swap(hash_multiset& hs) 380 { _M_ht.swap(hs._M_ht); } 381 382 template<class _Val, class _HF, class _EqK, class _Al> 383 friend bool 384 operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&, 385 const hash_multiset<_Val, _HF, _EqK, _Al>&); 386 387 iterator 388 begin() const 389 { return _M_ht.begin(); } 390 391 iterator 392 end() const 393 { return _M_ht.end(); } 394 395 iterator 396 insert(const value_type& __obj) 397 { return _M_ht.insert_equal(__obj); } 398 399 template<class _InputIterator> 400 void 401 insert(_InputIterator __f, _InputIterator __l) 402 { _M_ht.insert_equal(__f,__l); } 403 404 iterator 405 insert_noresize(const value_type& __obj) 406 { return _M_ht.insert_equal_noresize(__obj); } 407 408 iterator 409 find(const key_type& __key) const 410 { return _M_ht.find(__key); } 411 412 size_type 413 count(const key_type& __key) const 414 { return _M_ht.count(__key); } 415 416 pair<iterator, iterator> 417 equal_range(const key_type& __key) const 418 { return _M_ht.equal_range(__key); } 419 420 size_type 421 erase(const key_type& __key) 422 { return _M_ht.erase(__key); } 423 424 void 425 erase(iterator __it) 426 { _M_ht.erase(__it); } 427 428 void 429 erase(iterator __f, iterator __l) 430 { _M_ht.erase(__f, __l); } 431 432 void 433 clear() 434 { _M_ht.clear(); } 435 436 void 437 resize(size_type __hint) 438 { _M_ht.resize(__hint); } 439 440 size_type 441 bucket_count() const 442 { return _M_ht.bucket_count(); } 443 444 size_type 445 max_bucket_count() const 446 { return _M_ht.max_bucket_count(); } 447 448 size_type 449 elems_in_bucket(size_type __n) const 450 { return _M_ht.elems_in_bucket(__n); } 451 }; 452 453 template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> 454 inline bool 455 operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, 456 const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) 457 { return __hs1._M_ht == __hs2._M_ht; } 458 459 template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> 460 inline bool 461 operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, 462 const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) 463 { return !(__hs1 == __hs2); } 464 465 template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> 466 inline void 467 swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, 468 hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) 469 { __hs1.swap(__hs2); } 470 471_GLIBCXX_END_NAMESPACE_VERSION 472} // namespace 473 474namespace std _GLIBCXX_VISIBILITY(default) 475{ 476_GLIBCXX_BEGIN_NAMESPACE_VERSION 477 478 // Specialization of insert_iterator so that it will work for hash_set 479 // and hash_multiset. 480 template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> 481 class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn, 482 _EqualKey, _Alloc> > 483 { 484 protected: 485 typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> 486 _Container; 487 _Container* container; 488 489 public: 490 typedef _Container container_type; 491 typedef output_iterator_tag iterator_category; 492 typedef void value_type; 493 typedef void difference_type; 494 typedef void pointer; 495 typedef void reference; 496 497 insert_iterator(_Container& __x) 498 : container(&__x) {} 499 500 insert_iterator(_Container& __x, typename _Container::iterator) 501 : container(&__x) {} 502 503 insert_iterator<_Container>& 504 operator=(const typename _Container::value_type& __value) 505 { 506 container->insert(__value); 507 return *this; 508 } 509 510 insert_iterator<_Container>& 511 operator*() 512 { return *this; } 513 514 insert_iterator<_Container>& 515 operator++() 516 { return *this; } 517 518 insert_iterator<_Container>& 519 operator++(int) 520 { return *this; } 521 }; 522 523 template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> 524 class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn, 525 _EqualKey, _Alloc> > 526 { 527 protected: 528 typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> 529 _Container; 530 _Container* container; 531 typename _Container::iterator iter; 532 533 public: 534 typedef _Container container_type; 535 typedef output_iterator_tag iterator_category; 536 typedef void value_type; 537 typedef void difference_type; 538 typedef void pointer; 539 typedef void reference; 540 541 insert_iterator(_Container& __x) 542 : container(&__x) {} 543 544 insert_iterator(_Container& __x, typename _Container::iterator) 545 : container(&__x) {} 546 547 insert_iterator<_Container>& 548 operator=(const typename _Container::value_type& __value) 549 { 550 container->insert(__value); 551 return *this; 552 } 553 554 insert_iterator<_Container>& 555 operator*() 556 { return *this; } 557 558 insert_iterator<_Container>& 559 operator++() 560 { return *this; } 561 562 insert_iterator<_Container>& 563 operator++(int) { return *this; } 564 }; 565 566_GLIBCXX_END_NAMESPACE_VERSION 567} // namespace 568 569#endif 570