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