# 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: