1// Hashing map implementation -*- C++ -*-
3// Copyright (C) 2001-2021 Free Software Foundation, Inc.
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)
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.
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.
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/>.
27 * Silicon Graphics Computer Systems, Inc.
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.
39 * Hewlett-Packard Company
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.
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).
56#ifndef _BACKWARD_HASH_MAP
57#define _BACKWARD_HASH_MAP 1
59#ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
60#include <backward/backward_warning.h>
63#include <bits/c++config.h>
64#include <backward/hashtable.h>
65#include <bits/concept_check.h>
67namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
69_GLIBCXX_BEGIN_NAMESPACE_VERSION
74 using std::_Select1st;
77 * This is an SGI extension.
78 * @ingroup SGIextensions
81 template<class _Key, class _Tp, class _HashFn = hash<_Key>,
82 class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> >
86 typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn,
87 _Select1st<pair<const _Key, _Tp> >,
88 _EqualKey, _Alloc> _Ht;
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;
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;
107 typedef typename _Ht::iterator iterator;
108 typedef typename _Ht::const_iterator const_iterator;
110 typedef typename _Ht::allocator_type allocator_type;
114 { return _M_ht.hash_funct(); }
118 { return _M_ht.key_eq(); }
121 get_allocator() const
122 { return _M_ht.get_allocator(); }
125 : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
128 hash_map(size_type __n)
129 : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
131 hash_map(size_type __n, const hasher& __hf)
132 : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
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) {}
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); }
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); }
148 template<class _InputIterator>
149 hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
151 : _M_ht(__n, __hf, key_equal(), allocator_type())
152 { _M_ht.insert_unique(__f, __l); }
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); }
163 { return _M_ht.size(); }
167 { return _M_ht.max_size(); }
169 _GLIBCXX_NODISCARD bool
171 { return _M_ht.empty(); }
175 { _M_ht.swap(__hs._M_ht); }
177 template<class _K1, class _T1, class _HF, class _EqK, class _Al>
179 operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&,
180 const hash_map<_K1, _T1, _HF, _EqK, _Al>&);
184 { return _M_ht.begin(); }
188 { return _M_ht.end(); }
192 { return _M_ht.begin(); }
196 { return _M_ht.end(); }
199 insert(const value_type& __obj)
200 { return _M_ht.insert_unique(__obj); }
202 template<class _InputIterator>
204 insert(_InputIterator __f, _InputIterator __l)
205 { _M_ht.insert_unique(__f, __l); }
208 insert_noresize(const value_type& __obj)
209 { return _M_ht.insert_unique_noresize(__obj); }
212 find(const key_type& __key)
213 { return _M_ht.find(__key); }
216 find(const key_type& __key) const
217 { return _M_ht.find(__key); }
220 operator[](const key_type& __key)
221 { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; }
224 count(const key_type& __key) const
225 { return _M_ht.count(__key); }
227 pair<iterator, iterator>
228 equal_range(const key_type& __key)
229 { return _M_ht.equal_range(__key); }
231 pair<const_iterator, const_iterator>
232 equal_range(const key_type& __key) const
233 { return _M_ht.equal_range(__key); }
236 erase(const key_type& __key)
237 {return _M_ht.erase(__key); }
241 { _M_ht.erase(__it); }
244 erase(iterator __f, iterator __l)
245 { _M_ht.erase(__f, __l); }
252 resize(size_type __hint)
253 { _M_ht.resize(__hint); }
257 { return _M_ht.bucket_count(); }
260 max_bucket_count() const
261 { return _M_ht.max_bucket_count(); }
264 elems_in_bucket(size_type __n) const
265 { return _M_ht.elems_in_bucket(__n); }
268 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
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; }
274 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
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); }
280 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
282 swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
283 hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
284 { __hm1.swap(__hm2); }
288 * This is an SGI extension.
289 * @ingroup SGIextensions
292 template<class _Key, class _Tp,
293 class _HashFn = hash<_Key>,
294 class _EqualKey = equal_to<_Key>,
295 class _Alloc = allocator<_Tp> >
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)
305 typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFn,
306 _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc>
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;
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;
326 typedef typename _Ht::iterator iterator;
327 typedef typename _Ht::const_iterator const_iterator;
329 typedef typename _Ht::allocator_type allocator_type;
333 { return _M_ht.hash_funct(); }
337 { return _M_ht.key_eq(); }
340 get_allocator() const
341 { return _M_ht.get_allocator(); }
344 : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
347 hash_multimap(size_type __n)
348 : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
350 hash_multimap(size_type __n, const hasher& __hf)
351 : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
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) {}
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); }
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); }
367 template<class _InputIterator>
368 hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
370 : _M_ht(__n, __hf, key_equal(), allocator_type())
371 { _M_ht.insert_equal(__f, __l); }
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); }
382 { return _M_ht.size(); }
386 { return _M_ht.max_size(); }
388 _GLIBCXX_NODISCARD bool
390 { return _M_ht.empty(); }
393 swap(hash_multimap& __hs)
394 { _M_ht.swap(__hs._M_ht); }
396 template<class _K1, class _T1, class _HF, class _EqK, class _Al>
398 operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&,
399 const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&);
403 { return _M_ht.begin(); }
407 { return _M_ht.end(); }
411 { return _M_ht.begin(); }
415 { return _M_ht.end(); }
418 insert(const value_type& __obj)
419 { return _M_ht.insert_equal(__obj); }
421 template<class _InputIterator>
423 insert(_InputIterator __f, _InputIterator __l)
424 { _M_ht.insert_equal(__f,__l); }
427 insert_noresize(const value_type& __obj)
428 { return _M_ht.insert_equal_noresize(__obj); }
431 find(const key_type& __key)
432 { return _M_ht.find(__key); }
435 find(const key_type& __key) const
436 { return _M_ht.find(__key); }
439 count(const key_type& __key) const
440 { return _M_ht.count(__key); }
442 pair<iterator, iterator>
443 equal_range(const key_type& __key)
444 { return _M_ht.equal_range(__key); }
446 pair<const_iterator, const_iterator>
447 equal_range(const key_type& __key) const
448 { return _M_ht.equal_range(__key); }
451 erase(const key_type& __key)
452 { return _M_ht.erase(__key); }
456 { _M_ht.erase(__it); }
459 erase(iterator __f, iterator __l)
460 { _M_ht.erase(__f, __l); }
467 resize(size_type __hint)
468 { _M_ht.resize(__hint); }
472 { return _M_ht.bucket_count(); }
475 max_bucket_count() const
476 { return _M_ht.max_bucket_count(); }
479 elems_in_bucket(size_type __n) const
480 { return _M_ht.elems_in_bucket(__n); }
483 template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
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; }
489 template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
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); }
495 template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
497 swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
498 hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
499 { __hm1.swap(__hm2); }
501_GLIBCXX_END_NAMESPACE_VERSION
504namespace std _GLIBCXX_VISIBILITY(default)
506_GLIBCXX_BEGIN_NAMESPACE_VERSION
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,
515 typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>
517 _Container* container;
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;
527 insert_iterator(_Container& __x)
530 insert_iterator(_Container& __x, typename _Container::iterator)
533 insert_iterator<_Container>&
534 operator=(const typename _Container::value_type& __value)
536 container->insert(__value);
540 insert_iterator<_Container>&
544 insert_iterator<_Container>&
545 operator++() { return *this; }
547 insert_iterator<_Container>&
552 template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
553 class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn,
557 typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc>
559 _Container* container;
560 typename _Container::iterator iter;
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;
570 insert_iterator(_Container& __x)
573 insert_iterator(_Container& __x, typename _Container::iterator)
576 insert_iterator<_Container>&
577 operator=(const typename _Container::value_type& __value)
579 container->insert(__value);
583 insert_iterator<_Container>&
587 insert_iterator<_Container>&
591 insert_iterator<_Container>&
596_GLIBCXX_END_NAMESPACE_VERSION