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