hash_map

Go to the documentation of this file.
00001 // Hashing map implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 /*
00031  * Copyright (c) 1996
00032  * Silicon Graphics Computer Systems, Inc.
00033  *
00034  * Permission to use, copy, modify, distribute and sell this software
00035  * and its documentation for any purpose is hereby granted without fee,
00036  * provided that the above copyright notice appear in all copies and
00037  * that both that copyright notice and this permission notice appear
00038  * in supporting documentation.  Silicon Graphics makes no
00039  * representations about the suitability of this software for any
00040  * purpose.  It is provided "as is" without express or implied warranty.
00041  *
00042  *
00043  * Copyright (c) 1994
00044  * Hewlett-Packard Company
00045  *
00046  * Permission to use, copy, modify, distribute and sell this software
00047  * and its documentation for any purpose is hereby granted without fee,
00048  * provided that the above copyright notice appear in all copies and
00049  * that both that copyright notice and this permission notice appear
00050  * in supporting documentation.  Hewlett-Packard Company makes no
00051  * representations about the suitability of this software for any
00052  * purpose.  It is provided "as is" without express or implied warranty.
00053  *
00054  */
00055 
00056 /** @file backward/hash_map
00057  *  This file is a GNU extension to the Standard C++ Library (possibly
00058  *  containing extensions from the HP/SGI STL subset).
00059  */
00060 
00061 #ifndef _HASH_MAP
00062 #define _HASH_MAP 1
00063 
00064 #include "backward_warning.h"
00065 #include <bits/c++config.h>
00066 #include <backward/hashtable.h>
00067 #include <bits/concept_check.h>
00068 
00069 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
00070 
00071   using std::equal_to;
00072   using std::allocator;
00073   using std::pair;
00074   using std::_Select1st;
00075 
00076   /**
00077    *  This is an SGI extension.
00078    *  @ingroup SGIextensions
00079    *  @doctodo
00080    */
00081   template<class _Key, class _Tp, class _HashFn = hash<_Key>,
00082        class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> >
00083     class hash_map
00084     {
00085     private:
00086       typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn,
00087             _Select1st<pair<const _Key, _Tp> >,
00088             _EqualKey, _Alloc> _Ht;
00089 
00090       _Ht _M_ht;
00091 
00092     public:
00093       typedef typename _Ht::key_type key_type;
00094       typedef _Tp data_type;
00095       typedef _Tp mapped_type;
00096       typedef typename _Ht::value_type value_type;
00097       typedef typename _Ht::hasher hasher;
00098       typedef typename _Ht::key_equal key_equal;
00099       
00100       typedef typename _Ht::size_type size_type;
00101       typedef typename _Ht::difference_type difference_type;
00102       typedef typename _Ht::pointer pointer;
00103       typedef typename _Ht::const_pointer const_pointer;
00104       typedef typename _Ht::reference reference;
00105       typedef typename _Ht::const_reference const_reference;
00106       
00107       typedef typename _Ht::iterator iterator;
00108       typedef typename _Ht::const_iterator const_iterator;
00109       
00110       typedef typename _Ht::allocator_type allocator_type;
00111       
00112       hasher
00113       hash_funct() const
00114       { return _M_ht.hash_funct(); }
00115 
00116       key_equal
00117       key_eq() const
00118       { return _M_ht.key_eq(); }
00119 
00120       allocator_type
00121       get_allocator() const
00122       { return _M_ht.get_allocator(); }
00123 
00124       hash_map()
00125       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
00126   
00127       explicit
00128       hash_map(size_type __n)
00129       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
00130 
00131       hash_map(size_type __n, const hasher& __hf)
00132       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
00133 
00134       hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
00135            const allocator_type& __a = allocator_type())
00136       : _M_ht(__n, __hf, __eql, __a) {}
00137 
00138       template<class _InputIterator>
00139         hash_map(_InputIterator __f, _InputIterator __l)
00140     : _M_ht(100, hasher(), key_equal(), allocator_type())
00141         { _M_ht.insert_unique(__f, __l); }
00142 
00143       template<class _InputIterator>
00144         hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
00145     : _M_ht(__n, hasher(), key_equal(), allocator_type())
00146         { _M_ht.insert_unique(__f, __l); }
00147 
00148       template<class _InputIterator>
00149         hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
00150          const hasher& __hf)
00151     : _M_ht(__n, __hf, key_equal(), allocator_type())
00152         { _M_ht.insert_unique(__f, __l); }
00153 
00154       template<class _InputIterator>
00155         hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
00156          const hasher& __hf, const key_equal& __eql,
00157          const allocator_type& __a = allocator_type())
00158     : _M_ht(__n, __hf, __eql, __a)
00159         { _M_ht.insert_unique(__f, __l); }
00160 
00161       size_type
00162       size() const
00163       { return _M_ht.size(); }
00164       
00165       size_type
00166       max_size() const
00167       { return _M_ht.max_size(); }
00168       
00169       bool
00170       empty() const
00171       { return _M_ht.empty(); }
00172   
00173       void
00174       swap(hash_map& __hs)
00175       { _M_ht.swap(__hs._M_ht); }
00176 
00177       template<class _K1, class _T1, class _HF, class _EqK, class _Al>
00178         friend bool
00179         operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&,
00180             const hash_map<_K1, _T1, _HF, _EqK, _Al>&);
00181 
00182       iterator
00183       begin()
00184       { return _M_ht.begin(); }
00185 
00186       iterator
00187       end()
00188       { return _M_ht.end(); }
00189 
00190       const_iterator
00191       begin() const
00192       { return _M_ht.begin(); }
00193 
00194       const_iterator
00195       end() const
00196       { return _M_ht.end(); }
00197 
00198       pair<iterator, bool>
00199       insert(const value_type& __obj)
00200       { return _M_ht.insert_unique(__obj); }
00201 
00202       template<class _InputIterator>
00203         void
00204         insert(_InputIterator __f, _InputIterator __l)
00205         { _M_ht.insert_unique(__f, __l); }
00206 
00207       pair<iterator, bool>
00208       insert_noresize(const value_type& __obj)
00209       { return _M_ht.insert_unique_noresize(__obj); }
00210 
00211       iterator
00212       find(const key_type& __key)
00213       { return _M_ht.find(__key); }
00214 
00215       const_iterator
00216       find(const key_type& __key) const
00217       { return _M_ht.find(__key); }
00218 
00219       _Tp&
00220       operator[](const key_type& __key)
00221       { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; }
00222 
00223       size_type
00224       count(const key_type& __key) const
00225       { return _M_ht.count(__key); }
00226 
00227       pair<iterator, iterator>
00228       equal_range(const key_type& __key)
00229       { return _M_ht.equal_range(__key); }
00230 
00231       pair<const_iterator, const_iterator>
00232       equal_range(const key_type& __key) const
00233       { return _M_ht.equal_range(__key); }
00234 
00235       size_type
00236       erase(const key_type& __key)
00237       {return _M_ht.erase(__key); }
00238 
00239       void
00240       erase(iterator __it)
00241       { _M_ht.erase(__it); }
00242 
00243       void
00244       erase(iterator __f, iterator __l)
00245       { _M_ht.erase(__f, __l); }
00246 
00247       void
00248       clear()
00249       { _M_ht.clear(); }
00250 
00251       void
00252       resize(size_type __hint)
00253       { _M_ht.resize(__hint); }
00254 
00255       size_type
00256       bucket_count() const
00257       { return _M_ht.bucket_count(); }
00258 
00259       size_type
00260       max_bucket_count() const
00261       { return _M_ht.max_bucket_count(); }
00262 
00263       size_type
00264       elems_in_bucket(size_type __n) const
00265       { return _M_ht.elems_in_bucket(__n); }
00266     };
00267 
00268   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
00269     inline bool
00270     operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
00271            const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
00272     { return __hm1._M_ht == __hm2._M_ht; }
00273 
00274   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
00275     inline bool
00276     operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
00277            const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
00278     { return !(__hm1 == __hm2); }
00279 
00280   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
00281     inline void
00282     swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
00283      hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
00284     { __hm1.swap(__hm2); }
00285 
00286 
00287   /**
00288    *  This is an SGI extension.
00289    *  @ingroup SGIextensions
00290    *  @doctodo
00291    */
00292   template<class _Key, class _Tp,
00293        class _HashFn = hash<_Key>,
00294        class _EqualKey = equal_to<_Key>,
00295        class _Alloc = allocator<_Tp> >
00296     class hash_multimap
00297     {
00298       // concept requirements
00299       __glibcxx_class_requires(_Key, _SGIAssignableConcept)
00300       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
00301       __glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept)
00302       __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept)
00303     
00304     private:
00305       typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFn,
00306             _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc>
00307           _Ht;
00308 
00309       _Ht _M_ht;
00310 
00311     public:
00312       typedef typename _Ht::key_type key_type;
00313       typedef _Tp data_type;
00314       typedef _Tp mapped_type;
00315       typedef typename _Ht::value_type value_type;
00316       typedef typename _Ht::hasher hasher;
00317       typedef typename _Ht::key_equal key_equal;
00318       
00319       typedef typename _Ht::size_type size_type;
00320       typedef typename _Ht::difference_type difference_type;
00321       typedef typename _Ht::pointer pointer;
00322       typedef typename _Ht::const_pointer const_pointer;
00323       typedef typename _Ht::reference reference;
00324       typedef typename _Ht::const_reference const_reference;
00325       
00326       typedef typename _Ht::iterator iterator;
00327       typedef typename _Ht::const_iterator const_iterator;
00328       
00329       typedef typename _Ht::allocator_type allocator_type;
00330       
00331       hasher
00332       hash_funct() const
00333       { return _M_ht.hash_funct(); }
00334 
00335       key_equal
00336       key_eq() const
00337       { return _M_ht.key_eq(); }
00338 
00339       allocator_type
00340       get_allocator() const
00341       { return _M_ht.get_allocator(); }
00342 
00343       hash_multimap()
00344       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
00345 
00346       explicit
00347       hash_multimap(size_type __n)
00348       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
00349 
00350       hash_multimap(size_type __n, const hasher& __hf)
00351       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
00352 
00353       hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
00354             const allocator_type& __a = allocator_type())
00355       : _M_ht(__n, __hf, __eql, __a) {}
00356 
00357       template<class _InputIterator>
00358         hash_multimap(_InputIterator __f, _InputIterator __l)
00359     : _M_ht(100, hasher(), key_equal(), allocator_type())
00360         { _M_ht.insert_equal(__f, __l); }
00361 
00362       template<class _InputIterator>
00363         hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
00364     : _M_ht(__n, hasher(), key_equal(), allocator_type())
00365         { _M_ht.insert_equal(__f, __l); }
00366 
00367       template<class _InputIterator>
00368         hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
00369               const hasher& __hf)
00370     : _M_ht(__n, __hf, key_equal(), allocator_type())
00371         { _M_ht.insert_equal(__f, __l); }
00372 
00373       template<class _InputIterator>
00374         hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
00375               const hasher& __hf, const key_equal& __eql,
00376               const allocator_type& __a = allocator_type())
00377     : _M_ht(__n, __hf, __eql, __a)
00378         { _M_ht.insert_equal(__f, __l); }
00379 
00380       size_type
00381       size() const
00382       { return _M_ht.size(); }
00383 
00384       size_type
00385       max_size() const
00386       { return _M_ht.max_size(); }
00387 
00388       bool
00389       empty() const
00390       { return _M_ht.empty(); }
00391 
00392       void
00393       swap(hash_multimap& __hs)
00394       { _M_ht.swap(__hs._M_ht); }
00395 
00396       template<class _K1, class _T1, class _HF, class _EqK, class _Al>
00397         friend bool
00398         operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&,
00399            const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&);
00400 
00401       iterator
00402       begin()
00403       { return _M_ht.begin(); }
00404 
00405       iterator
00406       end()
00407       { return _M_ht.end(); }
00408 
00409       const_iterator
00410       begin() const
00411       { return _M_ht.begin(); }
00412 
00413       const_iterator
00414       end() const
00415       { return _M_ht.end(); }
00416 
00417       iterator
00418       insert(const value_type& __obj)
00419       { return _M_ht.insert_equal(__obj); }
00420 
00421       template<class _InputIterator>
00422         void
00423         insert(_InputIterator __f, _InputIterator __l)
00424         { _M_ht.insert_equal(__f,__l); }
00425 
00426       iterator
00427       insert_noresize(const value_type& __obj)
00428       { return _M_ht.insert_equal_noresize(__obj); }
00429 
00430       iterator
00431       find(const key_type& __key)
00432       { return _M_ht.find(__key); }
00433 
00434       const_iterator
00435       find(const key_type& __key) const
00436       { return _M_ht.find(__key); }
00437 
00438       size_type
00439       count(const key_type& __key) const
00440       { return _M_ht.count(__key); }
00441 
00442       pair<iterator, iterator>
00443       equal_range(const key_type& __key)
00444       { return _M_ht.equal_range(__key); }
00445 
00446       pair<const_iterator, const_iterator>
00447       equal_range(const key_type& __key) const
00448       { return _M_ht.equal_range(__key); }
00449 
00450       size_type
00451       erase(const key_type& __key)
00452       { return _M_ht.erase(__key); }
00453 
00454       void
00455       erase(iterator __it)
00456       { _M_ht.erase(__it); }
00457 
00458       void
00459       erase(iterator __f, iterator __l)
00460       { _M_ht.erase(__f, __l); }
00461 
00462       void
00463       clear()
00464       { _M_ht.clear(); }
00465 
00466       void
00467       resize(size_type __hint)
00468       { _M_ht.resize(__hint); }
00469 
00470       size_type
00471       bucket_count() const
00472       { return _M_ht.bucket_count(); }
00473 
00474       size_type
00475       max_bucket_count() const
00476       { return _M_ht.max_bucket_count(); }
00477       
00478       size_type
00479       elems_in_bucket(size_type __n) const
00480       { return _M_ht.elems_in_bucket(__n); }
00481     };
00482 
00483   template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
00484     inline bool
00485     operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
00486            const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
00487     { return __hm1._M_ht == __hm2._M_ht; }
00488 
00489   template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
00490     inline bool
00491     operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
00492            const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
00493     { return !(__hm1 == __hm2); }
00494 
00495   template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
00496     inline void
00497     swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
00498      hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
00499     { __hm1.swap(__hm2); }
00500 
00501 _GLIBCXX_END_NAMESPACE
00502 
00503 _GLIBCXX_BEGIN_NAMESPACE(std)
00504 
00505   // Specialization of insert_iterator so that it will work for hash_map
00506   // and hash_multimap.
00507   template<class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
00508     class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, 
00509                           _EqKey, _Alloc> >
00510     {
00511     protected:
00512       typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>
00513         _Container;
00514       _Container* container;
00515 
00516     public:
00517       typedef _Container          container_type;
00518       typedef output_iterator_tag iterator_category;
00519       typedef void                value_type;
00520       typedef void                difference_type;
00521       typedef void                pointer;
00522       typedef void                reference;
00523       
00524       insert_iterator(_Container& __x)
00525       : container(&__x) {}
00526 
00527       insert_iterator(_Container& __x, typename _Container::iterator)
00528       : container(&__x) {}
00529 
00530       insert_iterator<_Container>&
00531       operator=(const typename _Container::value_type& __value)
00532       {
00533     container->insert(__value);
00534     return *this;
00535       }
00536 
00537       insert_iterator<_Container>&
00538       operator*()
00539       { return *this; }
00540 
00541       insert_iterator<_Container>&
00542       operator++() { return *this; }
00543 
00544       insert_iterator<_Container>&
00545       operator++(int)
00546       { return *this; }
00547     };
00548 
00549   template<class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
00550     class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn,
00551                            _EqKey, _Alloc> >
00552     {
00553     protected:
00554       typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc>
00555         _Container;
00556       _Container* container;
00557       typename _Container::iterator iter;
00558 
00559     public:
00560       typedef _Container          container_type;
00561       typedef output_iterator_tag iterator_category;
00562       typedef void                value_type;
00563       typedef void                difference_type;
00564       typedef void                pointer;
00565       typedef void                reference;
00566 
00567       insert_iterator(_Container& __x)
00568       : container(&__x) {}
00569 
00570       insert_iterator(_Container& __x, typename _Container::iterator)
00571       : container(&__x) {}
00572 
00573       insert_iterator<_Container>&
00574       operator=(const typename _Container::value_type& __value)
00575       {
00576     container->insert(__value);
00577     return *this;
00578       }
00579 
00580       insert_iterator<_Container>&
00581       operator*()
00582       { return *this; }
00583 
00584       insert_iterator<_Container>&
00585       operator++()
00586       { return *this; }
00587 
00588       insert_iterator<_Container>&
00589       operator++(int)
00590       { return *this; }
00591     };
00592 
00593 _GLIBCXX_END_NAMESPACE
00594 
00595 #endif

Generated on Wed Mar 26 00:42:58 2008 for libstdc++ by  doxygen 1.5.1