hash_map

Go to the documentation of this file.
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 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
00069 
00070   using std::equal_to;
00071   using std::allocator;
00072   using std::pair;
00073   using std::_Select1st;
00074 
00075   /**
00076    *  This is an SGI extension.
00077    *  @ingroup SGIextensions
00078    *  @doctodo
00079    */
00080   template<class _Key, class _Tp, class _HashFn = hash<_Key>,
00081        class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> >
00082     class hash_map
00083     {
00084     private:
00085       typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn,
00086             _Select1st<pair<const _Key, _Tp> >,
00087             _EqualKey, _Alloc> _Ht;
00088 
00089       _Ht _M_ht;
00090 
00091     public:
00092       typedef typename _Ht::key_type key_type;
00093       typedef _Tp data_type;
00094       typedef _Tp mapped_type;
00095       typedef typename _Ht::value_type value_type;
00096       typedef typename _Ht::hasher hasher;
00097       typedef typename _Ht::key_equal key_equal;
00098       
00099       typedef typename _Ht::size_type size_type;
00100       typedef typename _Ht::difference_type difference_type;
00101       typedef typename _Ht::pointer pointer;
00102       typedef typename _Ht::const_pointer const_pointer;
00103       typedef typename _Ht::reference reference;
00104       typedef typename _Ht::const_reference const_reference;
00105       
00106       typedef typename _Ht::iterator iterator;
00107       typedef typename _Ht::const_iterator const_iterator;
00108       
00109       typedef typename _Ht::allocator_type allocator_type;
00110       
00111       hasher
00112       hash_funct() const
00113       { return _M_ht.hash_funct(); }
00114 
00115       key_equal
00116       key_eq() const
00117       { return _M_ht.key_eq(); }
00118 
00119       allocator_type
00120       get_allocator() const
00121       { return _M_ht.get_allocator(); }
00122 
00123       hash_map()
00124       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
00125   
00126       explicit
00127       hash_map(size_type __n)
00128       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
00129 
00130       hash_map(size_type __n, const hasher& __hf)
00131       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
00132 
00133       hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
00134            const allocator_type& __a = allocator_type())
00135       : _M_ht(__n, __hf, __eql, __a) {}
00136 
00137       template<class _InputIterator>
00138         hash_map(_InputIterator __f, _InputIterator __l)
00139     : _M_ht(100, hasher(), key_equal(), allocator_type())
00140         { _M_ht.insert_unique(__f, __l); }
00141 
00142       template<class _InputIterator>
00143         hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
00144     : _M_ht(__n, hasher(), key_equal(), allocator_type())
00145         { _M_ht.insert_unique(__f, __l); }
00146 
00147       template<class _InputIterator>
00148         hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
00149          const hasher& __hf)
00150     : _M_ht(__n, __hf, key_equal(), allocator_type())
00151         { _M_ht.insert_unique(__f, __l); }
00152 
00153       template<class _InputIterator>
00154         hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
00155          const hasher& __hf, const key_equal& __eql,
00156          const allocator_type& __a = allocator_type())
00157     : _M_ht(__n, __hf, __eql, __a)
00158         { _M_ht.insert_unique(__f, __l); }
00159 
00160       size_type
00161       size() const
00162       { return _M_ht.size(); }
00163       
00164       size_type
00165       max_size() const
00166       { return _M_ht.max_size(); }
00167       
00168       bool
00169       empty() const
00170       { return _M_ht.empty(); }
00171   
00172       void
00173       swap(hash_map& __hs)
00174       { _M_ht.swap(__hs._M_ht); }
00175 
00176       template<class _K1, class _T1, class _HF, class _EqK, class _Al>
00177         friend bool
00178         operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&,
00179             const hash_map<_K1, _T1, _HF, _EqK, _Al>&);
00180 
00181       iterator
00182       begin()
00183       { return _M_ht.begin(); }
00184 
00185       iterator
00186       end()
00187       { return _M_ht.end(); }
00188 
00189       const_iterator
00190       begin() const
00191       { return _M_ht.begin(); }
00192 
00193       const_iterator
00194       end() const
00195       { return _M_ht.end(); }
00196 
00197       pair<iterator, bool>
00198       insert(const value_type& __obj)
00199       { return _M_ht.insert_unique(__obj); }
00200 
00201       template<class _InputIterator>
00202         void
00203         insert(_InputIterator __f, _InputIterator __l)
00204         { _M_ht.insert_unique(__f, __l); }
00205 
00206       pair<iterator, bool>
00207       insert_noresize(const value_type& __obj)
00208       { return _M_ht.insert_unique_noresize(__obj); }
00209 
00210       iterator
00211       find(const key_type& __key)
00212       { return _M_ht.find(__key); }
00213 
00214       const_iterator
00215       find(const key_type& __key) const
00216       { return _M_ht.find(__key); }
00217 
00218       _Tp&
00219       operator[](const key_type& __key)
00220       { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; }
00221 
00222       size_type
00223       count(const key_type& __key) const
00224       { return _M_ht.count(__key); }
00225 
00226       pair<iterator, iterator>
00227       equal_range(const key_type& __key)
00228       { return _M_ht.equal_range(__key); }
00229 
00230       pair<const_iterator, const_iterator>
00231       equal_range(const key_type& __key) const
00232       { return _M_ht.equal_range(__key); }
00233 
00234       size_type
00235       erase(const key_type& __key)
00236       {return _M_ht.erase(__key); }
00237 
00238       void
00239       erase(iterator __it)
00240       { _M_ht.erase(__it); }
00241 
00242       void
00243       erase(iterator __f, iterator __l)
00244       { _M_ht.erase(__f, __l); }
00245 
00246       void
00247       clear()
00248       { _M_ht.clear(); }
00249 
00250       void
00251       resize(size_type __hint)
00252       { _M_ht.resize(__hint); }
00253 
00254       size_type
00255       bucket_count() const
00256       { return _M_ht.bucket_count(); }
00257 
00258       size_type
00259       max_bucket_count() const
00260       { return _M_ht.max_bucket_count(); }
00261 
00262       size_type
00263       elems_in_bucket(size_type __n) const
00264       { return _M_ht.elems_in_bucket(__n); }
00265     };
00266 
00267   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
00268     inline bool
00269     operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
00270            const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
00271     { return __hm1._M_ht == __hm2._M_ht; }
00272 
00273   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
00274     inline bool
00275     operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
00276            const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
00277     { return !(__hm1 == __hm2); }
00278 
00279   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
00280     inline void
00281     swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
00282      hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
00283     { __hm1.swap(__hm2); }
00284 
00285 
00286   /**
00287    *  This is an SGI extension.
00288    *  @ingroup SGIextensions
00289    *  @doctodo
00290    */
00291   template<class _Key, class _Tp,
00292        class _HashFn = hash<_Key>,
00293        class _EqualKey = equal_to<_Key>,
00294        class _Alloc = allocator<_Tp> >
00295     class hash_multimap
00296     {
00297       // concept requirements
00298       __glibcxx_class_requires(_Key, _SGIAssignableConcept)
00299       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
00300       __glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept)
00301       __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept)
00302     
00303     private:
00304       typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFn,
00305             _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc>
00306           _Ht;
00307 
00308       _Ht _M_ht;
00309 
00310     public:
00311       typedef typename _Ht::key_type key_type;
00312       typedef _Tp data_type;
00313       typedef _Tp mapped_type;
00314       typedef typename _Ht::value_type value_type;
00315       typedef typename _Ht::hasher hasher;
00316       typedef typename _Ht::key_equal key_equal;
00317       
00318       typedef typename _Ht::size_type size_type;
00319       typedef typename _Ht::difference_type difference_type;
00320       typedef typename _Ht::pointer pointer;
00321       typedef typename _Ht::const_pointer const_pointer;
00322       typedef typename _Ht::reference reference;
00323       typedef typename _Ht::const_reference const_reference;
00324       
00325       typedef typename _Ht::iterator iterator;
00326       typedef typename _Ht::const_iterator const_iterator;
00327       
00328       typedef typename _Ht::allocator_type allocator_type;
00329       
00330       hasher
00331       hash_funct() const
00332       { return _M_ht.hash_funct(); }
00333 
00334       key_equal
00335       key_eq() const
00336       { return _M_ht.key_eq(); }
00337 
00338       allocator_type
00339       get_allocator() const
00340       { return _M_ht.get_allocator(); }
00341 
00342       hash_multimap()
00343       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
00344 
00345       explicit
00346       hash_multimap(size_type __n)
00347       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
00348 
00349       hash_multimap(size_type __n, const hasher& __hf)
00350       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
00351 
00352       hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
00353             const allocator_type& __a = allocator_type())
00354       : _M_ht(__n, __hf, __eql, __a) {}
00355 
00356       template<class _InputIterator>
00357         hash_multimap(_InputIterator __f, _InputIterator __l)
00358     : _M_ht(100, hasher(), key_equal(), allocator_type())
00359         { _M_ht.insert_equal(__f, __l); }
00360 
00361       template<class _InputIterator>
00362         hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
00363     : _M_ht(__n, hasher(), key_equal(), allocator_type())
00364         { _M_ht.insert_equal(__f, __l); }
00365 
00366       template<class _InputIterator>
00367         hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
00368               const hasher& __hf)
00369     : _M_ht(__n, __hf, key_equal(), allocator_type())
00370         { _M_ht.insert_equal(__f, __l); }
00371 
00372       template<class _InputIterator>
00373         hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
00374               const hasher& __hf, const key_equal& __eql,
00375               const allocator_type& __a = allocator_type())
00376     : _M_ht(__n, __hf, __eql, __a)
00377         { _M_ht.insert_equal(__f, __l); }
00378 
00379       size_type
00380       size() const
00381       { return _M_ht.size(); }
00382 
00383       size_type
00384       max_size() const
00385       { return _M_ht.max_size(); }
00386 
00387       bool
00388       empty() const
00389       { return _M_ht.empty(); }
00390 
00391       void
00392       swap(hash_multimap& __hs)
00393       { _M_ht.swap(__hs._M_ht); }
00394 
00395       template<class _K1, class _T1, class _HF, class _EqK, class _Al>
00396         friend bool
00397         operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&,
00398            const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&);
00399 
00400       iterator
00401       begin()
00402       { return _M_ht.begin(); }
00403 
00404       iterator
00405       end()
00406       { return _M_ht.end(); }
00407 
00408       const_iterator
00409       begin() const
00410       { return _M_ht.begin(); }
00411 
00412       const_iterator
00413       end() const
00414       { return _M_ht.end(); }
00415 
00416       iterator
00417       insert(const value_type& __obj)
00418       { return _M_ht.insert_equal(__obj); }
00419 
00420       template<class _InputIterator>
00421         void
00422         insert(_InputIterator __f, _InputIterator __l)
00423         { _M_ht.insert_equal(__f,__l); }
00424 
00425       iterator
00426       insert_noresize(const value_type& __obj)
00427       { return _M_ht.insert_equal_noresize(__obj); }
00428 
00429       iterator
00430       find(const key_type& __key)
00431       { return _M_ht.find(__key); }
00432 
00433       const_iterator
00434       find(const key_type& __key) const
00435       { return _M_ht.find(__key); }
00436 
00437       size_type
00438       count(const key_type& __key) const
00439       { return _M_ht.count(__key); }
00440 
00441       pair<iterator, iterator>
00442       equal_range(const key_type& __key)
00443       { return _M_ht.equal_range(__key); }
00444 
00445       pair<const_iterator, const_iterator>
00446       equal_range(const key_type& __key) const
00447       { return _M_ht.equal_range(__key); }
00448 
00449       size_type
00450       erase(const key_type& __key)
00451       { return _M_ht.erase(__key); }
00452 
00453       void
00454       erase(iterator __it)
00455       { _M_ht.erase(__it); }
00456 
00457       void
00458       erase(iterator __f, iterator __l)
00459       { _M_ht.erase(__f, __l); }
00460 
00461       void
00462       clear()
00463       { _M_ht.clear(); }
00464 
00465       void
00466       resize(size_type __hint)
00467       { _M_ht.resize(__hint); }
00468 
00469       size_type
00470       bucket_count() const
00471       { return _M_ht.bucket_count(); }
00472 
00473       size_type
00474       max_bucket_count() const
00475       { return _M_ht.max_bucket_count(); }
00476       
00477       size_type
00478       elems_in_bucket(size_type __n) const
00479       { return _M_ht.elems_in_bucket(__n); }
00480     };
00481 
00482   template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
00483     inline bool
00484     operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
00485            const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
00486     { return __hm1._M_ht == __hm2._M_ht; }
00487 
00488   template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
00489     inline bool
00490     operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
00491            const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
00492     { return !(__hm1 == __hm2); }
00493 
00494   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
00495     inline void
00496     swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
00497      hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
00498     { __hm1.swap(__hm2); }
00499 
00500 _GLIBCXX_END_NAMESPACE
00501 
00502 _GLIBCXX_BEGIN_NAMESPACE(std)
00503 
00504   // Specialization of insert_iterator so that it will work for hash_map
00505   // and hash_multimap.
00506   template<class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
00507     class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, 
00508                           _EqKey, _Alloc> >
00509     {
00510     protected:
00511       typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>
00512         _Container;
00513       _Container* container;
00514 
00515     public:
00516       typedef _Container          container_type;
00517       typedef output_iterator_tag iterator_category;
00518       typedef void                value_type;
00519       typedef void                difference_type;
00520       typedef void                pointer;
00521       typedef void                reference;
00522       
00523       insert_iterator(_Container& __x)
00524       : container(&__x) {}
00525 
00526       insert_iterator(_Container& __x, typename _Container::iterator)
00527       : container(&__x) {}
00528 
00529       insert_iterator<_Container>&
00530       operator=(const typename _Container::value_type& __value)
00531       {
00532     container->insert(__value);
00533     return *this;
00534       }
00535 
00536       insert_iterator<_Container>&
00537       operator*()
00538       { return *this; }
00539 
00540       insert_iterator<_Container>&
00541       operator++() { return *this; }
00542 
00543       insert_iterator<_Container>&
00544       operator++(int)
00545       { return *this; }
00546     };
00547 
00548   template<class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
00549     class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn,
00550                            _EqKey, _Alloc> >
00551     {
00552     protected:
00553       typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc>
00554         _Container;
00555       _Container* container;
00556       typename _Container::iterator iter;
00557 
00558     public:
00559       typedef _Container          container_type;
00560       typedef output_iterator_tag iterator_category;
00561       typedef void                value_type;
00562       typedef void                difference_type;
00563       typedef void                pointer;
00564       typedef void                reference;
00565 
00566       insert_iterator(_Container& __x)
00567       : container(&__x) {}
00568 
00569       insert_iterator(_Container& __x, typename _Container::iterator)
00570       : container(&__x) {}
00571 
00572       insert_iterator<_Container>&
00573       operator=(const typename _Container::value_type& __value)
00574       {
00575     container->insert(__value);
00576     return *this;
00577       }
00578 
00579       insert_iterator<_Container>&
00580       operator*()
00581       { return *this; }
00582 
00583       insert_iterator<_Container>&
00584       operator++()
00585       { return *this; }
00586 
00587       insert_iterator<_Container>&
00588       operator++(int)
00589       { return *this; }
00590     };
00591 
00592 _GLIBCXX_END_NAMESPACE
00593 
00594 #endif