# hash_set

Go to the documentation of this file.

    00001 // Hashing set implementation -*- C++ -*-
    00002
    00003 // Copyright (C) 2001, 2002, 2004 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
    00056 /** @file ext/hash_set
    00057  *  This file is a GNU extension to the Standard C++ Library (possibly
    00058  *  containing extensions from the HP/SGI STL subset).
    00059  */
    00060
    00061 #ifndef _HASH_SET
    00062 #define _HASH_SET 1
    00063
    00064 #include <ext/hashtable.h>
    00065 #include <bits/concept_check.h>
    00066
    00067 namespace __gnu_cxx
    00068 {
    00069   using std::equal_to;
    00070   using std::allocator;
    00071   using std::pair;
    00072   using std::_Identity;
    00073
    00074   // Forward declaration of equality operator; needed for friend
    00075   // declaration.
    00076   template <class _Value, class _HashFcn  = hash<_Value>,
    00077         class _EqualKey = equal_to<_Value>,
    00078         class _Alloc = allocator<_Value> >
    00079     class hash_set;
    00080
    00081   template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    00082     inline bool
    00083     operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
    00084            const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2);
    00085
    00086   /**
    00087    *  This is an SGI extension.
    00088    *  @ingroup SGIextensions
    00089    *  @doctodo
    00090    */
    00091   template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    00092     class hash_set
    00093     {
    00094       // concept requirements
    00095       __glibcxx_class_requires(_Value, _SGIAssignableConcept)
    00096       __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
    00097       __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
    00098
    00099     private:
    00100       typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
    00101             _EqualKey, _Alloc> _Ht;
    00102       _Ht _M_ht;
    00103
    00104     public:
    00105       typedef typename _Ht::key_type key_type;
    00106       typedef typename _Ht::value_type value_type;
    00107       typedef typename _Ht::hasher hasher;
    00108       typedef typename _Ht::key_equal key_equal;
    00109
    00110       typedef typename _Ht::size_type size_type;
    00111       typedef typename _Ht::difference_type difference_type;
    00112       typedef typename _Alloc::pointer pointer;
    00113       typedef typename _Alloc::const_pointer const_pointer;
    00114       typedef typename _Alloc::reference reference;
    00115       typedef typename _Alloc::const_reference const_reference;
    00116
    00117       typedef typename _Ht::const_iterator iterator;
    00118       typedef typename _Ht::const_iterator const_iterator;
    00119
    00120       typedef typename _Ht::allocator_type allocator_type;
    00121
    00122       hasher
    00123       hash_funct() const
    00124       { return _M_ht.hash_funct(); }
    00125
    00126       key_equal
    00127       key_eq() const
    00128       { return _M_ht.key_eq(); }
    00129
    00130       allocator_type
    00131       get_allocator() const
    00132       { return _M_ht.get_allocator(); }
    00133
    00134     public:
    00135       hash_set()
    00136       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
    00137
    00138       explicit
    00139       hash_set(size_type __n)
    00140       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
    00141
    00142       hash_set(size_type __n, const hasher& __hf)
    00143       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
    00144
    00145       hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
    00146            const allocator_type& __a = allocator_type())
    00147       : _M_ht(__n, __hf, __eql, __a) {}
    00148
    00149       template <class _InputIterator>
    00150         hash_set(_InputIterator __f, _InputIterator __l)
    00151     : _M_ht(100, hasher(), key_equal(), allocator_type())
    00152         { _M_ht.insert_unique(__f, __l); }
    00153
    00154       template <class _InputIterator>
    00155         hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
    00156     : _M_ht(__n, hasher(), key_equal(), allocator_type())
    00157         { _M_ht.insert_unique(__f, __l); }
    00158
    00159       template <class _InputIterator>
    00160         hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
    00161          const hasher& __hf)
    00162     : _M_ht(__n, __hf, key_equal(), allocator_type())
    00163         { _M_ht.insert_unique(__f, __l); }
    00164
    00165       template <class _InputIterator>
    00166         hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
    00167          const hasher& __hf, const key_equal& __eql,
    00168          const allocator_type& __a = allocator_type())
    00169     : _M_ht(__n, __hf, __eql, __a)
    00170         { _M_ht.insert_unique(__f, __l); }
    00171
    00172     public:
    00173       size_type
    00174       size() const
    00175       { return _M_ht.size(); }
    00176
    00177       size_type
    00178       max_size() const
    00179       { return _M_ht.max_size(); }
    00180
    00181       bool
    00182       empty() const
    00183       { return _M_ht.empty(); }
    00184
    00185       void
    00186       swap(hash_set& __hs)
    00187       { _M_ht.swap(__hs._M_ht); }
    00188
    00189       template <class _Val, class _HF, class _EqK, class _Al>
    00190         friend bool
    00191         operator==(const hash_set<_Val, _HF, _EqK, _Al>&,
    00192            const hash_set<_Val, _HF, _EqK, _Al>&);
    00193
    00194       iterator
    00195       begin() const
    00196       { return _M_ht.begin(); }
    00197
    00198       iterator
    00199       end() const
    00200       { return _M_ht.end(); }
    00201
    00202     public:
    00203       pair<iterator, bool>
    00204       insert(const value_type& __obj)
    00205       {
    00206     pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj);
    00207     return pair<iterator,bool>(__p.first, __p.second);
    00208       }
    00209
    00210       template <class _InputIterator>
    00211         void
    00212         insert(_InputIterator __f, _InputIterator __l)
    00213         { _M_ht.insert_unique(__f, __l); }
    00214
    00215       pair<iterator, bool>
    00216       insert_noresize(const value_type& __obj)
    00217       {
    00218     pair<typename _Ht::iterator, bool> __p
    00219       = _M_ht.insert_unique_noresize(__obj);
    00220     return pair<iterator, bool>(__p.first, __p.second);
    00221       }
    00222
    00223       iterator
    00224       find(const key_type& __key) const
    00225       { return _M_ht.find(__key); }
    00226
    00227       size_type
    00228       count(const key_type& __key) const
    00229       { return _M_ht.count(__key); }
    00230
    00231       pair<iterator, iterator>
    00232       equal_range(const key_type& __key) const
    00233       { return _M_ht.equal_range(__key); }
    00234
    00235       size_type
    00236       erase(const key_type& __key)
    00237       {return _M_ht.erase(__key); }
    00238
    00239       void
    00240       erase(iterator __it)
    00241       { _M_ht.erase(__it); }
    00242
    00243       void
    00244       erase(iterator __f, iterator __l)
    00245       { _M_ht.erase(__f, __l); }
    00246
    00247       void
    00248       clear()
    00249       { _M_ht.clear(); }
    00250
    00251 public:
    00252       void
    00253       resize(size_type __hint)
    00254       { _M_ht.resize(__hint); }
    00255
    00256       size_type
    00257       bucket_count() const
    00258       { return _M_ht.bucket_count(); }
    00259
    00260       size_type
    00261       max_bucket_count() const
    00262       { return _M_ht.max_bucket_count(); }
    00263
    00264       size_type
    00265       elems_in_bucket(size_type __n) const
    00266       { return _M_ht.elems_in_bucket(__n); }
    00267     };
    00268
    00269   template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    00270     inline bool
    00271     operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
    00272            const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
    00273     { return __hs1._M_ht == __hs2._M_ht; }
    00274
    00275   template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    00276     inline bool
    00277     operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
    00278            const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
    00279     { return !(__hs1 == __hs2); }
    00280
    00281   template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
    00282     inline void
    00283     swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
    00284      hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
    00285     { __hs1.swap(__hs2); }
    00286
    00287   template <class _Value,
    00288         class _HashFcn = hash<_Value>,
    00289         class _EqualKey = equal_to<_Value>,
    00290         class _Alloc = allocator<_Value> >
    00291     class hash_multiset;
    00292
    00293   template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
    00294     inline bool
    00295     operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
    00296            const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2);
    00297
    00298
    00299   /**
    00300    *  This is an SGI extension.
    00301    *  @ingroup SGIextensions
    00302    *  @doctodo
    00303    */
    00304   template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    00305     class hash_multiset
    00306     {
    00307       // concept requirements
    00308       __glibcxx_class_requires(_Value, _SGIAssignableConcept)
    00309       __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
    00310       __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
    00311
    00312     private:
    00313       typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
    00314             _EqualKey, _Alloc> _Ht;
    00315       _Ht _M_ht;
    00316
    00317     public:
    00318       typedef typename _Ht::key_type key_type;
    00319       typedef typename _Ht::value_type value_type;
    00320       typedef typename _Ht::hasher hasher;
    00321       typedef typename _Ht::key_equal key_equal;
    00322
    00323       typedef typename _Ht::size_type size_type;
    00324       typedef typename _Ht::difference_type difference_type;
    00325       typedef typename _Alloc::pointer pointer;
    00326       typedef typename _Alloc::const_pointer const_pointer;
    00327       typedef typename _Alloc::reference reference;
    00328       typedef typename _Alloc::const_reference const_reference;
    00329
    00330       typedef typename _Ht::const_iterator iterator;
    00331       typedef typename _Ht::const_iterator const_iterator;
    00332
    00333       typedef typename _Ht::allocator_type allocator_type;
    00334
    00335       hasher
    00336       hash_funct() const
    00337       { return _M_ht.hash_funct(); }
    00338
    00339       key_equal
    00340       key_eq() const
    00341       { return _M_ht.key_eq(); }
    00342
    00343       allocator_type
    00344       get_allocator() const
    00345       { return _M_ht.get_allocator(); }
    00346
    00347     public:
    00348       hash_multiset()
    00349       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
    00350
    00351       explicit
    00352       hash_multiset(size_type __n)
    00353       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
    00354
    00355       hash_multiset(size_type __n, const hasher& __hf)
    00356       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
    00357
    00358       hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
    00359             const allocator_type& __a = allocator_type())
    00360       : _M_ht(__n, __hf, __eql, __a) {}
    00361
    00362       template <class _InputIterator>
    00363         hash_multiset(_InputIterator __f, _InputIterator __l)
    00364     : _M_ht(100, hasher(), key_equal(), allocator_type())
    00365         { _M_ht.insert_equal(__f, __l); }
    00366
    00367       template <class _InputIterator>
    00368         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
    00369     : _M_ht(__n, hasher(), key_equal(), allocator_type())
    00370         { _M_ht.insert_equal(__f, __l); }
    00371
    00372       template <class _InputIterator>
    00373         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
    00374               const hasher& __hf)
    00375     : _M_ht(__n, __hf, key_equal(), allocator_type())
    00376         { _M_ht.insert_equal(__f, __l); }
    00377
    00378       template <class _InputIterator>
    00379         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
    00380               const hasher& __hf, const key_equal& __eql,
    00381               const allocator_type& __a = allocator_type())
    00382     : _M_ht(__n, __hf, __eql, __a)
    00383         { _M_ht.insert_equal(__f, __l); }
    00384
    00385     public:
    00386       size_type
    00387       size() const
    00388       { return _M_ht.size(); }
    00389
    00390       size_type
    00391       max_size() const
    00392       { return _M_ht.max_size(); }
    00393
    00394       bool
    00395       empty() const
    00396       { return _M_ht.empty(); }
    00397
    00398       void
    00399       swap(hash_multiset& hs)
    00400       { _M_ht.swap(hs._M_ht); }
    00401
    00402       template <class _Val, class _HF, class _EqK, class _Al>
    00403         friend bool
    00404         operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&,
    00405            const hash_multiset<_Val, _HF, _EqK, _Al>&);
    00406
    00407       iterator
    00408       begin() const
    00409       { return _M_ht.begin(); }
    00410
    00411       iterator
    00412       end() const
    00413       { return _M_ht.end(); }
    00414
    00415 public:
    00416       iterator
    00417       insert(const value_type& __obj)
    00418       { return _M_ht.insert_equal(__obj); }
    00419
    00420       template <class _InputIterator>
    00421         void
    00422         insert(_InputIterator __f, _InputIterator __l)
    00423         { _M_ht.insert_equal(__f,__l); }
    00424
    00425       iterator
    00426       insert_noresize(const value_type& __obj)
    00427       { return _M_ht.insert_equal_noresize(__obj); }
    00428
    00429       iterator
    00430       find(const key_type& __key) const
    00431       { return _M_ht.find(__key); }
    00432
    00433       size_type
    00434       count(const key_type& __key) const
    00435       { return _M_ht.count(__key); }
    00436
    00437       pair<iterator, iterator>
    00438       equal_range(const key_type& __key) const
    00439       { return _M_ht.equal_range(__key); }
    00440
    00441       size_type
    00442       erase(const key_type& __key)
    00443       { return _M_ht.erase(__key); }
    00444
    00445       void
    00446       erase(iterator __it)
    00447       { _M_ht.erase(__it); }
    00448
    00449       void
    00450       erase(iterator __f, iterator __l)
    00451       { _M_ht.erase(__f, __l); }
    00452
    00453       void
    00454       clear()
    00455       { _M_ht.clear(); }
    00456
    00457     public:
    00458       void
    00459       resize(size_type __hint)
    00460       { _M_ht.resize(__hint); }
    00461
    00462       size_type
    00463       bucket_count() const
    00464       { return _M_ht.bucket_count(); }
    00465
    00466       size_type
    00467       max_bucket_count() const
    00468       { return _M_ht.max_bucket_count(); }
    00469
    00470       size_type
    00471       elems_in_bucket(size_type __n) const
    00472       { return _M_ht.elems_in_bucket(__n); }
    00473     };
    00474
    00475   template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
    00476     inline bool
    00477     operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
    00478            const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
    00479     { return __hs1._M_ht == __hs2._M_ht; }
    00480
    00481   template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
    00482     inline bool
    00483     operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
    00484            const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
    00485     { return !(__hs1 == __hs2); }
    00486
    00487   template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
    00488     inline void
    00489     swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
    00490      hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
    00491     { __hs1.swap(__hs2); }
    00492
    00493 } // namespace __gnu_cxx
    00494
    00495 namespace std
    00496 {
    00497   // Specialization of insert_iterator so that it will work for hash_set
    00498   // and hash_multiset.
    00499
    00500   template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    00501     class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn,
    00502                           _EqualKey, _Alloc> >
    00503     {
    00504     protected:
    00505       typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>
    00506         _Container;
    00507       _Container* container;
    00508
    00509     public:
    00510       typedef _Container          container_type;
    00511       typedef output_iterator_tag iterator_category;
    00512       typedef void                value_type;
    00513       typedef void                difference_type;
    00514       typedef void                pointer;
    00515       typedef void                reference;
    00516
    00517       insert_iterator(_Container& __x)
    00518       : container(&__x) {}
    00519
    00520       insert_iterator(_Container& __x, typename _Container::iterator)
    00521       : container(&__x) {}
    00522
    00523       insert_iterator<_Container>&
    00524       operator=(const typename _Container::value_type& __value)
    00525       {
    00526     container->insert(__value);
    00527     return *this;
    00528       }
    00529
    00530       insert_iterator<_Container>&
    00531       operator*()
    00532       { return *this; }
    00533
    00534       insert_iterator<_Container>&
    00535       operator++()
    00536       { return *this; }
    00537
    00538       insert_iterator<_Container>&
    00539       operator++(int)
    00540       { return *this; }
    00541     };
    00542
    00543   template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    00544     class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn,
    00545                            _EqualKey, _Alloc> >
    00546     {
    00547     protected:
    00548       typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>
    00549         _Container;
    00550       _Container* container;
    00551       typename _Container::iterator iter;
    00552
    00553     public:
    00554       typedef _Container          container_type;
    00555       typedef output_iterator_tag iterator_category;
    00556       typedef void                value_type;
    00557       typedef void                difference_type;
    00558       typedef void                pointer;
    00559       typedef void                reference;
    00560
    00561       insert_iterator(_Container& __x)
    00562       : container(&__x) {}
    00563
    00564       insert_iterator(_Container& __x, typename _Container::iterator)
    00565       : container(&__x) {}
    00566
    00567       insert_iterator<_Container>&
    00568       operator=(const typename _Container::value_type& __value)
    00569       {
    00570     container->insert(__value);
    00571     return *this;
    00572       }
    00573
    00574       insert_iterator<_Container>&
    00575       operator*()
    00576       { return *this; }
    00577
    00578       insert_iterator<_Container>&
    00579       operator++()
    00580       { return *this; }
    00581
    00582       insert_iterator<_Container>&
    00583       operator++(int) { return *this; }
    00584     };
    00585 } // namespace std
    00586 #endif