1 // Hashing set implementation -*- C++ -*-
 
    3 // Copyright (C) 2001-2014 Free Software Foundation, Inc.
 
    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)
 
   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.
 
   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.
 
   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/>.
 
   27  * Silicon Graphics Computer Systems, Inc.
 
   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.
 
   39  * Hewlett-Packard Company
 
   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.
 
   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).
 
   56 #ifndef _BACKWARD_HASH_SET
 
   57 #define _BACKWARD_HASH_SET 1
 
   59 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
 
   60 #include "backward_warning.h"
 
   63 #include <bits/c++config.h>
 
   64 #include <backward/hashtable.h>
 
   65 #include <bits/concept_check.h>
 
   67 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 
   69 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   77    *  This is an SGI extension.
 
   78    *  @ingroup SGIextensions
 
   81   template<class _Value, class _HashFcn  = hash<_Value>,
 
   82       class _EqualKey = equal_to<_Value>,
 
   83       class _Alloc = allocator<_Value> >
 
   86       // concept requirements
 
   87       __glibcxx_class_requires(_Value, _SGIAssignableConcept)
 
   88       __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
 
   89       __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
 
   92       typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
 
   93            _EqualKey, _Alloc> _Ht;
 
   97       typedef typename _Ht::key_type key_type;
 
   98       typedef typename _Ht::value_type value_type;
 
   99       typedef typename _Ht::hasher hasher;
 
  100       typedef typename _Ht::key_equal key_equal;
 
  102       typedef typename _Ht::size_type size_type;
 
  103       typedef typename _Ht::difference_type difference_type;
 
  104       typedef typename _Alloc::pointer pointer;
 
  105       typedef typename _Alloc::const_pointer const_pointer;
 
  106       typedef typename _Alloc::reference reference;
 
  107       typedef typename _Alloc::const_reference const_reference;
 
  109       typedef typename _Ht::const_iterator iterator;
 
  110       typedef typename _Ht::const_iterator const_iterator;
 
  112       typedef typename _Ht::allocator_type allocator_type;
 
  116       { return _M_ht.hash_funct(); }
 
  120       { return _M_ht.key_eq(); }
 
  123       get_allocator() const
 
  124       { return _M_ht.get_allocator(); }
 
  127       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
 
  130       hash_set(size_type __n)
 
  131       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
 
  133       hash_set(size_type __n, const hasher& __hf)
 
  134       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
 
  136       hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
 
  137           const allocator_type& __a = allocator_type())
 
  138       : _M_ht(__n, __hf, __eql, __a) {}
 
  140       template<class _InputIterator>
 
  141         hash_set(_InputIterator __f, _InputIterator __l)
 
  142    : _M_ht(100, hasher(), key_equal(), allocator_type())
 
  143         { _M_ht.insert_unique(__f, __l); }
 
  145       template<class _InputIterator>
 
  146         hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
 
  147    : _M_ht(__n, hasher(), key_equal(), allocator_type())
 
  148         { _M_ht.insert_unique(__f, __l); }
 
  150       template<class _InputIterator>
 
  151         hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
 
  153    : _M_ht(__n, __hf, key_equal(), allocator_type())
 
  154         { _M_ht.insert_unique(__f, __l); }
 
  156       template<class _InputIterator>
 
  157         hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
 
  158         const hasher& __hf, const key_equal& __eql,
 
  159         const allocator_type& __a = allocator_type())
 
  160    : _M_ht(__n, __hf, __eql, __a)
 
  161         { _M_ht.insert_unique(__f, __l); }
 
  165       { return _M_ht.size(); }
 
  169       { return _M_ht.max_size(); }
 
  173       { return _M_ht.empty(); }
 
  177       { _M_ht.swap(__hs._M_ht); }
 
  179       template<class _Val, class _HF, class _EqK, class _Al>
 
  181         operator==(const hash_set<_Val, _HF, _EqK, _Al>&,
 
  182           const hash_set<_Val, _HF, _EqK, _Al>&);
 
  186       { return _M_ht.begin(); }
 
  190       { return _M_ht.end(); }
 
  193       insert(const value_type& __obj)
 
  195    pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj);
 
  196    return pair<iterator,bool>(__p.first, __p.second);
 
  199       template<class _InputIterator>
 
  201         insert(_InputIterator __f, _InputIterator __l)
 
  202         { _M_ht.insert_unique(__f, __l); }
 
  205       insert_noresize(const value_type& __obj)
 
  207    pair<typename _Ht::iterator, bool> __p
 
  208      = _M_ht.insert_unique_noresize(__obj);
 
  209    return pair<iterator, bool>(__p.first, __p.second);
 
  213       find(const key_type& __key) const
 
  214       { return _M_ht.find(__key); }
 
  217       count(const key_type& __key) const
 
  218       { return _M_ht.count(__key); }
 
  220       pair<iterator, iterator>
 
  221       equal_range(const key_type& __key) const
 
  222       { return _M_ht.equal_range(__key); }
 
  225       erase(const key_type& __key)
 
  226       {return _M_ht.erase(__key); }
 
  230       { _M_ht.erase(__it); }
 
  233       erase(iterator __f, iterator __l)
 
  234       { _M_ht.erase(__f, __l); }
 
  241       resize(size_type __hint)
 
  242       { _M_ht.resize(__hint); }
 
  246       { return _M_ht.bucket_count(); }
 
  249       max_bucket_count() const
 
  250       { return _M_ht.max_bucket_count(); }
 
  253       elems_in_bucket(size_type __n) const
 
  254       { return _M_ht.elems_in_bucket(__n); }
 
  257   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
 
  259     operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  260           const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  261     { return __hs1._M_ht == __hs2._M_ht; }
 
  263   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
 
  265     operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  266           const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  267     { return !(__hs1 == __hs2); }
 
  269   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
 
  271     swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  272     hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  273     { __hs1.swap(__hs2); }
 
  277    *  This is an SGI extension.
 
  278    *  @ingroup SGIextensions
 
  281   template<class _Value,
 
  282       class _HashFcn = hash<_Value>,
 
  283       class _EqualKey = equal_to<_Value>,
 
  284       class _Alloc = allocator<_Value> >
 
  287       // concept requirements
 
  288       __glibcxx_class_requires(_Value, _SGIAssignableConcept)
 
  289       __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
 
  290       __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
 
  293       typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
 
  294            _EqualKey, _Alloc> _Ht;
 
  298       typedef typename _Ht::key_type key_type;
 
  299       typedef typename _Ht::value_type value_type;
 
  300       typedef typename _Ht::hasher hasher;
 
  301       typedef typename _Ht::key_equal key_equal;
 
  303       typedef typename _Ht::size_type size_type;
 
  304       typedef typename _Ht::difference_type difference_type;
 
  305       typedef typename _Alloc::pointer pointer;
 
  306       typedef typename _Alloc::const_pointer const_pointer;
 
  307       typedef typename _Alloc::reference reference;
 
  308       typedef typename _Alloc::const_reference const_reference;
 
  310       typedef typename _Ht::const_iterator iterator;
 
  311       typedef typename _Ht::const_iterator const_iterator;
 
  313       typedef typename _Ht::allocator_type allocator_type;
 
  317       { return _M_ht.hash_funct(); }
 
  321       { return _M_ht.key_eq(); }
 
  324       get_allocator() const
 
  325       { return _M_ht.get_allocator(); }
 
  328       : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
 
  331       hash_multiset(size_type __n)
 
  332       : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
 
  334       hash_multiset(size_type __n, const hasher& __hf)
 
  335       : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
 
  337       hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
 
  338            const allocator_type& __a = allocator_type())
 
  339       : _M_ht(__n, __hf, __eql, __a) {}
 
  341       template<class _InputIterator>
 
  342         hash_multiset(_InputIterator __f, _InputIterator __l)
 
  343    : _M_ht(100, hasher(), key_equal(), allocator_type())
 
  344         { _M_ht.insert_equal(__f, __l); }
 
  346       template<class _InputIterator>
 
  347         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
 
  348    : _M_ht(__n, hasher(), key_equal(), allocator_type())
 
  349         { _M_ht.insert_equal(__f, __l); }
 
  351       template<class _InputIterator>
 
  352         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
 
  354    : _M_ht(__n, __hf, key_equal(), allocator_type())
 
  355         { _M_ht.insert_equal(__f, __l); }
 
  357       template<class _InputIterator>
 
  358         hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
 
  359              const hasher& __hf, const key_equal& __eql,
 
  360              const allocator_type& __a = allocator_type())
 
  361    : _M_ht(__n, __hf, __eql, __a)
 
  362         { _M_ht.insert_equal(__f, __l); }
 
  366       { return _M_ht.size(); }
 
  370       { return _M_ht.max_size(); }
 
  374       { return _M_ht.empty(); }
 
  377       swap(hash_multiset& hs)
 
  378       { _M_ht.swap(hs._M_ht); }
 
  380       template<class _Val, class _HF, class _EqK, class _Al>
 
  382         operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&,
 
  383           const hash_multiset<_Val, _HF, _EqK, _Al>&);
 
  387       { return _M_ht.begin(); }
 
  391       { return _M_ht.end(); }
 
  394       insert(const value_type& __obj)
 
  395       { return _M_ht.insert_equal(__obj); }
 
  397       template<class _InputIterator>
 
  399         insert(_InputIterator __f, _InputIterator __l)
 
  400         { _M_ht.insert_equal(__f,__l); }
 
  403       insert_noresize(const value_type& __obj)
 
  404       { return _M_ht.insert_equal_noresize(__obj); }
 
  407       find(const key_type& __key) const
 
  408       { return _M_ht.find(__key); }
 
  411       count(const key_type& __key) const
 
  412       { return _M_ht.count(__key); }
 
  414       pair<iterator, iterator>
 
  415       equal_range(const key_type& __key) const
 
  416       { return _M_ht.equal_range(__key); }
 
  419       erase(const key_type& __key)
 
  420       { return _M_ht.erase(__key); }
 
  424       { _M_ht.erase(__it); }
 
  427       erase(iterator __f, iterator __l)
 
  428       { _M_ht.erase(__f, __l); }
 
  435       resize(size_type __hint)
 
  436       { _M_ht.resize(__hint); }
 
  440       { return _M_ht.bucket_count(); }
 
  443       max_bucket_count() const
 
  444       { return _M_ht.max_bucket_count(); }
 
  447       elems_in_bucket(size_type __n) const
 
  448       { return _M_ht.elems_in_bucket(__n); }
 
  451   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
 
  453     operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  454           const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  455     { return __hs1._M_ht == __hs2._M_ht; }
 
  457   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
 
  459     operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  460           const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  461     { return !(__hs1 == __hs2); }
 
  463   template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
 
  465     swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  466     hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  467     { __hs1.swap(__hs2); }
 
  469 _GLIBCXX_END_NAMESPACE_VERSION
 
  472 namespace std _GLIBCXX_VISIBILITY(default)
 
  474 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
  476   // Specialization of insert_iterator so that it will work for hash_set
 
  477   // and hash_multiset.
 
  478   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
 
  479     class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn,
 
  483       typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>
 
  485       _Container* container;
 
  488       typedef _Container          container_type;
 
  489       typedef output_iterator_tag iterator_category;
 
  490       typedef void                value_type;
 
  491       typedef void                difference_type;
 
  492       typedef void                pointer;
 
  493       typedef void                reference;
 
  495       insert_iterator(_Container& __x)
 
  498       insert_iterator(_Container& __x, typename _Container::iterator)
 
  501       insert_iterator<_Container>&
 
  502       operator=(const typename _Container::value_type& __value)
 
  504    container->insert(__value);
 
  508       insert_iterator<_Container>&
 
  512       insert_iterator<_Container>&
 
  516       insert_iterator<_Container>&
 
  521   template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
 
  522     class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn,
 
  526       typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>
 
  528       _Container* container;
 
  529       typename _Container::iterator iter;
 
  532       typedef _Container          container_type;
 
  533       typedef output_iterator_tag iterator_category;
 
  534       typedef void                value_type;
 
  535       typedef void                difference_type;
 
  536       typedef void                pointer;
 
  537       typedef void                reference;
 
  539       insert_iterator(_Container& __x)
 
  542       insert_iterator(_Container& __x, typename _Container::iterator)
 
  545       insert_iterator<_Container>&
 
  546       operator=(const typename _Container::value_type& __value)
 
  548    container->insert(__value);
 
  552       insert_iterator<_Container>&
 
  556       insert_iterator<_Container>&
 
  560       insert_iterator<_Container>&
 
  561       operator++(int) { return *this; }
 
  564 _GLIBCXX_END_NAMESPACE_VERSION