hash_set

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

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