00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
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 
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 
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   
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 } 
00380 
00381 namespace std
00382 {
00383 
00384 
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 } 
00440 
00441 #endif 
00442 
00443 
00444 
00445