1// Hashing set implementation -*- C++ -*-
 
    3// Copyright (C) 2001-2021 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/backward_warning.h>
 
   63#include <bits/c++config.h>
 
   64#include <backward/hashtable.h>
 
   65#include <bits/concept_check.h>
 
   67namespace __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)
 
   91      typedef __alloc_traits<_Alloc> _Alloc_traits;
 
   94      typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
 
   95                        _EqualKey, _Alloc> _Ht;
 
   99      typedef typename _Ht::key_type key_type;
 
  100      typedef typename _Ht::value_type value_type;
 
  101      typedef typename _Ht::hasher hasher;
 
  102      typedef typename _Ht::key_equal key_equal;
 
  104      typedef typename _Ht::size_type size_type;
 
  105      typedef typename _Ht::difference_type difference_type;
 
  106      typedef typename _Alloc_traits::pointer pointer;
 
  107      typedef typename _Alloc_traits::const_pointer const_pointer;
 
  108      typedef typename _Alloc_traits::reference reference;
 
  109      typedef typename _Alloc_traits::const_reference const_reference;
 
  111      typedef typename _Ht::const_iterator iterator;
 
  112      typedef typename _Ht::const_iterator const_iterator;
 
  114      typedef typename _Ht::allocator_type allocator_type;
 
  118      { return _M_ht.hash_funct(); }
 
  122      { return _M_ht.key_eq(); }
 
  125      get_allocator() const
 
  126      { return _M_ht.get_allocator(); }
 
  129      : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
 
  132      hash_set(size_type __n)
 
  133      : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
 
  135      hash_set(size_type __n, const hasher& __hf)
 
  136      : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
 
  138      hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
 
  139               const allocator_type& __a = allocator_type())
 
  140      : _M_ht(__n, __hf, __eql, __a) {}
 
  142      template<class _InputIterator>
 
  143        hash_set(_InputIterator __f, _InputIterator __l)
 
  144        : _M_ht(100, hasher(), key_equal(), allocator_type())
 
  145        { _M_ht.insert_unique(__f, __l); }
 
  147      template<class _InputIterator>
 
  148        hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
 
  149        : _M_ht(__n, hasher(), key_equal(), allocator_type())
 
  150        { _M_ht.insert_unique(__f, __l); }
 
  152      template<class _InputIterator>
 
  153        hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
 
  155        : _M_ht(__n, __hf, key_equal(), allocator_type())
 
  156        { _M_ht.insert_unique(__f, __l); }
 
  158      template<class _InputIterator>
 
  159        hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
 
  160                 const hasher& __hf, const key_equal& __eql,
 
  161                 const allocator_type& __a = allocator_type())
 
  162        : _M_ht(__n, __hf, __eql, __a)
 
  163        { _M_ht.insert_unique(__f, __l); }
 
  167      { return _M_ht.size(); }
 
  171      { return _M_ht.max_size(); }
 
  173      _GLIBCXX_NODISCARD bool
 
  175      { return _M_ht.empty(); }
 
  179      { _M_ht.swap(__hs._M_ht); }
 
  181      template<class _Val, class _HF, class _EqK, class _Al>
 
  183        operator==(const hash_set<_Val, _HF, _EqK, _Al>&,
 
  184                   const hash_set<_Val, _HF, _EqK, _Al>&);
 
  188      { return _M_ht.begin(); }
 
  192      { return _M_ht.end(); }
 
  195      insert(const value_type& __obj)
 
  197        pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj);
 
  198        return pair<iterator,bool>(__p.first, __p.second);
 
  201      template<class _InputIterator>
 
  203        insert(_InputIterator __f, _InputIterator __l)
 
  204        { _M_ht.insert_unique(__f, __l); }
 
  207      insert_noresize(const value_type& __obj)
 
  209        pair<typename _Ht::iterator, bool> __p
 
  210          = _M_ht.insert_unique_noresize(__obj);
 
  211        return pair<iterator, bool>(__p.first, __p.second);
 
  215      find(const key_type& __key) const
 
  216      { return _M_ht.find(__key); }
 
  219      count(const key_type& __key) const
 
  220      { return _M_ht.count(__key); }
 
  222      pair<iterator, iterator>
 
  223      equal_range(const key_type& __key) const
 
  224      { return _M_ht.equal_range(__key); }
 
  227      erase(const key_type& __key)
 
  228      {return _M_ht.erase(__key); }
 
  232      { _M_ht.erase(__it); }
 
  235      erase(iterator __f, iterator __l)
 
  236      { _M_ht.erase(__f, __l); }
 
  243      resize(size_type __hint)
 
  244      { _M_ht.resize(__hint); }
 
  248      { return _M_ht.bucket_count(); }
 
  251      max_bucket_count() const
 
  252      { return _M_ht.max_bucket_count(); }
 
  255      elems_in_bucket(size_type __n) const
 
  256      { return _M_ht.elems_in_bucket(__n); }
 
  259  template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
 
  261    operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  262               const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  263    { return __hs1._M_ht == __hs2._M_ht; }
 
  265  template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
 
  267    operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  268               const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  269    { return !(__hs1 == __hs2); }
 
  271  template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
 
  273    swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  274         hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  275    { __hs1.swap(__hs2); }
 
  279   *  This is an SGI extension.
 
  280   *  @ingroup SGIextensions
 
  283  template<class _Value,
 
  284           class _HashFcn = hash<_Value>,
 
  285           class _EqualKey = equal_to<_Value>,
 
  286           class _Alloc = allocator<_Value> >
 
  289      // concept requirements
 
  290      __glibcxx_class_requires(_Value, _SGIAssignableConcept)
 
  291      __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
 
  292      __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
 
  295      typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
 
  296                        _EqualKey, _Alloc> _Ht;
 
  300      typedef typename _Ht::key_type key_type;
 
  301      typedef typename _Ht::value_type value_type;
 
  302      typedef typename _Ht::hasher hasher;
 
  303      typedef typename _Ht::key_equal key_equal;
 
  305      typedef typename _Ht::size_type size_type;
 
  306      typedef typename _Ht::difference_type difference_type;
 
  307      typedef typename _Alloc::pointer pointer;
 
  308      typedef typename _Alloc::const_pointer const_pointer;
 
  309      typedef typename _Alloc::reference reference;
 
  310      typedef typename _Alloc::const_reference const_reference;
 
  312      typedef typename _Ht::const_iterator iterator;
 
  313      typedef typename _Ht::const_iterator const_iterator;
 
  315      typedef typename _Ht::allocator_type allocator_type;
 
  319      { return _M_ht.hash_funct(); }
 
  323      { return _M_ht.key_eq(); }
 
  326      get_allocator() const
 
  327      { return _M_ht.get_allocator(); }
 
  330      : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
 
  333      hash_multiset(size_type __n)
 
  334      : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
 
  336      hash_multiset(size_type __n, const hasher& __hf)
 
  337      : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
 
  339      hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
 
  340                    const allocator_type& __a = allocator_type())
 
  341      : _M_ht(__n, __hf, __eql, __a) {}
 
  343      template<class _InputIterator>
 
  344        hash_multiset(_InputIterator __f, _InputIterator __l)
 
  345        : _M_ht(100, hasher(), key_equal(), allocator_type())
 
  346        { _M_ht.insert_equal(__f, __l); }
 
  348      template<class _InputIterator>
 
  349        hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
 
  350        : _M_ht(__n, hasher(), key_equal(), allocator_type())
 
  351        { _M_ht.insert_equal(__f, __l); }
 
  353      template<class _InputIterator>
 
  354        hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
 
  356        : _M_ht(__n, __hf, key_equal(), allocator_type())
 
  357        { _M_ht.insert_equal(__f, __l); }
 
  359      template<class _InputIterator>
 
  360        hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
 
  361                      const hasher& __hf, const key_equal& __eql,
 
  362                      const allocator_type& __a = allocator_type())
 
  363        : _M_ht(__n, __hf, __eql, __a)
 
  364        { _M_ht.insert_equal(__f, __l); }
 
  368      { return _M_ht.size(); }
 
  372      { return _M_ht.max_size(); }
 
  374      _GLIBCXX_NODISCARD bool
 
  376      { return _M_ht.empty(); }
 
  379      swap(hash_multiset& hs)
 
  380      { _M_ht.swap(hs._M_ht); }
 
  382      template<class _Val, class _HF, class _EqK, class _Al>
 
  384        operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&,
 
  385                   const hash_multiset<_Val, _HF, _EqK, _Al>&);
 
  389      { return _M_ht.begin(); }
 
  393      { return _M_ht.end(); }
 
  396      insert(const value_type& __obj)
 
  397      { return _M_ht.insert_equal(__obj); }
 
  399      template<class _InputIterator>
 
  401        insert(_InputIterator __f, _InputIterator __l)
 
  402        { _M_ht.insert_equal(__f,__l); }
 
  405      insert_noresize(const value_type& __obj)
 
  406      { return _M_ht.insert_equal_noresize(__obj); }
 
  409      find(const key_type& __key) const
 
  410      { return _M_ht.find(__key); }
 
  413      count(const key_type& __key) const
 
  414      { return _M_ht.count(__key); }
 
  416      pair<iterator, iterator>
 
  417      equal_range(const key_type& __key) const
 
  418      { return _M_ht.equal_range(__key); }
 
  421      erase(const key_type& __key)
 
  422      { return _M_ht.erase(__key); }
 
  426      { _M_ht.erase(__it); }
 
  429      erase(iterator __f, iterator __l)
 
  430      { _M_ht.erase(__f, __l); }
 
  437      resize(size_type __hint)
 
  438      { _M_ht.resize(__hint); }
 
  442      { return _M_ht.bucket_count(); }
 
  445      max_bucket_count() const
 
  446      { return _M_ht.max_bucket_count(); }
 
  449      elems_in_bucket(size_type __n) const
 
  450      { return _M_ht.elems_in_bucket(__n); }
 
  453  template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
 
  455    operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  456               const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  457    { return __hs1._M_ht == __hs2._M_ht; }
 
  459  template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
 
  461    operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  462               const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  463    { return !(__hs1 == __hs2); }
 
  465  template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
 
  467    swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
 
  468         hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
 
  469    { __hs1.swap(__hs2); }
 
  471_GLIBCXX_END_NAMESPACE_VERSION
 
  474namespace std _GLIBCXX_VISIBILITY(default)
 
  476_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
  478  // Specialization of insert_iterator so that it will work for hash_set
 
  479  // and hash_multiset.
 
  480  template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
 
  481    class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn,
 
  485      typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>
 
  487      _Container* container;
 
  490      typedef _Container          container_type;
 
  491      typedef output_iterator_tag iterator_category;
 
  492      typedef void                value_type;
 
  493      typedef void                difference_type;
 
  494      typedef void                pointer;
 
  495      typedef void                reference;
 
  497      insert_iterator(_Container& __x)
 
  500      insert_iterator(_Container& __x, typename _Container::iterator)
 
  503      insert_iterator<_Container>&
 
  504      operator=(const typename _Container::value_type& __value)
 
  506        container->insert(__value);
 
  510      insert_iterator<_Container>&
 
  514      insert_iterator<_Container>&
 
  518      insert_iterator<_Container>&
 
  523  template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
 
  524    class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn,
 
  528      typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>
 
  530      _Container* container;
 
  531      typename _Container::iterator iter;
 
  534      typedef _Container          container_type;
 
  535      typedef output_iterator_tag iterator_category;
 
  536      typedef void                value_type;
 
  537      typedef void                difference_type;
 
  538      typedef void                pointer;
 
  539      typedef void                reference;
 
  541      insert_iterator(_Container& __x)
 
  544      insert_iterator(_Container& __x, typename _Container::iterator)
 
  547      insert_iterator<_Container>&
 
  548      operator=(const typename _Container::value_type& __value)
 
  550        container->insert(__value);
 
  554      insert_iterator<_Container>&
 
  558      insert_iterator<_Container>&
 
  562      insert_iterator<_Container>&
 
  563      operator++(int) { return *this; }
 
  566_GLIBCXX_END_NAMESPACE_VERSION