hash_set

Go to the documentation of this file.
00001 // Hashing set implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2004, 2005, 2006, 2009, 2010
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /*
00027  * Copyright (c) 1996
00028  * Silicon Graphics Computer Systems, Inc.
00029  *
00030  * Permission to use, copy, modify, distribute and sell this software
00031  * and its documentation for any purpose is hereby granted without fee,
00032  * provided that the above copyright notice appear in all copies and
00033  * that both that copyright notice and this permission notice appear
00034  * in supporting documentation.  Silicon Graphics makes no
00035  * representations about the suitability of this software for any
00036  * purpose.  It is provided "as is" without express or implied warranty.
00037  *
00038  *
00039  * Copyright (c) 1994
00040  * Hewlett-Packard Company
00041  *
00042  * Permission to use, copy, modify, distribute and sell this software
00043  * and its documentation for any purpose is hereby granted without fee,
00044  * provided that the above copyright notice appear in all copies and
00045  * that both that copyright notice and this permission notice appear
00046  * in supporting documentation.  Hewlett-Packard Company makes no
00047  * representations about the suitability of this software for any
00048  * purpose.  It is provided "as is" without express or implied warranty.
00049  *
00050  */
00051 
00052 /** @file backward/hash_set
00053  *  This file is a GNU extension to the Standard C++ Library (possibly
00054  *  containing extensions from the HP/SGI STL subset).
00055  */
00056 
00057 #ifndef _BACKWARD_HASH_SET
00058 #define _BACKWARD_HASH_SET 1
00059 
00060 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
00061 #include "backward_warning.h"
00062 #endif
00063 
00064 #include <bits/c++config.h>
00065 #include <backward/hashtable.h>
00066 #include <bits/concept_check.h>
00067 
00068 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
00069 
00070   using std::equal_to;
00071   using std::allocator;
00072   using std::pair;
00073   using std::_Identity;
00074 
00075   /**
00076    *  This is an SGI extension.
00077    *  @ingroup SGIextensions
00078    *  @doctodo
00079    */
00080   template<class _Value, class _HashFcn  = hash<_Value>,
00081        class _EqualKey = equal_to<_Value>,
00082        class _Alloc = allocator<_Value> >
00083     class hash_set
00084     {
00085       // concept requirements
00086       __glibcxx_class_requires(_Value, _SGIAssignableConcept)
00087       __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
00088       __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
00089 
00090     private:
00091       typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
00092             _EqualKey, _Alloc> _Ht;
00093       _Ht _M_ht;
00094 
00095     public:
00096       typedef typename _Ht::key_type key_type;
00097       typedef typename _Ht::value_type value_type;
00098       typedef typename _Ht::hasher hasher;
00099       typedef typename _Ht::key_equal key_equal;
00100       
00101       typedef typename _Ht::size_type size_type;
00102       typedef typename _Ht::difference_type difference_type;
00103       typedef typename _Alloc::pointer pointer;
00104       typedef typename _Alloc::const_pointer const_pointer;
00105       typedef typename _Alloc::reference reference;
00106       typedef typename _Alloc::const_reference const_reference;
00107       
00108       typedef typename _Ht::const_iterator iterator;
00109       typedef typename _Ht::const_iterator const_iterator;
00110       
00111       typedef typename _Ht::allocator_type allocator_type;
00112       
00113       hasher
00114       hash_funct() const
00115       { return _M_ht.hash_funct(); }
00116 
00117       key_equal
00118       key_eq() const
00119       { return _M_ht.key_eq(); }
00120 
00121       allocator_type
00122       get_allocator() const
00123       { return _M_ht.get_allocator(); }
00124 
00125       hash_set()
00126       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
00127 
00128       explicit
00129       hash_set(size_type __n)
00130       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
00131 
00132       hash_set(size_type __n, const hasher& __hf)
00133       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
00134 
00135       hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
00136            const allocator_type& __a = allocator_type())
00137       : _M_ht(__n, __hf, __eql, __a) {}
00138 
00139       template<class _InputIterator>
00140         hash_set(_InputIterator __f, _InputIterator __l)
00141     : _M_ht(100, hasher(), key_equal(), allocator_type())
00142         { _M_ht.insert_unique(__f, __l); }
00143 
00144       template<class _InputIterator>
00145         hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
00146     : _M_ht(__n, hasher(), key_equal(), allocator_type())
00147         { _M_ht.insert_unique(__f, __l); }
00148 
00149       template<class _InputIterator>
00150         hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
00151          const hasher& __hf)
00152     : _M_ht(__n, __hf, key_equal(), allocator_type())
00153         { _M_ht.insert_unique(__f, __l); }
00154 
00155       template<class _InputIterator>
00156         hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
00157          const hasher& __hf, const key_equal& __eql,
00158          const allocator_type& __a = allocator_type())
00159     : _M_ht(__n, __hf, __eql, __a)
00160         { _M_ht.insert_unique(__f, __l); }
00161 
00162       size_type
00163       size() const
00164       { return _M_ht.size(); }
00165 
00166       size_type
00167       max_size() const
00168       { return _M_ht.max_size(); }
00169       
00170       bool
00171       empty() const
00172       { return _M_ht.empty(); }
00173       
00174       void
00175       swap(hash_set& __hs)
00176       { _M_ht.swap(__hs._M_ht); }
00177 
00178       template<class _Val, class _HF, class _EqK, class _Al>
00179         friend bool
00180         operator==(const hash_set<_Val, _HF, _EqK, _Al>&,
00181            const hash_set<_Val, _HF, _EqK, _Al>&);
00182 
00183       iterator
00184       begin() const
00185       { return _M_ht.begin(); }
00186       
00187       iterator
00188       end() const
00189       { return _M_ht.end(); }
00190 
00191       pair<iterator, bool>
00192       insert(const value_type& __obj)
00193       {
00194     pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj);
00195     return pair<iterator,bool>(__p.first, __p.second);
00196       }
00197 
00198       template<class _InputIterator>
00199         void
00200         insert(_InputIterator __f, _InputIterator __l)
00201         { _M_ht.insert_unique(__f, __l); }
00202 
00203       pair<iterator, bool>
00204       insert_noresize(const value_type& __obj)
00205       {
00206     pair<typename _Ht::iterator, bool> __p
00207       = _M_ht.insert_unique_noresize(__obj);
00208     return pair<iterator, bool>(__p.first, __p.second);
00209       }
00210 
00211       iterator
00212       find(const key_type& __key) const
00213       { return _M_ht.find(__key); }
00214 
00215       size_type
00216       count(const key_type& __key) const
00217       { return _M_ht.count(__key); }
00218 
00219       pair<iterator, iterator>
00220       equal_range(const key_type& __key) const
00221       { return _M_ht.equal_range(__key); }
00222 
00223       size_type
00224       erase(const key_type& __key)
00225       {return _M_ht.erase(__key); }
00226       
00227       void
00228       erase(iterator __it)
00229       { _M_ht.erase(__it); }
00230       
00231       void
00232       erase(iterator __f, iterator __l)
00233       { _M_ht.erase(__f, __l); }
00234       
00235       void
00236       clear()
00237       { _M_ht.clear(); }
00238 
00239       void
00240       resize(size_type __hint)
00241       { _M_ht.resize(__hint); }
00242       
00243       size_type
00244       bucket_count() const
00245       { return _M_ht.bucket_count(); }
00246       
00247       size_type
00248       max_bucket_count() const
00249       { return _M_ht.max_bucket_count(); }
00250       
00251       size_type
00252       elems_in_bucket(size_type __n) const
00253       { return _M_ht.elems_in_bucket(__n); }
00254     };
00255 
00256   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
00257     inline bool
00258     operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
00259            const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
00260     { return __hs1._M_ht == __hs2._M_ht; }
00261 
00262   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
00263     inline bool
00264     operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
00265            const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
00266     { return !(__hs1 == __hs2); }
00267 
00268   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
00269     inline void
00270     swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
00271      hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
00272     { __hs1.swap(__hs2); }
00273 
00274 
00275   /**
00276    *  This is an SGI extension.
00277    *  @ingroup SGIextensions
00278    *  @doctodo
00279    */
00280   template<class _Value,
00281        class _HashFcn = hash<_Value>,
00282        class _EqualKey = equal_to<_Value>,
00283        class _Alloc = allocator<_Value> >
00284     class hash_multiset
00285     {
00286       // concept requirements
00287       __glibcxx_class_requires(_Value, _SGIAssignableConcept)
00288       __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
00289       __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
00290 
00291     private:
00292       typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
00293             _EqualKey, _Alloc> _Ht;
00294       _Ht _M_ht;
00295 
00296     public:
00297       typedef typename _Ht::key_type key_type;
00298       typedef typename _Ht::value_type value_type;
00299       typedef typename _Ht::hasher hasher;
00300       typedef typename _Ht::key_equal key_equal;
00301       
00302       typedef typename _Ht::size_type size_type;
00303       typedef typename _Ht::difference_type difference_type;
00304       typedef typename _Alloc::pointer pointer;
00305       typedef typename _Alloc::const_pointer const_pointer;
00306       typedef typename _Alloc::reference reference;
00307       typedef typename _Alloc::const_reference const_reference;
00308 
00309       typedef typename _Ht::const_iterator iterator;
00310       typedef typename _Ht::const_iterator const_iterator;
00311       
00312       typedef typename _Ht::allocator_type allocator_type;
00313       
00314       hasher
00315       hash_funct() const
00316       { return _M_ht.hash_funct(); }
00317       
00318       key_equal
00319       key_eq() const
00320       { return _M_ht.key_eq(); }
00321       
00322       allocator_type
00323       get_allocator() const
00324       { return _M_ht.get_allocator(); }
00325 
00326       hash_multiset()
00327       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
00328 
00329       explicit
00330       hash_multiset(size_type __n)
00331       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
00332 
00333       hash_multiset(size_type __n, const hasher& __hf)
00334       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
00335       
00336       hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
00337             const allocator_type& __a = allocator_type())
00338       : _M_ht(__n, __hf, __eql, __a) {}
00339 
00340       template<class _InputIterator>
00341         hash_multiset(_InputIterator __f, _InputIterator __l)
00342     : _M_ht(100, hasher(), key_equal(), allocator_type())
00343         { _M_ht.insert_equal(__f, __l); }
00344 
00345       template<class _InputIterator>
00346         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
00347     : _M_ht(__n, hasher(), key_equal(), allocator_type())
00348         { _M_ht.insert_equal(__f, __l); }
00349 
00350       template<class _InputIterator>
00351         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
00352               const hasher& __hf)
00353     : _M_ht(__n, __hf, key_equal(), allocator_type())
00354         { _M_ht.insert_equal(__f, __l); }
00355 
00356       template<class _InputIterator>
00357         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
00358               const hasher& __hf, const key_equal& __eql,
00359               const allocator_type& __a = allocator_type())
00360     : _M_ht(__n, __hf, __eql, __a)
00361         { _M_ht.insert_equal(__f, __l); }
00362 
00363       size_type
00364       size() const
00365       { return _M_ht.size(); }
00366 
00367       size_type
00368       max_size() const
00369       { return _M_ht.max_size(); }
00370 
00371       bool
00372       empty() const
00373       { return _M_ht.empty(); }
00374 
00375       void
00376       swap(hash_multiset& hs)
00377       { _M_ht.swap(hs._M_ht); }
00378 
00379       template<class _Val, class _HF, class _EqK, class _Al>
00380         friend bool
00381         operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&,
00382            const hash_multiset<_Val, _HF, _EqK, _Al>&);
00383 
00384       iterator
00385       begin() const
00386       { return _M_ht.begin(); }
00387       
00388       iterator
00389       end() const
00390       { return _M_ht.end(); }
00391 
00392       iterator
00393       insert(const value_type& __obj)
00394       { return _M_ht.insert_equal(__obj); }
00395   
00396       template<class _InputIterator>
00397         void
00398         insert(_InputIterator __f, _InputIterator __l)
00399         { _M_ht.insert_equal(__f,__l); }
00400   
00401       iterator
00402       insert_noresize(const value_type& __obj)
00403       { return _M_ht.insert_equal_noresize(__obj); }
00404 
00405       iterator
00406       find(const key_type& __key) const
00407       { return _M_ht.find(__key); }
00408 
00409       size_type
00410       count(const key_type& __key) const
00411       { return _M_ht.count(__key); }
00412 
00413       pair<iterator, iterator>
00414       equal_range(const key_type& __key) const
00415       { return _M_ht.equal_range(__key); }
00416 
00417       size_type
00418       erase(const key_type& __key)
00419       { return _M_ht.erase(__key); }
00420   
00421       void
00422       erase(iterator __it)
00423       { _M_ht.erase(__it); }
00424   
00425       void
00426       erase(iterator __f, iterator __l)
00427       { _M_ht.erase(__f, __l); }
00428   
00429       void
00430       clear()
00431       { _M_ht.clear(); }
00432 
00433       void
00434       resize(size_type __hint)
00435       { _M_ht.resize(__hint); }
00436   
00437       size_type
00438       bucket_count() const
00439       { return _M_ht.bucket_count(); }
00440 
00441       size_type
00442       max_bucket_count() const
00443       { return _M_ht.max_bucket_count(); }
00444 
00445       size_type
00446       elems_in_bucket(size_type __n) const
00447       { return _M_ht.elems_in_bucket(__n); }
00448     };
00449 
00450   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
00451     inline bool
00452     operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
00453            const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
00454     { return __hs1._M_ht == __hs2._M_ht; }
00455 
00456   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
00457     inline bool
00458     operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
00459            const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
00460     { return !(__hs1 == __hs2); }
00461 
00462   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
00463     inline void
00464     swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
00465      hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
00466     { __hs1.swap(__hs2); }
00467 
00468 _GLIBCXX_END_NAMESPACE
00469 
00470 _GLIBCXX_BEGIN_NAMESPACE(std)
00471 
00472   // Specialization of insert_iterator so that it will work for hash_set
00473   // and hash_multiset.
00474   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
00475     class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn,
00476                           _EqualKey, _Alloc> >
00477     {
00478     protected:
00479       typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>
00480         _Container;
00481       _Container* container;
00482 
00483     public:
00484       typedef _Container          container_type;
00485       typedef output_iterator_tag iterator_category;
00486       typedef void                value_type;
00487       typedef void                difference_type;
00488       typedef void                pointer;
00489       typedef void                reference;
00490 
00491       insert_iterator(_Container& __x)
00492       : container(&__x) {}
00493       
00494       insert_iterator(_Container& __x, typename _Container::iterator)
00495       : container(&__x) {}
00496 
00497       insert_iterator<_Container>&
00498       operator=(const typename _Container::value_type& __value)
00499       {
00500     container->insert(__value);
00501     return *this;
00502       }
00503 
00504       insert_iterator<_Container>&
00505       operator*()
00506       { return *this; }
00507       
00508       insert_iterator<_Container>&
00509       operator++()
00510       { return *this; }
00511       
00512       insert_iterator<_Container>&
00513       operator++(int)
00514       { return *this; }
00515     };
00516 
00517   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
00518     class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn,
00519                            _EqualKey, _Alloc> >
00520     {
00521     protected:
00522       typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>
00523         _Container;
00524       _Container* container;
00525       typename _Container::iterator iter;
00526 
00527     public:
00528       typedef _Container          container_type;
00529       typedef output_iterator_tag iterator_category;
00530       typedef void                value_type;
00531       typedef void                difference_type;
00532       typedef void                pointer;
00533       typedef void                reference;
00534       
00535       insert_iterator(_Container& __x)
00536       : container(&__x) {}
00537       
00538       insert_iterator(_Container& __x, typename _Container::iterator)
00539       : container(&__x) {}
00540 
00541       insert_iterator<_Container>&
00542       operator=(const typename _Container::value_type& __value)
00543       {
00544     container->insert(__value);
00545     return *this;
00546       }
00547 
00548       insert_iterator<_Container>&
00549       operator*()
00550       { return *this; }
00551 
00552       insert_iterator<_Container>&
00553       operator++()
00554       { return *this; }
00555 
00556       insert_iterator<_Container>&
00557       operator++(int) { return *this; }
00558     };
00559 
00560 _GLIBCXX_END_NAMESPACE
00561 
00562 #endif