Home | History | Annotate | Download | only in backward
      1 // Hashing set implementation -*- C++ -*-
      2 
      3 // Copyright (C) 2001, 2002, 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /*
     26  * Copyright (c) 1996
     27  * Silicon Graphics Computer Systems, Inc.
     28  *
     29  * Permission to use, copy, modify, distribute and sell this software
     30  * and its documentation for any purpose is hereby granted without fee,
     31  * provided that the above copyright notice appear in all copies and
     32  * that both that copyright notice and this permission notice appear
     33  * in supporting documentation.  Silicon Graphics makes no
     34  * representations about the suitability of this software for any
     35  * purpose.  It is provided "as is" without express or implied warranty.
     36  *
     37  *
     38  * Copyright (c) 1994
     39  * Hewlett-Packard Company
     40  *
     41  * Permission to use, copy, modify, distribute and sell this software
     42  * and its documentation for any purpose is hereby granted without fee,
     43  * provided that the above copyright notice appear in all copies and
     44  * that both that copyright notice and this permission notice appear
     45  * in supporting documentation.  Hewlett-Packard Company makes no
     46  * representations about the suitability of this software for any
     47  * purpose.  It is provided "as is" without express or implied warranty.
     48  *
     49  */
     50 
     51 /** @file backward/hash_set
     52  *  This file is a GNU extension to the Standard C++ Library (possibly
     53  *  containing extensions from the HP/SGI STL subset).
     54  */
     55 
     56 #ifndef _HASH_SET
     57 #define _HASH_SET 1
     58 
     59 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
     60 #include "backward_warning.h"
     61 #endif
     62 
     63 #include <bits/c++config.h>
     64 #include <backward/hashtable.h>
     65 #include <bits/concept_check.h>
     66 
     67 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
     68 
     69   using std::equal_to;
     70   using std::allocator;
     71   using std::pair;
     72   using std::_Identity;
     73 
     74   /**
     75    *  This is an SGI extension.
     76    *  @ingroup SGIextensions
     77    *  @doctodo
     78    */
     79   template<class _Value, class _HashFcn  = hash<_Value>,
     80 	   class _EqualKey = equal_to<_Value>,
     81 	   class _Alloc = allocator<_Value> >
     82     class hash_set
     83     {
     84       // concept requirements
     85       __glibcxx_class_requires(_Value, _SGIAssignableConcept)
     86       __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
     87       __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
     88 
     89     private:
     90       typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
     91 			_EqualKey, _Alloc> _Ht;
     92       _Ht _M_ht;
     93 
     94     public:
     95       typedef typename _Ht::key_type key_type;
     96       typedef typename _Ht::value_type value_type;
     97       typedef typename _Ht::hasher hasher;
     98       typedef typename _Ht::key_equal key_equal;
     99       
    100       typedef typename _Ht::size_type size_type;
    101       typedef typename _Ht::difference_type difference_type;
    102       typedef typename _Alloc::pointer pointer;
    103       typedef typename _Alloc::const_pointer const_pointer;
    104       typedef typename _Alloc::reference reference;
    105       typedef typename _Alloc::const_reference const_reference;
    106       
    107       typedef typename _Ht::const_iterator iterator;
    108       typedef typename _Ht::const_iterator const_iterator;
    109       
    110       typedef typename _Ht::allocator_type allocator_type;
    111       
    112       hasher
    113       hash_funct() const
    114       { return _M_ht.hash_funct(); }
    115 
    116       key_equal
    117       key_eq() const
    118       { return _M_ht.key_eq(); }
    119 
    120       allocator_type
    121       get_allocator() const
    122       { return _M_ht.get_allocator(); }
    123 
    124       hash_set()
    125       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
    126 
    127       explicit
    128       hash_set(size_type __n)
    129       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
    130 
    131       hash_set(size_type __n, const hasher& __hf)
    132       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
    133 
    134       hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
    135 	       const allocator_type& __a = allocator_type())
    136       : _M_ht(__n, __hf, __eql, __a) {}
    137 
    138       template<class _InputIterator>
    139         hash_set(_InputIterator __f, _InputIterator __l)
    140 	: _M_ht(100, hasher(), key_equal(), allocator_type())
    141         { _M_ht.insert_unique(__f, __l); }
    142 
    143       template<class _InputIterator>
    144         hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
    145 	: _M_ht(__n, hasher(), key_equal(), allocator_type())
    146         { _M_ht.insert_unique(__f, __l); }
    147 
    148       template<class _InputIterator>
    149         hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
    150 		 const hasher& __hf)
    151 	: _M_ht(__n, __hf, key_equal(), allocator_type())
    152         { _M_ht.insert_unique(__f, __l); }
    153 
    154       template<class _InputIterator>
    155         hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
    156 		 const hasher& __hf, const key_equal& __eql,
    157 		 const allocator_type& __a = allocator_type())
    158 	: _M_ht(__n, __hf, __eql, __a)
    159         { _M_ht.insert_unique(__f, __l); }
    160 
    161       size_type
    162       size() const
    163       { return _M_ht.size(); }
    164 
    165       size_type
    166       max_size() const
    167       { return _M_ht.max_size(); }
    168       
    169       bool
    170       empty() const
    171       { return _M_ht.empty(); }
    172       
    173       void
    174       swap(hash_set& __hs)
    175       { _M_ht.swap(__hs._M_ht); }
    176 
    177       template<class _Val, class _HF, class _EqK, class _Al>
    178         friend bool
    179         operator==(const hash_set<_Val, _HF, _EqK, _Al>&,
    180 		   const hash_set<_Val, _HF, _EqK, _Al>&);
    181 
    182       iterator
    183       begin() const
    184       { return _M_ht.begin(); }
    185       
    186       iterator
    187       end() const
    188       { return _M_ht.end(); }
    189 
    190       pair<iterator, bool>
    191       insert(const value_type& __obj)
    192       {
    193 	pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj);
    194 	return pair<iterator,bool>(__p.first, __p.second);
    195       }
    196 
    197       template<class _InputIterator>
    198         void
    199         insert(_InputIterator __f, _InputIterator __l)
    200         { _M_ht.insert_unique(__f, __l); }
    201 
    202       pair<iterator, bool>
    203       insert_noresize(const value_type& __obj)
    204       {
    205 	pair<typename _Ht::iterator, bool> __p
    206 	  = _M_ht.insert_unique_noresize(__obj);
    207 	return pair<iterator, bool>(__p.first, __p.second);
    208       }
    209 
    210       iterator
    211       find(const key_type& __key) const
    212       { return _M_ht.find(__key); }
    213 
    214       size_type
    215       count(const key_type& __key) const
    216       { return _M_ht.count(__key); }
    217 
    218       pair<iterator, iterator>
    219       equal_range(const key_type& __key) const
    220       { return _M_ht.equal_range(__key); }
    221 
    222       size_type
    223       erase(const key_type& __key)
    224       {return _M_ht.erase(__key); }
    225       
    226       void
    227       erase(iterator __it)
    228       { _M_ht.erase(__it); }
    229       
    230       void
    231       erase(iterator __f, iterator __l)
    232       { _M_ht.erase(__f, __l); }
    233       
    234       void
    235       clear()
    236       { _M_ht.clear(); }
    237 
    238       void
    239       resize(size_type __hint)
    240       { _M_ht.resize(__hint); }
    241       
    242       size_type
    243       bucket_count() const
    244       { return _M_ht.bucket_count(); }
    245       
    246       size_type
    247       max_bucket_count() const
    248       { return _M_ht.max_bucket_count(); }
    249       
    250       size_type
    251       elems_in_bucket(size_type __n) const
    252       { return _M_ht.elems_in_bucket(__n); }
    253     };
    254 
    255   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    256     inline bool
    257     operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
    258 	       const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
    259     { return __hs1._M_ht == __hs2._M_ht; }
    260 
    261   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    262     inline bool
    263     operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
    264 	       const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
    265     { return !(__hs1 == __hs2); }
    266 
    267   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
    268     inline void
    269     swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
    270 	 hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
    271     { __hs1.swap(__hs2); }
    272 
    273 
    274   /**
    275    *  This is an SGI extension.
    276    *  @ingroup SGIextensions
    277    *  @doctodo
    278    */
    279   template<class _Value,
    280 	   class _HashFcn = hash<_Value>,
    281 	   class _EqualKey = equal_to<_Value>,
    282 	   class _Alloc = allocator<_Value> >
    283     class hash_multiset
    284     {
    285       // concept requirements
    286       __glibcxx_class_requires(_Value, _SGIAssignableConcept)
    287       __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
    288       __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
    289 
    290     private:
    291       typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
    292 			_EqualKey, _Alloc> _Ht;
    293       _Ht _M_ht;
    294 
    295     public:
    296       typedef typename _Ht::key_type key_type;
    297       typedef typename _Ht::value_type value_type;
    298       typedef typename _Ht::hasher hasher;
    299       typedef typename _Ht::key_equal key_equal;
    300       
    301       typedef typename _Ht::size_type size_type;
    302       typedef typename _Ht::difference_type difference_type;
    303       typedef typename _Alloc::pointer pointer;
    304       typedef typename _Alloc::const_pointer const_pointer;
    305       typedef typename _Alloc::reference reference;
    306       typedef typename _Alloc::const_reference const_reference;
    307 
    308       typedef typename _Ht::const_iterator iterator;
    309       typedef typename _Ht::const_iterator const_iterator;
    310       
    311       typedef typename _Ht::allocator_type allocator_type;
    312       
    313       hasher
    314       hash_funct() const
    315       { return _M_ht.hash_funct(); }
    316       
    317       key_equal
    318       key_eq() const
    319       { return _M_ht.key_eq(); }
    320       
    321       allocator_type
    322       get_allocator() const
    323       { return _M_ht.get_allocator(); }
    324 
    325       hash_multiset()
    326       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
    327 
    328       explicit
    329       hash_multiset(size_type __n)
    330       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
    331 
    332       hash_multiset(size_type __n, const hasher& __hf)
    333       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
    334       
    335       hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
    336 		    const allocator_type& __a = allocator_type())
    337       : _M_ht(__n, __hf, __eql, __a) {}
    338 
    339       template<class _InputIterator>
    340         hash_multiset(_InputIterator __f, _InputIterator __l)
    341 	: _M_ht(100, hasher(), key_equal(), allocator_type())
    342         { _M_ht.insert_equal(__f, __l); }
    343 
    344       template<class _InputIterator>
    345         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
    346 	: _M_ht(__n, hasher(), key_equal(), allocator_type())
    347         { _M_ht.insert_equal(__f, __l); }
    348 
    349       template<class _InputIterator>
    350         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
    351 		      const hasher& __hf)
    352 	: _M_ht(__n, __hf, key_equal(), allocator_type())
    353         { _M_ht.insert_equal(__f, __l); }
    354 
    355       template<class _InputIterator>
    356         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
    357 		      const hasher& __hf, const key_equal& __eql,
    358 		      const allocator_type& __a = allocator_type())
    359 	: _M_ht(__n, __hf, __eql, __a)
    360         { _M_ht.insert_equal(__f, __l); }
    361 
    362       size_type
    363       size() const
    364       { return _M_ht.size(); }
    365 
    366       size_type
    367       max_size() const
    368       { return _M_ht.max_size(); }
    369 
    370       bool
    371       empty() const
    372       { return _M_ht.empty(); }
    373 
    374       void
    375       swap(hash_multiset& hs)
    376       { _M_ht.swap(hs._M_ht); }
    377 
    378       template<class _Val, class _HF, class _EqK, class _Al>
    379         friend bool
    380         operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&,
    381 		   const hash_multiset<_Val, _HF, _EqK, _Al>&);
    382 
    383       iterator
    384       begin() const
    385       { return _M_ht.begin(); }
    386       
    387       iterator
    388       end() const
    389       { return _M_ht.end(); }
    390 
    391       iterator
    392       insert(const value_type& __obj)
    393       { return _M_ht.insert_equal(__obj); }
    394   
    395       template<class _InputIterator>
    396         void
    397         insert(_InputIterator __f, _InputIterator __l)
    398         { _M_ht.insert_equal(__f,__l); }
    399   
    400       iterator
    401       insert_noresize(const value_type& __obj)
    402       { return _M_ht.insert_equal_noresize(__obj); }
    403 
    404       iterator
    405       find(const key_type& __key) const
    406       { return _M_ht.find(__key); }
    407 
    408       size_type
    409       count(const key_type& __key) const
    410       { return _M_ht.count(__key); }
    411 
    412       pair<iterator, iterator>
    413       equal_range(const key_type& __key) const
    414       { return _M_ht.equal_range(__key); }
    415 
    416       size_type
    417       erase(const key_type& __key)
    418       { return _M_ht.erase(__key); }
    419   
    420       void
    421       erase(iterator __it)
    422       { _M_ht.erase(__it); }
    423   
    424       void
    425       erase(iterator __f, iterator __l)
    426       { _M_ht.erase(__f, __l); }
    427   
    428       void
    429       clear()
    430       { _M_ht.clear(); }
    431 
    432       void
    433       resize(size_type __hint)
    434       { _M_ht.resize(__hint); }
    435   
    436       size_type
    437       bucket_count() const
    438       { return _M_ht.bucket_count(); }
    439 
    440       size_type
    441       max_bucket_count() const
    442       { return _M_ht.max_bucket_count(); }
    443 
    444       size_type
    445       elems_in_bucket(size_type __n) const
    446       { return _M_ht.elems_in_bucket(__n); }
    447     };
    448 
    449   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
    450     inline bool
    451     operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
    452 	       const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
    453     { return __hs1._M_ht == __hs2._M_ht; }
    454 
    455   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
    456     inline bool
    457     operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
    458 	       const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
    459     { return !(__hs1 == __hs2); }
    460 
    461   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
    462     inline void
    463     swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
    464 	 hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
    465     { __hs1.swap(__hs2); }
    466 
    467 _GLIBCXX_END_NAMESPACE
    468 
    469 _GLIBCXX_BEGIN_NAMESPACE(std)
    470 
    471   // Specialization of insert_iterator so that it will work for hash_set
    472   // and hash_multiset.
    473   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    474     class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn,
    475 					      _EqualKey, _Alloc> >
    476     {
    477     protected:
    478       typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>
    479         _Container;
    480       _Container* container;
    481 
    482     public:
    483       typedef _Container          container_type;
    484       typedef output_iterator_tag iterator_category;
    485       typedef void                value_type;
    486       typedef void                difference_type;
    487       typedef void                pointer;
    488       typedef void                reference;
    489 
    490       insert_iterator(_Container& __x)
    491       : container(&__x) {}
    492       
    493       insert_iterator(_Container& __x, typename _Container::iterator)
    494       : container(&__x) {}
    495 
    496       insert_iterator<_Container>&
    497       operator=(const typename _Container::value_type& __value)
    498       {
    499 	container->insert(__value);
    500 	return *this;
    501       }
    502 
    503       insert_iterator<_Container>&
    504       operator*()
    505       { return *this; }
    506       
    507       insert_iterator<_Container>&
    508       operator++()
    509       { return *this; }
    510       
    511       insert_iterator<_Container>&
    512       operator++(int)
    513       { return *this; }
    514     };
    515 
    516   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
    517     class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn,
    518 						   _EqualKey, _Alloc> >
    519     {
    520     protected:
    521       typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>
    522         _Container;
    523       _Container* container;
    524       typename _Container::iterator iter;
    525 
    526     public:
    527       typedef _Container          container_type;
    528       typedef output_iterator_tag iterator_category;
    529       typedef void                value_type;
    530       typedef void                difference_type;
    531       typedef void                pointer;
    532       typedef void                reference;
    533       
    534       insert_iterator(_Container& __x)
    535       : container(&__x) {}
    536       
    537       insert_iterator(_Container& __x, typename _Container::iterator)
    538       : container(&__x) {}
    539 
    540       insert_iterator<_Container>&
    541       operator=(const typename _Container::value_type& __value)
    542       {
    543 	container->insert(__value);
    544 	return *this;
    545       }
    546 
    547       insert_iterator<_Container>&
    548       operator*()
    549       { return *this; }
    550 
    551       insert_iterator<_Container>&
    552       operator++()
    553       { return *this; }
    554 
    555       insert_iterator<_Container>&
    556       operator++(int) { return *this; }
    557     };
    558 
    559 _GLIBCXX_END_NAMESPACE
    560 
    561 #endif
    562