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