hash_map

Go to the documentation of this file.
00001 // Hashing map implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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 
00062 #ifndef __SGI_STL_INTERNAL_HASH_MAP_H
00063 #define __SGI_STL_INTERNAL_HASH_MAP_H
00064 
00065 #include <ext/stl_hashtable.h>
00066 #include <bits/concept_check.h>
00067 
00068 namespace __gnu_cxx
00069 {
00070 using std::equal_to;
00071 using std::allocator;
00072 using std::pair;
00073 using std::_Select1st;
00074 
00075 // Forward declaration of equality operator; needed for friend declaration.
00076 
00077 template <class _Key, class _Tp,
00078           class _HashFcn  = hash<_Key>,
00079           class _EqualKey = equal_to<_Key>,
00080           class _Alloc =  allocator<_Tp> >
00081 class hash_map;
00082 
00083 template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
00084 inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&,
00085                        const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&);
00086 
00087 template <class _Key, class _Tp, class _HashFcn, class _EqualKey,
00088           class _Alloc>
00089 class hash_map
00090 {
00091 private:
00092   typedef hashtable<pair<const _Key,_Tp>,_Key,_HashFcn,
00093                     _Select1st<pair<const _Key,_Tp> >,_EqualKey,_Alloc> _Ht;
00094   _Ht _M_ht;
00095 
00096 public:
00097   typedef typename _Ht::key_type key_type;
00098   typedef _Tp data_type;
00099   typedef _Tp mapped_type;
00100   typedef typename _Ht::value_type value_type;
00101   typedef typename _Ht::hasher hasher;
00102   typedef typename _Ht::key_equal key_equal;
00103   
00104   typedef typename _Ht::size_type size_type;
00105   typedef typename _Ht::difference_type difference_type;
00106   typedef typename _Ht::pointer pointer;
00107   typedef typename _Ht::const_pointer const_pointer;
00108   typedef typename _Ht::reference reference;
00109   typedef typename _Ht::const_reference const_reference;
00110 
00111   typedef typename _Ht::iterator iterator;
00112   typedef typename _Ht::const_iterator const_iterator;
00113 
00114   typedef typename _Ht::allocator_type allocator_type;
00115 
00116   hasher hash_funct() const { return _M_ht.hash_funct(); }
00117   key_equal key_eq() const { return _M_ht.key_eq(); }
00118   allocator_type get_allocator() const { return _M_ht.get_allocator(); }
00119 
00120 public:
00121   hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
00122   explicit hash_map(size_type __n)
00123     : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
00124   hash_map(size_type __n, const hasher& __hf)
00125     : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
00126   hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
00127            const allocator_type& __a = allocator_type())
00128     : _M_ht(__n, __hf, __eql, __a) {}
00129 
00130   template <class _InputIterator>
00131   hash_map(_InputIterator __f, _InputIterator __l)
00132     : _M_ht(100, hasher(), key_equal(), allocator_type())
00133     { _M_ht.insert_unique(__f, __l); }
00134   template <class _InputIterator>
00135   hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
00136     : _M_ht(__n, hasher(), key_equal(), allocator_type())
00137     { _M_ht.insert_unique(__f, __l); }
00138   template <class _InputIterator>
00139   hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
00140            const hasher& __hf)
00141     : _M_ht(__n, __hf, key_equal(), allocator_type())
00142     { _M_ht.insert_unique(__f, __l); }
00143   template <class _InputIterator>
00144   hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
00145            const hasher& __hf, const key_equal& __eql,
00146            const allocator_type& __a = allocator_type())
00147     : _M_ht(__n, __hf, __eql, __a)
00148     { _M_ht.insert_unique(__f, __l); }
00149 
00150 public:
00151   size_type size() const { return _M_ht.size(); }
00152   size_type max_size() const { return _M_ht.max_size(); }
00153   bool empty() const { return _M_ht.empty(); }
00154   void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); }
00155 
00156   template <class _K1, class _T1, class _HF, class _EqK, class _Al>
00157   friend bool operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&,
00158                           const hash_map<_K1, _T1, _HF, _EqK, _Al>&);
00159 
00160   iterator begin() { return _M_ht.begin(); }
00161   iterator end() { return _M_ht.end(); }
00162   const_iterator begin() const { return _M_ht.begin(); }
00163   const_iterator end() const { return _M_ht.end(); }
00164 
00165 public:
00166   pair<iterator,bool> insert(const value_type& __obj)
00167     { return _M_ht.insert_unique(__obj); }
00168   template <class _InputIterator>
00169   void insert(_InputIterator __f, _InputIterator __l)
00170     { _M_ht.insert_unique(__f,__l); }
00171   pair<iterator,bool> insert_noresize(const value_type& __obj)
00172     { return _M_ht.insert_unique_noresize(__obj); }    
00173 
00174   iterator find(const key_type& __key) { return _M_ht.find(__key); }
00175   const_iterator find(const key_type& __key) const 
00176     { return _M_ht.find(__key); }
00177 
00178   _Tp& operator[](const key_type& __key) {
00179     return _M_ht.find_or_insert(value_type(__key, _Tp())).second;
00180   }
00181 
00182   size_type count(const key_type& __key) const { return _M_ht.count(__key); }
00183   
00184   pair<iterator, iterator> equal_range(const key_type& __key)
00185     { return _M_ht.equal_range(__key); }
00186   pair<const_iterator, const_iterator>
00187   equal_range(const key_type& __key) const
00188     { return _M_ht.equal_range(__key); }
00189 
00190   size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
00191   void erase(iterator __it) { _M_ht.erase(__it); }
00192   void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
00193   void clear() { _M_ht.clear(); }
00194 
00195   void resize(size_type __hint) { _M_ht.resize(__hint); }
00196   size_type bucket_count() const { return _M_ht.bucket_count(); }
00197   size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
00198   size_type elems_in_bucket(size_type __n) const
00199     { return _M_ht.elems_in_bucket(__n); }
00200 };
00201 
00202 template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
00203 inline bool 
00204 operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
00205            const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2)
00206 {
00207   return __hm1._M_ht == __hm2._M_ht;
00208 }
00209 
00210 template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
00211 inline bool 
00212 operator!=(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
00213            const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) {
00214   return !(__hm1 == __hm2);
00215 }
00216 
00217 template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
00218 inline void 
00219 swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
00220      hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2)
00221 {
00222   __hm1.swap(__hm2);
00223 }
00224 
00225 // Forward declaration of equality operator; needed for friend declaration.
00226 
00227 template <class _Key, class _Tp,
00228           class _HashFcn  = hash<_Key>,
00229           class _EqualKey = equal_to<_Key>,
00230           class _Alloc =  allocator<_Tp> >
00231 class hash_multimap;
00232 
00233 template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
00234 inline bool 
00235 operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1,
00236            const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2);
00237 
00238 template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc>
00239 class hash_multimap
00240 {
00241   // concept requirements
00242   __glibcpp_class_requires(_Key, _SGIAssignableConcept)
00243   __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
00244   __glibcpp_class_requires3(_HashFcn, size_t, _Key, _UnaryFunctionConcept);
00245   __glibcpp_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept);
00246 
00247 private:
00248   typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFcn,
00249                     _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> 
00250           _Ht;
00251   _Ht _M_ht;
00252 
00253 public:
00254   typedef typename _Ht::key_type key_type;
00255   typedef _Tp data_type;
00256   typedef _Tp mapped_type;
00257   typedef typename _Ht::value_type value_type;
00258   typedef typename _Ht::hasher hasher;
00259   typedef typename _Ht::key_equal key_equal;
00260 
00261   typedef typename _Ht::size_type size_type;
00262   typedef typename _Ht::difference_type difference_type;
00263   typedef typename _Ht::pointer pointer;
00264   typedef typename _Ht::const_pointer const_pointer;
00265   typedef typename _Ht::reference reference;
00266   typedef typename _Ht::const_reference const_reference;
00267 
00268   typedef typename _Ht::iterator iterator;
00269   typedef typename _Ht::const_iterator const_iterator;
00270 
00271   typedef typename _Ht::allocator_type allocator_type;
00272 
00273   hasher hash_funct() const { return _M_ht.hash_funct(); }
00274   key_equal key_eq() const { return _M_ht.key_eq(); }
00275   allocator_type get_allocator() const { return _M_ht.get_allocator(); }
00276 
00277 public:
00278   hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
00279   explicit hash_multimap(size_type __n)
00280     : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
00281   hash_multimap(size_type __n, const hasher& __hf)
00282     : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
00283   hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
00284                 const allocator_type& __a = allocator_type())
00285     : _M_ht(__n, __hf, __eql, __a) {}
00286 
00287   template <class _InputIterator>
00288   hash_multimap(_InputIterator __f, _InputIterator __l)
00289     : _M_ht(100, hasher(), key_equal(), allocator_type())
00290     { _M_ht.insert_equal(__f, __l); }
00291   template <class _InputIterator>
00292   hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
00293     : _M_ht(__n, hasher(), key_equal(), allocator_type())
00294     { _M_ht.insert_equal(__f, __l); }
00295   template <class _InputIterator>
00296   hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
00297                 const hasher& __hf)
00298     : _M_ht(__n, __hf, key_equal(), allocator_type())
00299     { _M_ht.insert_equal(__f, __l); }
00300   template <class _InputIterator>
00301   hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
00302                 const hasher& __hf, const key_equal& __eql,
00303                 const allocator_type& __a = allocator_type())
00304     : _M_ht(__n, __hf, __eql, __a)
00305     { _M_ht.insert_equal(__f, __l); }
00306 
00307 public:
00308   size_type size() const { return _M_ht.size(); }
00309   size_type max_size() const { return _M_ht.max_size(); }
00310   bool empty() const { return _M_ht.empty(); }
00311   void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); }
00312 
00313   template <class _K1, class _T1, class _HF, class _EqK, class _Al>
00314   friend bool operator== (const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&,
00315                           const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&);
00316 
00317   iterator begin() { return _M_ht.begin(); }
00318   iterator end() { return _M_ht.end(); }
00319   const_iterator begin() const { return _M_ht.begin(); }
00320   const_iterator end() const { return _M_ht.end(); }
00321 
00322 public:
00323   iterator insert(const value_type& __obj) 
00324     { return _M_ht.insert_equal(__obj); }
00325   template <class _InputIterator>
00326   void insert(_InputIterator __f, _InputIterator __l) 
00327     { _M_ht.insert_equal(__f,__l); }
00328   iterator insert_noresize(const value_type& __obj)
00329     { return _M_ht.insert_equal_noresize(__obj); }    
00330 
00331   iterator find(const key_type& __key) { return _M_ht.find(__key); }
00332   const_iterator find(const key_type& __key) const 
00333     { return _M_ht.find(__key); }
00334 
00335   size_type count(const key_type& __key) const { return _M_ht.count(__key); }
00336   
00337   pair<iterator, iterator> equal_range(const key_type& __key)
00338     { return _M_ht.equal_range(__key); }
00339   pair<const_iterator, const_iterator>
00340   equal_range(const key_type& __key) const
00341     { return _M_ht.equal_range(__key); }
00342 
00343   size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
00344   void erase(iterator __it) { _M_ht.erase(__it); }
00345   void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
00346   void clear() { _M_ht.clear(); }
00347 
00348 public:
00349   void resize(size_type __hint) { _M_ht.resize(__hint); }
00350   size_type bucket_count() const { return _M_ht.bucket_count(); }
00351   size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
00352   size_type elems_in_bucket(size_type __n) const
00353     { return _M_ht.elems_in_bucket(__n); }
00354 };
00355 
00356 template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
00357 inline bool 
00358 operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1,
00359            const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2)
00360 {
00361   return __hm1._M_ht == __hm2._M_ht;
00362 }
00363 
00364 template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
00365 inline bool 
00366 operator!=(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1,
00367            const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) {
00368   return !(__hm1 == __hm2);
00369 }
00370 
00371 template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
00372 inline void 
00373 swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
00374      hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2)
00375 {
00376   __hm1.swap(__hm2);
00377 }
00378 
00379 } // namespace __gnu_cxx
00380 
00381 namespace std
00382 {
00383 // Specialization of insert_iterator so that it will work for hash_map
00384 // and hash_multimap.
00385 
00386 template <class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
00387 class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> > {
00388 protected:
00389   typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container;
00390   _Container* container;
00391 public:
00392   typedef _Container          container_type;
00393   typedef output_iterator_tag iterator_category;
00394   typedef void                value_type;
00395   typedef void                difference_type;
00396   typedef void                pointer;
00397   typedef void                reference;
00398 
00399   insert_iterator(_Container& __x) : container(&__x) {}
00400   insert_iterator(_Container& __x, typename _Container::iterator)
00401     : container(&__x) {}
00402   insert_iterator<_Container>&
00403   operator=(const typename _Container::value_type& __value) { 
00404     container->insert(__value);
00405     return *this;
00406   }
00407   insert_iterator<_Container>& operator*() { return *this; }
00408   insert_iterator<_Container>& operator++() { return *this; }
00409   insert_iterator<_Container>& operator++(int) { return *this; }
00410 };
00411 
00412 template <class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
00413 class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> > {
00414 protected:
00415   typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container;
00416   _Container* container;
00417   typename _Container::iterator iter;
00418 public:
00419   typedef _Container          container_type;
00420   typedef output_iterator_tag iterator_category;
00421   typedef void                value_type;
00422   typedef void                difference_type;
00423   typedef void                pointer;
00424   typedef void                reference;
00425 
00426   insert_iterator(_Container& __x) : container(&__x) {}
00427   insert_iterator(_Container& __x, typename _Container::iterator)
00428     : container(&__x) {}
00429   insert_iterator<_Container>&
00430   operator=(const typename _Container::value_type& __value) { 
00431     container->insert(__value);
00432     return *this;
00433   }
00434   insert_iterator<_Container>& operator*() { return *this; }
00435   insert_iterator<_Container>& operator++() { return *this; }
00436   insert_iterator<_Container>& operator++(int) { return *this; }
00437 };
00438 
00439 } // namespace std
00440 
00441 #endif /* __SGI_STL_INTERNAL_HASH_MAP_H */
00442 
00443 // Local Variables:
00444 // mode:C++
00445 // End:

Generated on Wed May 1 19:19:31 2002 for libstdc++-v3 Source by doxygen1.2.15