xref: /freebsd/contrib/llvm-project/libcxx/include/ext/hash_set (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_HASH_SET
110b57cec5SDimitry Andric#define _LIBCPP_HASH_SET
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric
150b57cec5SDimitry Andric    hash_set synopsis
160b57cec5SDimitry Andric
170b57cec5SDimitry Andricnamespace __gnu_cxx
180b57cec5SDimitry Andric{
190b57cec5SDimitry Andric
200b57cec5SDimitry Andrictemplate <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
210b57cec5SDimitry Andric          class Alloc = allocator<Value>>
220b57cec5SDimitry Andricclass hash_set
230b57cec5SDimitry Andric{
240b57cec5SDimitry Andricpublic:
250b57cec5SDimitry Andric    // types
260b57cec5SDimitry Andric    typedef Value                                                      key_type;
270b57cec5SDimitry Andric    typedef key_type                                                   value_type;
280b57cec5SDimitry Andric    typedef Hash                                                       hasher;
290b57cec5SDimitry Andric    typedef Pred                                                       key_equal;
300b57cec5SDimitry Andric    typedef Alloc                                                      allocator_type;
310b57cec5SDimitry Andric    typedef value_type&                                                reference;
320b57cec5SDimitry Andric    typedef const value_type&                                          const_reference;
330b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::pointer         pointer;
340b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
350b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::size_type       size_type;
360b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric    typedef /unspecified/ iterator;
390b57cec5SDimitry Andric    typedef /unspecified/ const_iterator;
400b57cec5SDimitry Andric
410b57cec5SDimitry Andric    explicit hash_set(size_type n = 193, const hasher& hf = hasher(),
420b57cec5SDimitry Andric                           const key_equal& eql = key_equal(),
430b57cec5SDimitry Andric                           const allocator_type& a = allocator_type());
440b57cec5SDimitry Andric    template <class InputIterator>
450b57cec5SDimitry Andric        hash_set(InputIterator f, InputIterator l,
460b57cec5SDimitry Andric                      size_type n = 193, const hasher& hf = hasher(),
470b57cec5SDimitry Andric                      const key_equal& eql = key_equal(),
480b57cec5SDimitry Andric                      const allocator_type& a = allocator_type());
490b57cec5SDimitry Andric    hash_set(const hash_set&);
500b57cec5SDimitry Andric    ~hash_set();
510b57cec5SDimitry Andric    hash_set& operator=(const hash_set&);
520b57cec5SDimitry Andric
530b57cec5SDimitry Andric    allocator_type get_allocator() const;
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric    bool      empty() const;
560b57cec5SDimitry Andric    size_type size() const;
570b57cec5SDimitry Andric    size_type max_size() const;
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric    iterator       begin();
600b57cec5SDimitry Andric    iterator       end();
610b57cec5SDimitry Andric    const_iterator begin()  const;
620b57cec5SDimitry Andric    const_iterator end()    const;
630b57cec5SDimitry Andric
640b57cec5SDimitry Andric    pair<iterator, bool> insert(const value_type& obj);
650b57cec5SDimitry Andric    template <class InputIterator>
660b57cec5SDimitry Andric        void insert(InputIterator first, InputIterator last);
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric    void erase(const_iterator position);
690b57cec5SDimitry Andric    size_type erase(const key_type& k);
700b57cec5SDimitry Andric    void erase(const_iterator first, const_iterator last);
710b57cec5SDimitry Andric    void clear();
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric    void swap(hash_set&);
740b57cec5SDimitry Andric
750b57cec5SDimitry Andric    hasher hash_funct() const;
760b57cec5SDimitry Andric    key_equal key_eq() const;
770b57cec5SDimitry Andric
780b57cec5SDimitry Andric    iterator       find(const key_type& k);
790b57cec5SDimitry Andric    const_iterator find(const key_type& k) const;
800b57cec5SDimitry Andric    size_type count(const key_type& k) const;
810b57cec5SDimitry Andric    pair<iterator, iterator>             equal_range(const key_type& k);
820b57cec5SDimitry Andric    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
830b57cec5SDimitry Andric
840b57cec5SDimitry Andric    size_type bucket_count() const;
850b57cec5SDimitry Andric    size_type max_bucket_count() const;
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric    size_type elems_in_bucket(size_type n) const;
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric    void resize(size_type n);
900b57cec5SDimitry Andric};
910b57cec5SDimitry Andric
920b57cec5SDimitry Andrictemplate <class Value, class Hash, class Pred, class Alloc>
930b57cec5SDimitry Andric    void swap(hash_set<Value, Hash, Pred, Alloc>& x,
940b57cec5SDimitry Andric              hash_set<Value, Hash, Pred, Alloc>& y);
950b57cec5SDimitry Andric
960b57cec5SDimitry Andrictemplate <class Value, class Hash, class Pred, class Alloc>
970b57cec5SDimitry Andric    bool
980b57cec5SDimitry Andric    operator==(const hash_set<Value, Hash, Pred, Alloc>& x,
990b57cec5SDimitry Andric               const hash_set<Value, Hash, Pred, Alloc>& y);
1000b57cec5SDimitry Andric
1010b57cec5SDimitry Andrictemplate <class Value, class Hash, class Pred, class Alloc>
1020b57cec5SDimitry Andric    bool
1030b57cec5SDimitry Andric    operator!=(const hash_set<Value, Hash, Pred, Alloc>& x,
1040b57cec5SDimitry Andric               const hash_set<Value, Hash, Pred, Alloc>& y);
1050b57cec5SDimitry Andric
1060b57cec5SDimitry Andrictemplate <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
1070b57cec5SDimitry Andric          class Alloc = allocator<Value>>
1080b57cec5SDimitry Andricclass hash_multiset
1090b57cec5SDimitry Andric{
1100b57cec5SDimitry Andricpublic:
1110b57cec5SDimitry Andric    // types
1120b57cec5SDimitry Andric    typedef Value                                                      key_type;
1130b57cec5SDimitry Andric    typedef key_type                                                   value_type;
1140b57cec5SDimitry Andric    typedef Hash                                                       hasher;
1150b57cec5SDimitry Andric    typedef Pred                                                       key_equal;
1160b57cec5SDimitry Andric    typedef Alloc                                                      allocator_type;
1170b57cec5SDimitry Andric    typedef value_type&                                                reference;
1180b57cec5SDimitry Andric    typedef const value_type&                                          const_reference;
1190b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::pointer         pointer;
1200b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
1210b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::size_type       size_type;
1220b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andric    typedef /unspecified/ iterator;
1250b57cec5SDimitry Andric    typedef /unspecified/ const_iterator;
1260b57cec5SDimitry Andric
1270b57cec5SDimitry Andric    explicit hash_multiset(size_type n = 193, const hasher& hf = hasher(),
1280b57cec5SDimitry Andric                           const key_equal& eql = key_equal(),
1290b57cec5SDimitry Andric                           const allocator_type& a = allocator_type());
1300b57cec5SDimitry Andric    template <class InputIterator>
1310b57cec5SDimitry Andric        hash_multiset(InputIterator f, InputIterator l,
1320b57cec5SDimitry Andric                      size_type n = 193, const hasher& hf = hasher(),
1330b57cec5SDimitry Andric                      const key_equal& eql = key_equal(),
1340b57cec5SDimitry Andric                      const allocator_type& a = allocator_type());
1350b57cec5SDimitry Andric    hash_multiset(const hash_multiset&);
1360b57cec5SDimitry Andric    ~hash_multiset();
1370b57cec5SDimitry Andric    hash_multiset& operator=(const hash_multiset&);
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andric    allocator_type get_allocator() const;
1400b57cec5SDimitry Andric
1410b57cec5SDimitry Andric    bool      empty() const;
1420b57cec5SDimitry Andric    size_type size() const;
1430b57cec5SDimitry Andric    size_type max_size() const;
1440b57cec5SDimitry Andric
1450b57cec5SDimitry Andric    iterator       begin();
1460b57cec5SDimitry Andric    iterator       end();
1470b57cec5SDimitry Andric    const_iterator begin()  const;
1480b57cec5SDimitry Andric    const_iterator end()    const;
1490b57cec5SDimitry Andric
1500b57cec5SDimitry Andric    iterator insert(const value_type& obj);
1510b57cec5SDimitry Andric    template <class InputIterator>
1520b57cec5SDimitry Andric        void insert(InputIterator first, InputIterator last);
1530b57cec5SDimitry Andric
1540b57cec5SDimitry Andric    void erase(const_iterator position);
1550b57cec5SDimitry Andric    size_type erase(const key_type& k);
1560b57cec5SDimitry Andric    void erase(const_iterator first, const_iterator last);
1570b57cec5SDimitry Andric    void clear();
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric    void swap(hash_multiset&);
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric    hasher hash_funct() const;
1620b57cec5SDimitry Andric    key_equal key_eq() const;
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric    iterator       find(const key_type& k);
1650b57cec5SDimitry Andric    const_iterator find(const key_type& k) const;
1660b57cec5SDimitry Andric    size_type count(const key_type& k) const;
1670b57cec5SDimitry Andric    pair<iterator, iterator>             equal_range(const key_type& k);
1680b57cec5SDimitry Andric    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
1690b57cec5SDimitry Andric
1700b57cec5SDimitry Andric    size_type bucket_count() const;
1710b57cec5SDimitry Andric    size_type max_bucket_count() const;
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andric    size_type elems_in_bucket(size_type n) const;
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andric    void resize(size_type n);
1760b57cec5SDimitry Andric};
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andrictemplate <class Value, class Hash, class Pred, class Alloc>
1790b57cec5SDimitry Andric    void swap(hash_multiset<Value, Hash, Pred, Alloc>& x,
1800b57cec5SDimitry Andric              hash_multiset<Value, Hash, Pred, Alloc>& y);
1810b57cec5SDimitry Andric
1820b57cec5SDimitry Andrictemplate <class Value, class Hash, class Pred, class Alloc>
1830b57cec5SDimitry Andric    bool
1840b57cec5SDimitry Andric    operator==(const hash_multiset<Value, Hash, Pred, Alloc>& x,
1850b57cec5SDimitry Andric               const hash_multiset<Value, Hash, Pred, Alloc>& y);
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andrictemplate <class Value, class Hash, class Pred, class Alloc>
1880b57cec5SDimitry Andric    bool
1890b57cec5SDimitry Andric    operator!=(const hash_multiset<Value, Hash, Pred, Alloc>& x,
1900b57cec5SDimitry Andric               const hash_multiset<Value, Hash, Pred, Alloc>& y);
1910b57cec5SDimitry Andric}  // __gnu_cxx
1920b57cec5SDimitry Andric
1930b57cec5SDimitry Andric*/
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andric#include <__config>
1960b57cec5SDimitry Andric#include <__hash_table>
19781ad6265SDimitry Andric#include <algorithm>
1980b57cec5SDimitry Andric#include <ext/__hash>
19904eeddc0SDimitry Andric#include <functional>
2000b57cec5SDimitry Andric
201fe6060f1SDimitry Andric#if defined(__DEPRECATED) && __DEPRECATED
2020b57cec5SDimitry Andric#  if defined(_LIBCPP_WARNING)
2030b57cec5SDimitry Andric_LIBCPP_WARNING("Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>")
2040b57cec5SDimitry Andric#  else
2050b57cec5SDimitry Andric#    warning Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>
2060b57cec5SDimitry Andric#  endif
2070b57cec5SDimitry Andric#endif
2080b57cec5SDimitry Andric
2090eae32dcSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2100eae32dcSDimitry Andric#  pragma GCC system_header
2110eae32dcSDimitry Andric#endif
2120eae32dcSDimitry Andric
2130b57cec5SDimitry Andricnamespace __gnu_cxx {
2140b57cec5SDimitry Andric
215*cb14a3feSDimitry Andrictemplate <class _Value,
216*cb14a3feSDimitry Andric          class _Hash  = hash<_Value>,
217*cb14a3feSDimitry Andric          class _Pred  = std::equal_to<_Value>,
2180b57cec5SDimitry Andric          class _Alloc = std::allocator<_Value> >
219*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_set {
2200b57cec5SDimitry Andricpublic:
2210b57cec5SDimitry Andric  // types
2220b57cec5SDimitry Andric  typedef _Value key_type;
2230b57cec5SDimitry Andric  typedef key_type value_type;
2240b57cec5SDimitry Andric  typedef _Hash hasher;
2250b57cec5SDimitry Andric  typedef _Pred key_equal;
2260b57cec5SDimitry Andric  typedef _Alloc allocator_type;
2270b57cec5SDimitry Andric  typedef value_type& reference;
2280b57cec5SDimitry Andric  typedef const value_type& const_reference;
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andricprivate:
2310b57cec5SDimitry Andric  typedef std::__hash_table<value_type, hasher, key_equal, allocator_type> __table;
2320b57cec5SDimitry Andric
2330b57cec5SDimitry Andric  __table __table_;
2340b57cec5SDimitry Andric
2350b57cec5SDimitry Andricpublic:
2360b57cec5SDimitry Andric  typedef typename __table::pointer pointer;
2370b57cec5SDimitry Andric  typedef typename __table::const_pointer const_pointer;
2380b57cec5SDimitry Andric  typedef typename __table::size_type size_type;
2390b57cec5SDimitry Andric  typedef typename __table::difference_type difference_type;
2400b57cec5SDimitry Andric
2410b57cec5SDimitry Andric  typedef typename __table::const_iterator iterator;
2420b57cec5SDimitry Andric  typedef typename __table::const_iterator const_iterator;
2430b57cec5SDimitry Andric
244*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_set() {}
245*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit hash_set(
246*cb14a3feSDimitry Andric      size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
247*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a);
2480b57cec5SDimitry Andric  template <class _InputIterator>
24906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last);
2500b57cec5SDimitry Andric  template <class _InputIterator>
251*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
252*cb14a3feSDimitry Andric  hash_set(_InputIterator __first,
253*cb14a3feSDimitry Andric           _InputIterator __last,
254*cb14a3feSDimitry Andric           size_type __n,
255*cb14a3feSDimitry Andric           const hasher& __hf     = hasher(),
2560b57cec5SDimitry Andric           const key_equal& __eql = key_equal());
2570b57cec5SDimitry Andric  template <class _InputIterator>
258*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
259*cb14a3feSDimitry Andric  hash_set(_InputIterator __first,
260*cb14a3feSDimitry Andric           _InputIterator __last,
261*cb14a3feSDimitry Andric           size_type __n,
262*cb14a3feSDimitry Andric           const hasher& __hf,
263*cb14a3feSDimitry Andric           const key_equal& __eql,
2640b57cec5SDimitry Andric           const allocator_type& __a);
26506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_set(const hash_set& __u);
2660b57cec5SDimitry Andric
267*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return allocator_type(__table_.__node_alloc()); }
2680b57cec5SDimitry Andric
269*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool empty() const { return __table_.size() == 0; }
270*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type size() const { return __table_.size(); }
271*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_size() const { return __table_.max_size(); }
2720b57cec5SDimitry Andric
273*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() { return __table_.begin(); }
274*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() { return __table_.end(); }
275*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { return __table_.begin(); }
276*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __table_.end(); }
2770b57cec5SDimitry Andric
278*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI std::pair<iterator, bool> insert(const value_type& __x) {
279*cb14a3feSDimitry Andric    return __table_.__insert_unique(__x);
280*cb14a3feSDimitry Andric  }
281*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) { return insert(__x).first; }
2820b57cec5SDimitry Andric  template <class _InputIterator>
283*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last);
2840b57cec5SDimitry Andric
285*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __p) { __table_.erase(__p); }
286*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __table_.__erase_unique(__k); }
287*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __first, const_iterator __last) { __table_.erase(__first, __last); }
288*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void clear() { __table_.clear(); }
2890b57cec5SDimitry Andric
290*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(hash_set& __u) { __table_.swap(__u.__table_); }
2910b57cec5SDimitry Andric
292*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hasher hash_funct() const { return __table_.hash_function(); }
293*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq(); }
2940b57cec5SDimitry Andric
295*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
296*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
297*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_unique(__k); }
298*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI std::pair<iterator, iterator> equal_range(const key_type& __k) {
299*cb14a3feSDimitry Andric    return __table_.__equal_range_unique(__k);
300*cb14a3feSDimitry Andric  }
301*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
302*cb14a3feSDimitry Andric    return __table_.__equal_range_unique(__k);
303*cb14a3feSDimitry Andric  }
3040b57cec5SDimitry Andric
305*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const { return __table_.bucket_count(); }
306*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const { return __table_.max_bucket_count(); }
3070b57cec5SDimitry Andric
308*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type elems_in_bucket(size_type __n) const { return __table_.bucket_size(__n); }
3090b57cec5SDimitry Andric
310*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { __table_.__rehash_unique(__n); }
3110b57cec5SDimitry Andric};
3120b57cec5SDimitry Andric
3130b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
314*cb14a3feSDimitry Andrichash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n, const hasher& __hf, const key_equal& __eql)
315*cb14a3feSDimitry Andric    : __table_(__hf, __eql) {
316753f127fSDimitry Andric  __table_.__rehash_unique(__n);
3170b57cec5SDimitry Andric}
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
320*cb14a3feSDimitry Andrichash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
321*cb14a3feSDimitry Andric    size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
322*cb14a3feSDimitry Andric    : __table_(__hf, __eql, __a) {
323753f127fSDimitry Andric  __table_.__rehash_unique(__n);
3240b57cec5SDimitry Andric}
3250b57cec5SDimitry Andric
3260b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
3270b57cec5SDimitry Andrictemplate <class _InputIterator>
328*cb14a3feSDimitry Andrichash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(_InputIterator __first, _InputIterator __last) {
3290b57cec5SDimitry Andric  insert(__first, __last);
3300b57cec5SDimitry Andric}
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
3330b57cec5SDimitry Andrictemplate <class _InputIterator>
3340b57cec5SDimitry Andrichash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
335*cb14a3feSDimitry Andric    _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql)
336*cb14a3feSDimitry Andric    : __table_(__hf, __eql) {
337753f127fSDimitry Andric  __table_.__rehash_unique(__n);
3380b57cec5SDimitry Andric  insert(__first, __last);
3390b57cec5SDimitry Andric}
3400b57cec5SDimitry Andric
3410b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
3420b57cec5SDimitry Andrictemplate <class _InputIterator>
3430b57cec5SDimitry Andrichash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
344*cb14a3feSDimitry Andric    _InputIterator __first,
345*cb14a3feSDimitry Andric    _InputIterator __last,
346*cb14a3feSDimitry Andric    size_type __n,
347*cb14a3feSDimitry Andric    const hasher& __hf,
348*cb14a3feSDimitry Andric    const key_equal& __eql,
349*cb14a3feSDimitry Andric    const allocator_type& __a)
350*cb14a3feSDimitry Andric    : __table_(__hf, __eql, __a) {
351753f127fSDimitry Andric  __table_.__rehash_unique(__n);
3520b57cec5SDimitry Andric  insert(__first, __last);
3530b57cec5SDimitry Andric}
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
356*cb14a3feSDimitry Andrichash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(const hash_set& __u) : __table_(__u.__table_) {
357753f127fSDimitry Andric  __table_.__rehash_unique(__u.bucket_count());
3580b57cec5SDimitry Andric  insert(__u.begin(), __u.end());
3590b57cec5SDimitry Andric}
3600b57cec5SDimitry Andric
3610b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
3620b57cec5SDimitry Andrictemplate <class _InputIterator>
363*cb14a3feSDimitry Andricinline void hash_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) {
3640b57cec5SDimitry Andric  for (; __first != __last; ++__first)
3650b57cec5SDimitry Andric    __table_.__insert_unique(*__first);
3660b57cec5SDimitry Andric}
3670b57cec5SDimitry Andric
3680b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
369*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
370*cb14a3feSDimitry Andricswap(hash_set<_Value, _Hash, _Pred, _Alloc>& __x, hash_set<_Value, _Hash, _Pred, _Alloc>& __y) {
3710b57cec5SDimitry Andric  __x.swap(__y);
3720b57cec5SDimitry Andric}
3730b57cec5SDimitry Andric
3740b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
375bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool
376*cb14a3feSDimitry Andricoperator==(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x, const hash_set<_Value, _Hash, _Pred, _Alloc>& __y) {
3770b57cec5SDimitry Andric  if (__x.size() != __y.size())
3780b57cec5SDimitry Andric    return false;
379*cb14a3feSDimitry Andric  typedef typename hash_set<_Value, _Hash, _Pred, _Alloc>::const_iterator const_iterator;
380*cb14a3feSDimitry Andric  for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); __i != __ex; ++__i) {
3810b57cec5SDimitry Andric    const_iterator __j = __y.find(*__i);
3820b57cec5SDimitry Andric    if (__j == __ey || !(*__i == *__j))
3830b57cec5SDimitry Andric      return false;
3840b57cec5SDimitry Andric  }
3850b57cec5SDimitry Andric  return true;
3860b57cec5SDimitry Andric}
3870b57cec5SDimitry Andric
3880b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
389*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
390*cb14a3feSDimitry Andricoperator!=(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x, const hash_set<_Value, _Hash, _Pred, _Alloc>& __y) {
3910b57cec5SDimitry Andric  return !(__x == __y);
3920b57cec5SDimitry Andric}
3930b57cec5SDimitry Andric
394*cb14a3feSDimitry Andrictemplate <class _Value,
395*cb14a3feSDimitry Andric          class _Hash  = hash<_Value>,
396*cb14a3feSDimitry Andric          class _Pred  = std::equal_to<_Value>,
3970b57cec5SDimitry Andric          class _Alloc = std::allocator<_Value> >
398*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_multiset {
3990b57cec5SDimitry Andricpublic:
4000b57cec5SDimitry Andric  // types
4010b57cec5SDimitry Andric  typedef _Value key_type;
4020b57cec5SDimitry Andric  typedef key_type value_type;
4030b57cec5SDimitry Andric  typedef _Hash hasher;
4040b57cec5SDimitry Andric  typedef _Pred key_equal;
4050b57cec5SDimitry Andric  typedef _Alloc allocator_type;
4060b57cec5SDimitry Andric  typedef value_type& reference;
4070b57cec5SDimitry Andric  typedef const value_type& const_reference;
4080b57cec5SDimitry Andric
4090b57cec5SDimitry Andricprivate:
4100b57cec5SDimitry Andric  typedef std::__hash_table<value_type, hasher, key_equal, allocator_type> __table;
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andric  __table __table_;
4130b57cec5SDimitry Andric
4140b57cec5SDimitry Andricpublic:
4150b57cec5SDimitry Andric  typedef typename __table::pointer pointer;
4160b57cec5SDimitry Andric  typedef typename __table::const_pointer const_pointer;
4170b57cec5SDimitry Andric  typedef typename __table::size_type size_type;
4180b57cec5SDimitry Andric  typedef typename __table::difference_type difference_type;
4190b57cec5SDimitry Andric
4200b57cec5SDimitry Andric  typedef typename __table::const_iterator iterator;
4210b57cec5SDimitry Andric  typedef typename __table::const_iterator const_iterator;
4220b57cec5SDimitry Andric
423*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_multiset() {}
424*cb14a3feSDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI
425*cb14a3feSDimitry Andric  hash_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
4265f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
427*cb14a3feSDimitry Andric  hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a);
4280b57cec5SDimitry Andric  template <class _InputIterator>
42906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last);
4300b57cec5SDimitry Andric  template <class _InputIterator>
431*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
432*cb14a3feSDimitry Andric  hash_multiset(_InputIterator __first,
433*cb14a3feSDimitry Andric                _InputIterator __last,
434*cb14a3feSDimitry Andric                size_type __n,
435*cb14a3feSDimitry Andric                const hasher& __hf     = hasher(),
4360b57cec5SDimitry Andric                const key_equal& __eql = key_equal());
4370b57cec5SDimitry Andric  template <class _InputIterator>
438*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_multiset(
439*cb14a3feSDimitry Andric      _InputIterator __first,
440*cb14a3feSDimitry Andric      _InputIterator __last,
441*cb14a3feSDimitry Andric      size_type __n,
442*cb14a3feSDimitry Andric      const hasher& __hf,
443*cb14a3feSDimitry Andric      const key_equal& __eql,
444*cb14a3feSDimitry Andric      const allocator_type& __a);
44506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_multiset(const hash_multiset& __u);
4460b57cec5SDimitry Andric
447*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return allocator_type(__table_.__node_alloc()); }
4480b57cec5SDimitry Andric
449*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool empty() const { return __table_.size() == 0; }
450*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type size() const { return __table_.size(); }
451*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_size() const { return __table_.max_size(); }
4520b57cec5SDimitry Andric
453*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() { return __table_.begin(); }
454*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() { return __table_.end(); }
455*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { return __table_.begin(); }
456*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __table_.end(); }
4570b57cec5SDimitry Andric
458*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return __table_.__insert_multi(__x); }
459*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) { return insert(__x); }
4600b57cec5SDimitry Andric  template <class _InputIterator>
461*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last);
4620b57cec5SDimitry Andric
463*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __p) { __table_.erase(__p); }
464*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __table_.__erase_multi(__k); }
465*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __first, const_iterator __last) { __table_.erase(__first, __last); }
466*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void clear() { __table_.clear(); }
4670b57cec5SDimitry Andric
468*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(hash_multiset& __u) { __table_.swap(__u.__table_); }
4690b57cec5SDimitry Andric
470*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hasher hash_funct() const { return __table_.hash_function(); }
471*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq(); }
4720b57cec5SDimitry Andric
473*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
474*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
475*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_multi(__k); }
476*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI std::pair<iterator, iterator> equal_range(const key_type& __k) {
477*cb14a3feSDimitry Andric    return __table_.__equal_range_multi(__k);
478*cb14a3feSDimitry Andric  }
479*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
480*cb14a3feSDimitry Andric    return __table_.__equal_range_multi(__k);
481*cb14a3feSDimitry Andric  }
4820b57cec5SDimitry Andric
483*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const { return __table_.bucket_count(); }
484*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const { return __table_.max_bucket_count(); }
4850b57cec5SDimitry Andric
486*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type elems_in_bucket(size_type __n) const { return __table_.bucket_size(__n); }
4870b57cec5SDimitry Andric
488*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { __table_.__rehash_multi(__n); }
4890b57cec5SDimitry Andric};
4900b57cec5SDimitry Andric
4910b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
492*cb14a3feSDimitry Andrichash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql)
493*cb14a3feSDimitry Andric    : __table_(__hf, __eql) {
494753f127fSDimitry Andric  __table_.__rehash_multi(__n);
4950b57cec5SDimitry Andric}
4960b57cec5SDimitry Andric
4970b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
4980b57cec5SDimitry Andrichash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
499*cb14a3feSDimitry Andric    size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
500*cb14a3feSDimitry Andric    : __table_(__hf, __eql, __a) {
501*cb14a3feSDimitry Andric  __table_.__rehash_multi(__n);
502*cb14a3feSDimitry Andric}
503*cb14a3feSDimitry Andric
504*cb14a3feSDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
505*cb14a3feSDimitry Andrictemplate <class _InputIterator>
506*cb14a3feSDimitry Andrichash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(_InputIterator __first, _InputIterator __last) {
507*cb14a3feSDimitry Andric  insert(__first, __last);
508*cb14a3feSDimitry Andric}
509*cb14a3feSDimitry Andric
510*cb14a3feSDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
511*cb14a3feSDimitry Andrictemplate <class _InputIterator>
512*cb14a3feSDimitry Andrichash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
513*cb14a3feSDimitry Andric    _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql)
514*cb14a3feSDimitry Andric    : __table_(__hf, __eql) {
515*cb14a3feSDimitry Andric  __table_.__rehash_multi(__n);
516*cb14a3feSDimitry Andric  insert(__first, __last);
517*cb14a3feSDimitry Andric}
518*cb14a3feSDimitry Andric
519*cb14a3feSDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
520*cb14a3feSDimitry Andrictemplate <class _InputIterator>
521*cb14a3feSDimitry Andrichash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
522*cb14a3feSDimitry Andric    _InputIterator __first,
523*cb14a3feSDimitry Andric    _InputIterator __last,
524*cb14a3feSDimitry Andric    size_type __n,
525*cb14a3feSDimitry Andric    const hasher& __hf,
526*cb14a3feSDimitry Andric    const key_equal& __eql,
5270b57cec5SDimitry Andric    const allocator_type& __a)
528*cb14a3feSDimitry Andric    : __table_(__hf, __eql, __a) {
529753f127fSDimitry Andric  __table_.__rehash_multi(__n);
5300b57cec5SDimitry Andric  insert(__first, __last);
5310b57cec5SDimitry Andric}
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
534*cb14a3feSDimitry Andrichash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(const hash_multiset& __u) : __table_(__u.__table_) {
535753f127fSDimitry Andric  __table_.__rehash_multi(__u.bucket_count());
5360b57cec5SDimitry Andric  insert(__u.begin(), __u.end());
5370b57cec5SDimitry Andric}
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
5400b57cec5SDimitry Andrictemplate <class _InputIterator>
541*cb14a3feSDimitry Andricinline void hash_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) {
5420b57cec5SDimitry Andric  for (; __first != __last; ++__first)
5430b57cec5SDimitry Andric    __table_.__insert_multi(*__first);
5440b57cec5SDimitry Andric}
5450b57cec5SDimitry Andric
5460b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
547*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
548*cb14a3feSDimitry Andricswap(hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x, hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) {
5490b57cec5SDimitry Andric  __x.swap(__y);
5500b57cec5SDimitry Andric}
5510b57cec5SDimitry Andric
5520b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
553*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator==(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
554*cb14a3feSDimitry Andric                                      const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) {
5550b57cec5SDimitry Andric  if (__x.size() != __y.size())
5560b57cec5SDimitry Andric    return false;
557*cb14a3feSDimitry Andric  typedef typename hash_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator const_iterator;
5580b57cec5SDimitry Andric  typedef std::pair<const_iterator, const_iterator> _EqRng;
559*cb14a3feSDimitry Andric  for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) {
5600b57cec5SDimitry Andric    _EqRng __xeq = __x.equal_range(*__i);
5610b57cec5SDimitry Andric    _EqRng __yeq = __y.equal_range(*__i);
562*cb14a3feSDimitry Andric    if (std::distance(__xeq.first, __xeq.second) != std::distance(__yeq.first, __yeq.second) ||
5635f757f3fSDimitry Andric        !std::is_permutation(__xeq.first, __xeq.second, __yeq.first))
5640b57cec5SDimitry Andric      return false;
5650b57cec5SDimitry Andric    __i = __xeq.second;
5660b57cec5SDimitry Andric  }
5670b57cec5SDimitry Andric  return true;
5680b57cec5SDimitry Andric}
5690b57cec5SDimitry Andric
5700b57cec5SDimitry Andrictemplate <class _Value, class _Hash, class _Pred, class _Alloc>
571*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
572*cb14a3feSDimitry Andric                                             const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y) {
5730b57cec5SDimitry Andric  return !(__x == __y);
5740b57cec5SDimitry Andric}
5750b57cec5SDimitry Andric
5760eae32dcSDimitry Andric} // namespace __gnu_cxx
5770b57cec5SDimitry Andric
578bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
579bdd1243dSDimitry Andric#  include <concepts>
580bdd1243dSDimitry Andric#  include <iterator>
58106c3fb27SDimitry Andric#  include <type_traits>
582bdd1243dSDimitry Andric#endif
583bdd1243dSDimitry Andric
5840b57cec5SDimitry Andric#endif // _LIBCPP_HASH_SET
585