xref: /freebsd/contrib/llvm-project/libcxx/include/ext/hash_map (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
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_MAP
110b57cec5SDimitry Andric#define _LIBCPP_HASH_MAP
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric
150b57cec5SDimitry Andric    hash_map synopsis
160b57cec5SDimitry Andric
170b57cec5SDimitry Andricnamespace __gnu_cxx
180b57cec5SDimitry Andric{
190b57cec5SDimitry Andric
200b57cec5SDimitry Andrictemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
210b57cec5SDimitry Andric          class Alloc = allocator<pair<const Key, T>>>
220b57cec5SDimitry Andricclass hash_map
230b57cec5SDimitry Andric{
240b57cec5SDimitry Andricpublic:
250b57cec5SDimitry Andric    // types
260b57cec5SDimitry Andric    typedef Key                                                        key_type;
270b57cec5SDimitry Andric    typedef T                                                          mapped_type;
280b57cec5SDimitry Andric    typedef Hash                                                       hasher;
290b57cec5SDimitry Andric    typedef Pred                                                       key_equal;
300b57cec5SDimitry Andric    typedef Alloc                                                      allocator_type;
310b57cec5SDimitry Andric    typedef pair<const key_type, mapped_type>                          value_type;
320b57cec5SDimitry Andric    typedef value_type&                                                reference;
330b57cec5SDimitry Andric    typedef const value_type&                                          const_reference;
340b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::pointer         pointer;
350b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
360b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::size_type       size_type;
370b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
380b57cec5SDimitry Andric
390b57cec5SDimitry Andric    typedef /unspecified/ iterator;
400b57cec5SDimitry Andric    typedef /unspecified/ const_iterator;
410b57cec5SDimitry Andric
42e40139ffSDimitry Andric    hash_map();
43e40139ffSDimitry Andric    explicit hash_map(size_type n, const hasher& hf = hasher(),
440b57cec5SDimitry Andric                           const key_equal& eql = key_equal(),
450b57cec5SDimitry Andric                           const allocator_type& a = allocator_type());
460b57cec5SDimitry Andric    template <class InputIterator>
47e40139ffSDimitry Andric    hash_map(InputIterator f, InputIterator l);
48e40139ffSDimitry Andric    template <class InputIterator>
490b57cec5SDimitry Andric    hash_map(InputIterator f, InputIterator l,
50e40139ffSDimitry Andric                size_type n, const hasher& hf = hasher(),
510b57cec5SDimitry Andric                const key_equal& eql = key_equal(),
520b57cec5SDimitry Andric                const allocator_type& a = allocator_type());
530b57cec5SDimitry Andric    hash_map(const hash_map&);
540b57cec5SDimitry Andric    ~hash_map();
550b57cec5SDimitry Andric    hash_map& operator=(const hash_map&);
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric    allocator_type get_allocator() const;
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric    bool      empty() const;
600b57cec5SDimitry Andric    size_type size() const;
610b57cec5SDimitry Andric    size_type max_size() const;
620b57cec5SDimitry Andric
630b57cec5SDimitry Andric    iterator       begin();
640b57cec5SDimitry Andric    iterator       end();
650b57cec5SDimitry Andric    const_iterator begin()  const;
660b57cec5SDimitry Andric    const_iterator end()    const;
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric    pair<iterator, bool> insert(const value_type& obj);
690b57cec5SDimitry Andric    template <class InputIterator>
700b57cec5SDimitry Andric        void insert(InputIterator first, InputIterator last);
710b57cec5SDimitry Andric
720b57cec5SDimitry Andric    void erase(const_iterator position);
730b57cec5SDimitry Andric    size_type erase(const key_type& k);
740b57cec5SDimitry Andric    void erase(const_iterator first, const_iterator last);
750b57cec5SDimitry Andric    void clear();
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric    void swap(hash_map&);
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric    hasher hash_funct() const;
800b57cec5SDimitry Andric    key_equal key_eq() const;
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric    iterator       find(const key_type& k);
830b57cec5SDimitry Andric    const_iterator find(const key_type& k) const;
840b57cec5SDimitry Andric    size_type count(const key_type& k) const;
850b57cec5SDimitry Andric    pair<iterator, iterator>             equal_range(const key_type& k);
860b57cec5SDimitry Andric    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric    mapped_type& operator[](const key_type& k);
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric    size_type bucket_count() const;
910b57cec5SDimitry Andric    size_type max_bucket_count() const;
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric    size_type elems_in_bucket(size_type n) const;
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric    void resize(size_type n);
960b57cec5SDimitry Andric};
970b57cec5SDimitry Andric
980b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
990b57cec5SDimitry Andric    void swap(hash_map<Key, T, Hash, Pred, Alloc>& x,
1000b57cec5SDimitry Andric              hash_map<Key, T, Hash, Pred, Alloc>& y);
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
1030b57cec5SDimitry Andric    bool
1040b57cec5SDimitry Andric    operator==(const hash_map<Key, T, Hash, Pred, Alloc>& x,
1050b57cec5SDimitry Andric               const hash_map<Key, T, Hash, Pred, Alloc>& y);
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
1080b57cec5SDimitry Andric    bool
1090b57cec5SDimitry Andric    operator!=(const hash_map<Key, T, Hash, Pred, Alloc>& x,
1100b57cec5SDimitry Andric               const hash_map<Key, T, Hash, Pred, Alloc>& y);
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andrictemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
1130b57cec5SDimitry Andric          class Alloc = allocator<pair<const Key, T>>>
1140b57cec5SDimitry Andricclass hash_multimap
1150b57cec5SDimitry Andric{
1160b57cec5SDimitry Andricpublic:
1170b57cec5SDimitry Andric    // types
1180b57cec5SDimitry Andric    typedef Key                                                        key_type;
1190b57cec5SDimitry Andric    typedef T                                                          mapped_type;
1200b57cec5SDimitry Andric    typedef Hash                                                       hasher;
1210b57cec5SDimitry Andric    typedef Pred                                                       key_equal;
1220b57cec5SDimitry Andric    typedef Alloc                                                      allocator_type;
1230b57cec5SDimitry Andric    typedef pair<const key_type, mapped_type>                          value_type;
1240b57cec5SDimitry Andric    typedef value_type&                                                reference;
1250b57cec5SDimitry Andric    typedef const value_type&                                          const_reference;
1260b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::pointer         pointer;
1270b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
1280b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::size_type       size_type;
1290b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric    typedef /unspecified/ iterator;
1320b57cec5SDimitry Andric    typedef /unspecified/ const_iterator;
1330b57cec5SDimitry Andric
1340b57cec5SDimitry Andric    explicit hash_multimap(size_type n = 193, const hasher& hf = hasher(),
1350b57cec5SDimitry Andric                           const key_equal& eql = key_equal(),
1360b57cec5SDimitry Andric                           const allocator_type& a = allocator_type());
1370b57cec5SDimitry Andric    template <class InputIterator>
1380b57cec5SDimitry Andric        hash_multimap(InputIterator f, InputIterator l,
1390b57cec5SDimitry Andric                      size_type n = 193, const hasher& hf = hasher(),
1400b57cec5SDimitry Andric                      const key_equal& eql = key_equal(),
1410b57cec5SDimitry Andric                      const allocator_type& a = allocator_type());
1420b57cec5SDimitry Andric    explicit hash_multimap(const allocator_type&);
1430b57cec5SDimitry Andric    hash_multimap(const hash_multimap&);
1440b57cec5SDimitry Andric    ~hash_multimap();
1450b57cec5SDimitry Andric    hash_multimap& operator=(const hash_multimap&);
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andric    allocator_type get_allocator() const;
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andric    bool      empty() const;
1500b57cec5SDimitry Andric    size_type size() const;
1510b57cec5SDimitry Andric    size_type max_size() const;
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andric    iterator       begin();
1540b57cec5SDimitry Andric    iterator       end();
1550b57cec5SDimitry Andric    const_iterator begin()  const;
1560b57cec5SDimitry Andric    const_iterator end()    const;
1570b57cec5SDimitry Andric
1580b57cec5SDimitry Andric    iterator insert(const value_type& obj);
1590b57cec5SDimitry Andric    template <class InputIterator>
1600b57cec5SDimitry Andric        void insert(InputIterator first, InputIterator last);
1610b57cec5SDimitry Andric
1620b57cec5SDimitry Andric    void erase(const_iterator position);
1630b57cec5SDimitry Andric    size_type erase(const key_type& k);
1640b57cec5SDimitry Andric    void erase(const_iterator first, const_iterator last);
1650b57cec5SDimitry Andric    void clear();
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andric    void swap(hash_multimap&);
1680b57cec5SDimitry Andric
1690b57cec5SDimitry Andric    hasher hash_funct() const;
1700b57cec5SDimitry Andric    key_equal key_eq() const;
1710b57cec5SDimitry Andric
1720b57cec5SDimitry Andric    iterator       find(const key_type& k);
1730b57cec5SDimitry Andric    const_iterator find(const key_type& k) const;
1740b57cec5SDimitry Andric    size_type count(const key_type& k) const;
1750b57cec5SDimitry Andric    pair<iterator, iterator>             equal_range(const key_type& k);
1760b57cec5SDimitry Andric    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric    size_type bucket_count() const;
1790b57cec5SDimitry Andric    size_type max_bucket_count() const;
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andric    size_type elems_in_bucket(size_type n) const;
1820b57cec5SDimitry Andric
1830b57cec5SDimitry Andric    void resize(size_type n);
1840b57cec5SDimitry Andric};
1850b57cec5SDimitry Andric
1860b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
1870b57cec5SDimitry Andric    void swap(hash_multimap<Key, T, Hash, Pred, Alloc>& x,
1880b57cec5SDimitry Andric              hash_multimap<Key, T, Hash, Pred, Alloc>& y);
1890b57cec5SDimitry Andric
1900b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
1910b57cec5SDimitry Andric    bool
1920b57cec5SDimitry Andric    operator==(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
1930b57cec5SDimitry Andric               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
1960b57cec5SDimitry Andric    bool
1970b57cec5SDimitry Andric    operator!=(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
1980b57cec5SDimitry Andric               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);
1990b57cec5SDimitry Andric
2000b57cec5SDimitry Andric}  // __gnu_cxx
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric*/
2030b57cec5SDimitry Andric
20481ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
2050b57cec5SDimitry Andric#include <__config>
2060b57cec5SDimitry Andric#include <__hash_table>
20781ad6265SDimitry Andric#include <algorithm>
20804eeddc0SDimitry Andric#include <ext/__hash>
2090b57cec5SDimitry Andric#include <functional>
2100b57cec5SDimitry Andric
211fe6060f1SDimitry Andric#if defined(__DEPRECATED) && __DEPRECATED
2120b57cec5SDimitry Andric#  if defined(_LIBCPP_WARNING)
2130b57cec5SDimitry Andric_LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>")
2140b57cec5SDimitry Andric#  else
2150b57cec5SDimitry Andric#    warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
2160b57cec5SDimitry Andric#  endif
2170b57cec5SDimitry Andric#endif
2180b57cec5SDimitry Andric
2190b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2200b57cec5SDimitry Andric#  pragma GCC system_header
2210b57cec5SDimitry Andric#endif
2220b57cec5SDimitry Andric
2230b57cec5SDimitry Andricnamespace __gnu_cxx {
2240b57cec5SDimitry Andric
225*cb14a3feSDimitry Andrictemplate <class _Tp, class _Hash, bool = std::is_empty<_Hash>::value && !std::__libcpp_is_final<_Hash>::value >
226*cb14a3feSDimitry Andricclass __hash_map_hasher : private _Hash {
2270b57cec5SDimitry Andricpublic:
2285f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_hasher() : _Hash() {}
2295f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_hasher(const _Hash& __h) : _Hash(__h) {}
2305f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const _Hash& hash_function() const { return *this; }
231*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_t operator()(const _Tp& __x) const { return static_cast<const _Hash&>(*this)(__x.first); }
232*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_t operator()(const typename _Tp::first_type& __x) const {
233*cb14a3feSDimitry Andric    return static_cast<const _Hash&>(*this)(__x);
234*cb14a3feSDimitry Andric  }
2350b57cec5SDimitry Andric};
2360b57cec5SDimitry Andric
2370b57cec5SDimitry Andrictemplate <class _Tp, class _Hash>
238*cb14a3feSDimitry Andricclass __hash_map_hasher<_Tp, _Hash, false> {
2390b57cec5SDimitry Andric  _Hash __hash_;
240*cb14a3feSDimitry Andric
2410b57cec5SDimitry Andricpublic:
2425f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_hasher() : __hash_() {}
2435f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_hasher(const _Hash& __h) : __hash_(__h) {}
2445f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const _Hash& hash_function() const { return __hash_; }
245*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_t operator()(const _Tp& __x) const { return __hash_(__x.first); }
246*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_t operator()(const typename _Tp::first_type& __x) const { return __hash_(__x); }
2470b57cec5SDimitry Andric};
2480b57cec5SDimitry Andric
249*cb14a3feSDimitry Andrictemplate <class _Tp, class _Pred, bool = std::is_empty<_Pred>::value && !std::__libcpp_is_final<_Pred>::value >
250*cb14a3feSDimitry Andricclass __hash_map_equal : private _Pred {
2510b57cec5SDimitry Andricpublic:
2525f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_equal() : _Pred() {}
2535f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_equal(const _Pred& __p) : _Pred(__p) {}
2545f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const _Pred& key_eq() const { return *this; }
255*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
256*cb14a3feSDimitry Andric    return static_cast<const _Pred&>(*this)(__x.first, __y.first);
257*cb14a3feSDimitry Andric  }
258*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const {
259*cb14a3feSDimitry Andric    return static_cast<const _Pred&>(*this)(__x, __y.first);
260*cb14a3feSDimitry Andric  }
261*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const {
262*cb14a3feSDimitry Andric    return static_cast<const _Pred&>(*this)(__x.first, __y);
263*cb14a3feSDimitry Andric  }
264*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool
265*cb14a3feSDimitry Andric  operator()(const typename _Tp::first_type& __x, const typename _Tp::first_type& __y) const {
266*cb14a3feSDimitry Andric    return static_cast<const _Pred&>(*this)(__x, __y);
267*cb14a3feSDimitry Andric  }
2680b57cec5SDimitry Andric};
2690b57cec5SDimitry Andric
2700b57cec5SDimitry Andrictemplate <class _Tp, class _Pred>
271*cb14a3feSDimitry Andricclass __hash_map_equal<_Tp, _Pred, false> {
2720b57cec5SDimitry Andric  _Pred __pred_;
273*cb14a3feSDimitry Andric
2740b57cec5SDimitry Andricpublic:
2755f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_equal() : __pred_() {}
2765f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_equal(const _Pred& __p) : __pred_(__p) {}
2775f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const _Pred& key_eq() const { return __pred_; }
278*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { return __pred_(__x.first, __y.first); }
279*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const {
280*cb14a3feSDimitry Andric    return __pred_(__x, __y.first);
281*cb14a3feSDimitry Andric  }
282*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const {
283*cb14a3feSDimitry Andric    return __pred_(__x.first, __y);
284*cb14a3feSDimitry Andric  }
285*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool
286*cb14a3feSDimitry Andric  operator()(const typename _Tp::first_type& __x, const typename _Tp::first_type& __y) const {
287*cb14a3feSDimitry Andric    return __pred_(__x, __y);
288*cb14a3feSDimitry Andric  }
2890b57cec5SDimitry Andric};
2900b57cec5SDimitry Andric
2910b57cec5SDimitry Andrictemplate <class _Alloc>
292*cb14a3feSDimitry Andricclass __hash_map_node_destructor {
2930b57cec5SDimitry Andric  typedef _Alloc allocator_type;
2940b57cec5SDimitry Andric  typedef std::allocator_traits<allocator_type> __alloc_traits;
2950b57cec5SDimitry Andric  typedef typename __alloc_traits::value_type::__node_value_type value_type;
296*cb14a3feSDimitry Andric
2970b57cec5SDimitry Andricpublic:
2980b57cec5SDimitry Andric  typedef typename __alloc_traits::pointer pointer;
299*cb14a3feSDimitry Andric
3000b57cec5SDimitry Andricprivate:
3010b57cec5SDimitry Andric  typedef typename value_type::first_type first_type;
3020b57cec5SDimitry Andric  typedef typename value_type::second_type second_type;
3030b57cec5SDimitry Andric
3040b57cec5SDimitry Andric  allocator_type& __na_;
3050b57cec5SDimitry Andric
3060b57cec5SDimitry Andricpublic:
3070b57cec5SDimitry Andric  bool __first_constructed;
3080b57cec5SDimitry Andric  bool __second_constructed;
3090b57cec5SDimitry Andric
31006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_node_destructor(__hash_map_node_destructor const&) = default;
311cd0c3137SDimitry Andric  __hash_map_node_destructor& operator=(const __hash_map_node_destructor&)            = delete;
312cd0c3137SDimitry Andric
313*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __hash_map_node_destructor(allocator_type& __na)
314*cb14a3feSDimitry Andric      : __na_(__na), __first_constructed(false), __second_constructed(false) {}
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
317*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_node_destructor(std::__hash_node_destructor<allocator_type>&& __x)
318*cb14a3feSDimitry Andric      : __na_(__x.__na_), __first_constructed(__x.__value_constructed), __second_constructed(__x.__value_constructed) {
3190b57cec5SDimitry Andric    __x.__value_constructed = false;
3200b57cec5SDimitry Andric  }
3210b57cec5SDimitry Andric#else  // _LIBCPP_CXX03_LANG
322*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_node_destructor(const std::__hash_node_destructor<allocator_type>& __x)
323*cb14a3feSDimitry Andric      : __na_(__x.__na_), __first_constructed(__x.__value_constructed), __second_constructed(__x.__value_constructed) {
3240b57cec5SDimitry Andric    const_cast<bool&>(__x.__value_constructed) = false;
3250b57cec5SDimitry Andric  }
3260b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
3270b57cec5SDimitry Andric
328*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) {
3290b57cec5SDimitry Andric    if (__second_constructed)
3305f757f3fSDimitry Andric      __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().second));
3310b57cec5SDimitry Andric    if (__first_constructed)
3325f757f3fSDimitry Andric      __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().first));
3330b57cec5SDimitry Andric    if (__p)
3340b57cec5SDimitry Andric      __alloc_traits::deallocate(__na_, __p, 1);
3350b57cec5SDimitry Andric  }
3360b57cec5SDimitry Andric};
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andrictemplate <class _HashIterator>
339*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_iterator {
3400b57cec5SDimitry Andric  _HashIterator __i_;
3410b57cec5SDimitry Andric
3420b57cec5SDimitry Andric  typedef const typename _HashIterator::value_type::first_type key_type;
3430b57cec5SDimitry Andric  typedef typename _HashIterator::value_type::second_type mapped_type;
344*cb14a3feSDimitry Andric
3450b57cec5SDimitry Andricpublic:
3460b57cec5SDimitry Andric  typedef std::forward_iterator_tag iterator_category;
3470b57cec5SDimitry Andric  typedef std::pair<key_type, mapped_type> value_type;
3480b57cec5SDimitry Andric  typedef typename _HashIterator::difference_type difference_type;
3490b57cec5SDimitry Andric  typedef value_type& reference;
350*cb14a3feSDimitry Andric  typedef std::__rebind_pointer_t<typename _HashIterator::pointer, value_type> pointer;
3510b57cec5SDimitry Andric
3525f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_iterator() {}
3530b57cec5SDimitry Andric
3545f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_iterator(_HashIterator __i) : __i_(__i) {}
3550b57cec5SDimitry Andric
3565f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *operator->(); }
3575f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return (pointer)__i_.operator->(); }
3580b57cec5SDimitry Andric
359*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_iterator& operator++() {
360*cb14a3feSDimitry Andric    ++__i_;
361*cb14a3feSDimitry Andric    return *this;
362*cb14a3feSDimitry Andric  }
363*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_iterator operator++(int) {
3640b57cec5SDimitry Andric    __hash_map_iterator __t(*this);
3650b57cec5SDimitry Andric    ++(*this);
3660b57cec5SDimitry Andric    return __t;
3670b57cec5SDimitry Andric  }
3680b57cec5SDimitry Andric
369*cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y) {
370*cb14a3feSDimitry Andric    return __x.__i_ == __y.__i_;
371*cb14a3feSDimitry Andric  }
372*cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y) {
373*cb14a3feSDimitry Andric    return __x.__i_ != __y.__i_;
374*cb14a3feSDimitry Andric  }
3750b57cec5SDimitry Andric
376*cb14a3feSDimitry Andric  template <class, class, class, class, class>
377*cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS hash_map;
378*cb14a3feSDimitry Andric  template <class, class, class, class, class>
379*cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
380*cb14a3feSDimitry Andric  template <class>
381*cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
382*cb14a3feSDimitry Andric  template <class>
383*cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
384*cb14a3feSDimitry Andric  template <class>
385*cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
3860b57cec5SDimitry Andric};
3870b57cec5SDimitry Andric
3880b57cec5SDimitry Andrictemplate <class _HashIterator>
389*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator {
3900b57cec5SDimitry Andric  _HashIterator __i_;
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andric  typedef const typename _HashIterator::value_type::first_type key_type;
3930b57cec5SDimitry Andric  typedef typename _HashIterator::value_type::second_type mapped_type;
394*cb14a3feSDimitry Andric
3950b57cec5SDimitry Andricpublic:
3960b57cec5SDimitry Andric  typedef std::forward_iterator_tag iterator_category;
3970b57cec5SDimitry Andric  typedef std::pair<key_type, mapped_type> value_type;
3980b57cec5SDimitry Andric  typedef typename _HashIterator::difference_type difference_type;
3990b57cec5SDimitry Andric  typedef const value_type& reference;
400*cb14a3feSDimitry Andric  typedef std::__rebind_pointer_t<typename _HashIterator::pointer, const value_type> pointer;
4010b57cec5SDimitry Andric
4025f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator() {}
4030b57cec5SDimitry Andric
404*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {}
405*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator(__hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
4060b57cec5SDimitry Andric      : __i_(__i.__i_) {}
4070b57cec5SDimitry Andric
408*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *operator->(); }
409*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return (pointer)__i_.operator->(); }
4100b57cec5SDimitry Andric
411*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator& operator++() {
412*cb14a3feSDimitry Andric    ++__i_;
413*cb14a3feSDimitry Andric    return *this;
414*cb14a3feSDimitry Andric  }
415*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator operator++(int) {
4160b57cec5SDimitry Andric    __hash_map_const_iterator __t(*this);
4170b57cec5SDimitry Andric    ++(*this);
4180b57cec5SDimitry Andric    return __t;
4190b57cec5SDimitry Andric  }
4200b57cec5SDimitry Andric
421*cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool
422*cb14a3feSDimitry Andric  operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) {
423*cb14a3feSDimitry Andric    return __x.__i_ == __y.__i_;
424*cb14a3feSDimitry Andric  }
425*cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool
426*cb14a3feSDimitry Andric  operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) {
427*cb14a3feSDimitry Andric    return __x.__i_ != __y.__i_;
428*cb14a3feSDimitry Andric  }
4290b57cec5SDimitry Andric
430*cb14a3feSDimitry Andric  template <class, class, class, class, class>
431*cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS hash_map;
432*cb14a3feSDimitry Andric  template <class, class, class, class, class>
433*cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
434*cb14a3feSDimitry Andric  template <class>
435*cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
436*cb14a3feSDimitry Andric  template <class>
437*cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
4380b57cec5SDimitry Andric};
4390b57cec5SDimitry Andric
440*cb14a3feSDimitry Andrictemplate <class _Key,
441*cb14a3feSDimitry Andric          class _Tp,
442*cb14a3feSDimitry Andric          class _Hash  = hash<_Key>,
443*cb14a3feSDimitry Andric          class _Pred  = std::equal_to<_Key>,
4440b57cec5SDimitry Andric          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
445*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_map {
4460b57cec5SDimitry Andricpublic:
4470b57cec5SDimitry Andric  // types
4480b57cec5SDimitry Andric  typedef _Key key_type;
4490b57cec5SDimitry Andric  typedef _Tp mapped_type;
4500b57cec5SDimitry Andric  typedef _Tp data_type;
4510b57cec5SDimitry Andric  typedef _Hash hasher;
4520b57cec5SDimitry Andric  typedef _Pred key_equal;
4530b57cec5SDimitry Andric  typedef _Alloc allocator_type;
4540b57cec5SDimitry Andric  typedef std::pair<const key_type, mapped_type> value_type;
4550b57cec5SDimitry Andric  typedef value_type& reference;
4560b57cec5SDimitry Andric  typedef const value_type& const_reference;
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andricprivate:
4590b57cec5SDimitry Andric  typedef std::pair<key_type, mapped_type> __value_type;
4600b57cec5SDimitry Andric  typedef __hash_map_hasher<__value_type, hasher> __hasher;
4610b57cec5SDimitry Andric  typedef __hash_map_equal<__value_type, key_equal> __key_equal;
462bdd1243dSDimitry Andric  typedef std::__rebind_alloc<std::allocator_traits<allocator_type>, __value_type> __allocator_type;
4630b57cec5SDimitry Andric
464*cb14a3feSDimitry Andric  typedef std::__hash_table<__value_type, __hasher, __key_equal, __allocator_type> __table;
4650b57cec5SDimitry Andric
4660b57cec5SDimitry Andric  __table __table_;
4670b57cec5SDimitry Andric
4680b57cec5SDimitry Andric  typedef typename __table::__node_pointer __node_pointer;
4690b57cec5SDimitry Andric  typedef typename __table::__node_const_pointer __node_const_pointer;
4700b57cec5SDimitry Andric  typedef typename __table::__node_traits __node_traits;
4710b57cec5SDimitry Andric  typedef typename __table::__node_allocator __node_allocator;
4720b57cec5SDimitry Andric  typedef typename __table::__node __node;
4730b57cec5SDimitry Andric  typedef __hash_map_node_destructor<__node_allocator> _Dp;
4740b57cec5SDimitry Andric  typedef std::unique_ptr<__node, _Dp> __node_holder;
4750b57cec5SDimitry Andric  typedef std::allocator_traits<allocator_type> __alloc_traits;
476*cb14a3feSDimitry Andric
4770b57cec5SDimitry Andricpublic:
4780b57cec5SDimitry Andric  typedef typename __alloc_traits::pointer pointer;
4790b57cec5SDimitry Andric  typedef typename __alloc_traits::const_pointer const_pointer;
4800b57cec5SDimitry Andric  typedef typename __alloc_traits::size_type size_type;
4810b57cec5SDimitry Andric  typedef typename __alloc_traits::difference_type difference_type;
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andric  typedef __hash_map_iterator<typename __table::iterator> iterator;
4840b57cec5SDimitry Andric  typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
4850b57cec5SDimitry Andric
4865f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_map() {}
487*cb14a3feSDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI
488*cb14a3feSDimitry Andric  hash_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
489*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a);
4900b57cec5SDimitry Andric  template <class _InputIterator>
49106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last);
4920b57cec5SDimitry Andric  template <class _InputIterator>
493*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
494*cb14a3feSDimitry Andric  hash_map(_InputIterator __first,
495*cb14a3feSDimitry Andric           _InputIterator __last,
496*cb14a3feSDimitry Andric           size_type __n,
497*cb14a3feSDimitry Andric           const hasher& __hf     = hasher(),
4980b57cec5SDimitry Andric           const key_equal& __eql = key_equal());
4990b57cec5SDimitry Andric  template <class _InputIterator>
500*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
501*cb14a3feSDimitry Andric  hash_map(_InputIterator __first,
502*cb14a3feSDimitry Andric           _InputIterator __last,
503*cb14a3feSDimitry Andric           size_type __n,
504*cb14a3feSDimitry Andric           const hasher& __hf,
5050b57cec5SDimitry Andric           const key_equal& __eql,
5060b57cec5SDimitry Andric           const allocator_type& __a);
50706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_map(const hash_map& __u);
5080b57cec5SDimitry Andric
509*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return allocator_type(__table_.__node_alloc()); }
5100b57cec5SDimitry Andric
511*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool empty() const { return __table_.size() == 0; }
512*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type size() const { return __table_.size(); }
513*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_size() const { return __table_.max_size(); }
5140b57cec5SDimitry Andric
515*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() { return __table_.begin(); }
516*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() { return __table_.end(); }
517*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { return __table_.begin(); }
518*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __table_.end(); }
5190b57cec5SDimitry Andric
520*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI std::pair<iterator, bool> insert(const value_type& __x) {
521*cb14a3feSDimitry Andric    return __table_.__insert_unique(__x);
522*cb14a3feSDimitry Andric  }
523*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) { return insert(__x).first; }
5240b57cec5SDimitry Andric  template <class _InputIterator>
525*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last);
5260b57cec5SDimitry Andric
527*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __p) { __table_.erase(__p.__i_); }
528*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __table_.__erase_unique(__k); }
529*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __first, const_iterator __last) {
530*cb14a3feSDimitry Andric    __table_.erase(__first.__i_, __last.__i_);
531*cb14a3feSDimitry Andric  }
532*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void clear() { __table_.clear(); }
5330b57cec5SDimitry Andric
534*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(hash_map& __u) { __table_.swap(__u.__table_); }
5350b57cec5SDimitry Andric
536*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hasher hash_funct() const { return __table_.hash_function().hash_function(); }
537*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq().key_eq(); }
5380b57cec5SDimitry Andric
539*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
540*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
541*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_unique(__k); }
542*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI std::pair<iterator, iterator> equal_range(const key_type& __k) {
543*cb14a3feSDimitry Andric    return __table_.__equal_range_unique(__k);
544*cb14a3feSDimitry Andric  }
545*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
546*cb14a3feSDimitry Andric    return __table_.__equal_range_unique(__k);
547*cb14a3feSDimitry Andric  }
5480b57cec5SDimitry Andric
54906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
5500b57cec5SDimitry Andric
551*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const { return __table_.bucket_count(); }
552*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const { return __table_.max_bucket_count(); }
5530b57cec5SDimitry Andric
554*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type elems_in_bucket(size_type __n) const { return __table_.bucket_size(__n); }
5550b57cec5SDimitry Andric
556*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { __table_.__rehash_unique(__n); }
5570b57cec5SDimitry Andric
5580b57cec5SDimitry Andricprivate:
55906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(const key_type& __k);
5600b57cec5SDimitry Andric};
5610b57cec5SDimitry Andric
5620b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
563*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(size_type __n, const hasher& __hf, const key_equal& __eql)
564*cb14a3feSDimitry Andric    : __table_(__hf, __eql) {
565753f127fSDimitry Andric  __table_.__rehash_unique(__n);
5660b57cec5SDimitry Andric}
5670b57cec5SDimitry Andric
5680b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
5690b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
570*cb14a3feSDimitry Andric    size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
571*cb14a3feSDimitry Andric    : __table_(__hf, __eql, __a) {
572*cb14a3feSDimitry Andric  __table_.__rehash_unique(__n);
573*cb14a3feSDimitry Andric}
574*cb14a3feSDimitry Andric
575*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
576*cb14a3feSDimitry Andrictemplate <class _InputIterator>
577*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(_InputIterator __first, _InputIterator __last) {
578*cb14a3feSDimitry Andric  insert(__first, __last);
579*cb14a3feSDimitry Andric}
580*cb14a3feSDimitry Andric
581*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
582*cb14a3feSDimitry Andrictemplate <class _InputIterator>
583*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
584*cb14a3feSDimitry Andric    _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql)
585*cb14a3feSDimitry Andric    : __table_(__hf, __eql) {
586*cb14a3feSDimitry Andric  __table_.__rehash_unique(__n);
587*cb14a3feSDimitry Andric  insert(__first, __last);
588*cb14a3feSDimitry Andric}
589*cb14a3feSDimitry Andric
590*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
591*cb14a3feSDimitry Andrictemplate <class _InputIterator>
592*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
593*cb14a3feSDimitry Andric    _InputIterator __first,
594*cb14a3feSDimitry Andric    _InputIterator __last,
595*cb14a3feSDimitry Andric    size_type __n,
596*cb14a3feSDimitry Andric    const hasher& __hf,
597*cb14a3feSDimitry Andric    const key_equal& __eql,
5980b57cec5SDimitry Andric    const allocator_type& __a)
599*cb14a3feSDimitry Andric    : __table_(__hf, __eql, __a) {
600753f127fSDimitry Andric  __table_.__rehash_unique(__n);
6010b57cec5SDimitry Andric  insert(__first, __last);
6020b57cec5SDimitry Andric}
6030b57cec5SDimitry Andric
6040b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
605*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(const hash_map& __u) : __table_(__u.__table_) {
606753f127fSDimitry Andric  __table_.__rehash_unique(__u.bucket_count());
6070b57cec5SDimitry Andric  insert(__u.begin(), __u.end());
6080b57cec5SDimitry Andric}
6090b57cec5SDimitry Andric
6100b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6110b57cec5SDimitry Andrictypename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
612*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k) {
6130b57cec5SDimitry Andric  __node_allocator& __na = __table_.__node_alloc();
6140b57cec5SDimitry Andric  __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
6155f757f3fSDimitry Andric  __node_traits::construct(__na, std::addressof(__h->__get_value().first), __k);
6160b57cec5SDimitry Andric  __h.get_deleter().__first_constructed = true;
6175f757f3fSDimitry Andric  __node_traits::construct(__na, std::addressof(__h->__get_value().second));
6180b57cec5SDimitry Andric  __h.get_deleter().__second_constructed = true;
619e8d8bef9SDimitry Andric  return __h;
6200b57cec5SDimitry Andric}
6210b57cec5SDimitry Andric
6220b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6230b57cec5SDimitry Andrictemplate <class _InputIterator>
624*cb14a3feSDimitry Andricinline void hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) {
6250b57cec5SDimitry Andric  for (; __first != __last; ++__first)
6260b57cec5SDimitry Andric    __table_.__insert_unique(*__first);
6270b57cec5SDimitry Andric}
6280b57cec5SDimitry Andric
6290b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
630*cb14a3feSDimitry Andric_Tp& hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) {
6310b57cec5SDimitry Andric  iterator __i = find(__k);
6320b57cec5SDimitry Andric  if (__i != end())
6330b57cec5SDimitry Andric    return __i->second;
6340b57cec5SDimitry Andric  __node_holder __h             = __construct_node(__k);
6350b57cec5SDimitry Andric  std::pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
6360b57cec5SDimitry Andric  __h.release();
6370b57cec5SDimitry Andric  return __r.first->second;
6380b57cec5SDimitry Andric}
6390b57cec5SDimitry Andric
6400b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
641*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
642*cb14a3feSDimitry Andricswap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) {
6430b57cec5SDimitry Andric  __x.swap(__y);
6440b57cec5SDimitry Andric}
6450b57cec5SDimitry Andric
6460b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
647bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool
648*cb14a3feSDimitry Andricoperator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) {
6490b57cec5SDimitry Andric  if (__x.size() != __y.size())
6500b57cec5SDimitry Andric    return false;
651*cb14a3feSDimitry Andric  typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator const_iterator;
652*cb14a3feSDimitry Andric  for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); __i != __ex; ++__i) {
6530b57cec5SDimitry Andric    const_iterator __j = __y.find(__i->first);
6540b57cec5SDimitry Andric    if (__j == __ey || !(*__i == *__j))
6550b57cec5SDimitry Andric      return false;
6560b57cec5SDimitry Andric  }
6570b57cec5SDimitry Andric  return true;
6580b57cec5SDimitry Andric}
6590b57cec5SDimitry Andric
6600b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
661*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
662*cb14a3feSDimitry Andricoperator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) {
6630b57cec5SDimitry Andric  return !(__x == __y);
6640b57cec5SDimitry Andric}
6650b57cec5SDimitry Andric
666*cb14a3feSDimitry Andrictemplate <class _Key,
667*cb14a3feSDimitry Andric          class _Tp,
668*cb14a3feSDimitry Andric          class _Hash  = hash<_Key>,
669*cb14a3feSDimitry Andric          class _Pred  = std::equal_to<_Key>,
6700b57cec5SDimitry Andric          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
671*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_multimap {
6720b57cec5SDimitry Andricpublic:
6730b57cec5SDimitry Andric  // types
6740b57cec5SDimitry Andric  typedef _Key key_type;
6750b57cec5SDimitry Andric  typedef _Tp mapped_type;
6760b57cec5SDimitry Andric  typedef _Tp data_type;
6770b57cec5SDimitry Andric  typedef _Hash hasher;
6780b57cec5SDimitry Andric  typedef _Pred key_equal;
6790b57cec5SDimitry Andric  typedef _Alloc allocator_type;
6800b57cec5SDimitry Andric  typedef std::pair<const key_type, mapped_type> value_type;
6810b57cec5SDimitry Andric  typedef value_type& reference;
6820b57cec5SDimitry Andric  typedef const value_type& const_reference;
6830b57cec5SDimitry Andric
6840b57cec5SDimitry Andricprivate:
6850b57cec5SDimitry Andric  typedef std::pair<key_type, mapped_type> __value_type;
6860b57cec5SDimitry Andric  typedef __hash_map_hasher<__value_type, hasher> __hasher;
6870b57cec5SDimitry Andric  typedef __hash_map_equal<__value_type, key_equal> __key_equal;
688bdd1243dSDimitry Andric  typedef std::__rebind_alloc<std::allocator_traits<allocator_type>, __value_type> __allocator_type;
6890b57cec5SDimitry Andric
690*cb14a3feSDimitry Andric  typedef std::__hash_table<__value_type, __hasher, __key_equal, __allocator_type> __table;
6910b57cec5SDimitry Andric
6920b57cec5SDimitry Andric  __table __table_;
6930b57cec5SDimitry Andric
6940b57cec5SDimitry Andric  typedef typename __table::__node_traits __node_traits;
6950b57cec5SDimitry Andric  typedef typename __table::__node_allocator __node_allocator;
6960b57cec5SDimitry Andric  typedef typename __table::__node __node;
6970b57cec5SDimitry Andric  typedef __hash_map_node_destructor<__node_allocator> _Dp;
6980b57cec5SDimitry Andric  typedef std::unique_ptr<__node, _Dp> __node_holder;
6990b57cec5SDimitry Andric  typedef std::allocator_traits<allocator_type> __alloc_traits;
700*cb14a3feSDimitry Andric
7010b57cec5SDimitry Andricpublic:
7020b57cec5SDimitry Andric  typedef typename __alloc_traits::pointer pointer;
7030b57cec5SDimitry Andric  typedef typename __alloc_traits::const_pointer const_pointer;
7040b57cec5SDimitry Andric  typedef typename __alloc_traits::size_type size_type;
7050b57cec5SDimitry Andric  typedef typename __alloc_traits::difference_type difference_type;
7060b57cec5SDimitry Andric
7070b57cec5SDimitry Andric  typedef __hash_map_iterator<typename __table::iterator> iterator;
7080b57cec5SDimitry Andric  typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
7090b57cec5SDimitry Andric
710*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_multimap() {}
711*cb14a3feSDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI
712*cb14a3feSDimitry Andric  hash_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
7135f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
714*cb14a3feSDimitry Andric  hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a);
7150b57cec5SDimitry Andric  template <class _InputIterator>
71606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last);
7170b57cec5SDimitry Andric  template <class _InputIterator>
718*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI
719*cb14a3feSDimitry Andric  hash_multimap(_InputIterator __first,
720*cb14a3feSDimitry Andric                _InputIterator __last,
721*cb14a3feSDimitry Andric                size_type __n,
722*cb14a3feSDimitry Andric                const hasher& __hf     = hasher(),
7230b57cec5SDimitry Andric                const key_equal& __eql = key_equal());
7240b57cec5SDimitry Andric  template <class _InputIterator>
725*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_multimap(
726*cb14a3feSDimitry Andric      _InputIterator __first,
727*cb14a3feSDimitry Andric      _InputIterator __last,
728*cb14a3feSDimitry Andric      size_type __n,
729*cb14a3feSDimitry Andric      const hasher& __hf,
7300b57cec5SDimitry Andric      const key_equal& __eql,
7310b57cec5SDimitry Andric      const allocator_type& __a);
73206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI hash_multimap(const hash_multimap& __u);
7330b57cec5SDimitry Andric
734*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return allocator_type(__table_.__node_alloc()); }
7350b57cec5SDimitry Andric
736*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool empty() const { return __table_.size() == 0; }
737*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type size() const { return __table_.size(); }
738*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_size() const { return __table_.max_size(); }
7390b57cec5SDimitry Andric
740*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() { return __table_.begin(); }
741*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() { return __table_.end(); }
742*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { return __table_.begin(); }
743*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __table_.end(); }
7440b57cec5SDimitry Andric
745*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return __table_.__insert_multi(__x); }
746*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) { return insert(__x); }
7470b57cec5SDimitry Andric  template <class _InputIterator>
748*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last);
7490b57cec5SDimitry Andric
750*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __p) { __table_.erase(__p.__i_); }
751*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __table_.__erase_multi(__k); }
752*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __first, const_iterator __last) {
753*cb14a3feSDimitry Andric    __table_.erase(__first.__i_, __last.__i_);
754*cb14a3feSDimitry Andric  }
755*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void clear() { __table_.clear(); }
7560b57cec5SDimitry Andric
757*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(hash_multimap& __u) { __table_.swap(__u.__table_); }
7580b57cec5SDimitry Andric
759*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI hasher hash_funct() const { return __table_.hash_function().hash_function(); }
760*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq().key_eq(); }
7610b57cec5SDimitry Andric
762*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); }
763*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); }
764*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_multi(__k); }
765*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI std::pair<iterator, iterator> equal_range(const key_type& __k) {
766*cb14a3feSDimitry Andric    return __table_.__equal_range_multi(__k);
767*cb14a3feSDimitry Andric  }
768*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
769*cb14a3feSDimitry Andric    return __table_.__equal_range_multi(__k);
770*cb14a3feSDimitry Andric  }
7710b57cec5SDimitry Andric
772*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const { return __table_.bucket_count(); }
773*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const { return __table_.max_bucket_count(); }
7740b57cec5SDimitry Andric
775*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type elems_in_bucket(size_type __n) const { return __table_.bucket_size(__n); }
7760b57cec5SDimitry Andric
777*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { __table_.__rehash_multi(__n); }
7780b57cec5SDimitry Andric};
7790b57cec5SDimitry Andric
7800b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
781*cb14a3feSDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql)
782*cb14a3feSDimitry Andric    : __table_(__hf, __eql) {
783753f127fSDimitry Andric  __table_.__rehash_multi(__n);
7840b57cec5SDimitry Andric}
7850b57cec5SDimitry Andric
7860b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
7870b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
788*cb14a3feSDimitry Andric    size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
789*cb14a3feSDimitry Andric    : __table_(__hf, __eql, __a) {
790*cb14a3feSDimitry Andric  __table_.__rehash_multi(__n);
791*cb14a3feSDimitry Andric}
792*cb14a3feSDimitry Andric
793*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
794*cb14a3feSDimitry Andrictemplate <class _InputIterator>
795*cb14a3feSDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(_InputIterator __first, _InputIterator __last) {
796*cb14a3feSDimitry Andric  insert(__first, __last);
797*cb14a3feSDimitry Andric}
798*cb14a3feSDimitry Andric
799*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
800*cb14a3feSDimitry Andrictemplate <class _InputIterator>
801*cb14a3feSDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
802*cb14a3feSDimitry Andric    _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql)
803*cb14a3feSDimitry Andric    : __table_(__hf, __eql) {
804*cb14a3feSDimitry Andric  __table_.__rehash_multi(__n);
805*cb14a3feSDimitry Andric  insert(__first, __last);
806*cb14a3feSDimitry Andric}
807*cb14a3feSDimitry Andric
808*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
809*cb14a3feSDimitry Andrictemplate <class _InputIterator>
810*cb14a3feSDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
811*cb14a3feSDimitry Andric    _InputIterator __first,
812*cb14a3feSDimitry Andric    _InputIterator __last,
813*cb14a3feSDimitry Andric    size_type __n,
814*cb14a3feSDimitry Andric    const hasher& __hf,
815*cb14a3feSDimitry Andric    const key_equal& __eql,
8160b57cec5SDimitry Andric    const allocator_type& __a)
817*cb14a3feSDimitry Andric    : __table_(__hf, __eql, __a) {
818753f127fSDimitry Andric  __table_.__rehash_multi(__n);
8190b57cec5SDimitry Andric  insert(__first, __last);
8200b57cec5SDimitry Andric}
8210b57cec5SDimitry Andric
8220b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
823*cb14a3feSDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(const hash_multimap& __u) : __table_(__u.__table_) {
824753f127fSDimitry Andric  __table_.__rehash_multi(__u.bucket_count());
8250b57cec5SDimitry Andric  insert(__u.begin(), __u.end());
8260b57cec5SDimitry Andric}
8270b57cec5SDimitry Andric
8280b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
8290b57cec5SDimitry Andrictemplate <class _InputIterator>
830*cb14a3feSDimitry Andricinline void hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) {
8310b57cec5SDimitry Andric  for (; __first != __last; ++__first)
8320b57cec5SDimitry Andric    __table_.__insert_multi(*__first);
8330b57cec5SDimitry Andric}
8340b57cec5SDimitry Andric
8350b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
836*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
837*cb14a3feSDimitry Andricswap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) {
8380b57cec5SDimitry Andric  __x.swap(__y);
8390b57cec5SDimitry Andric}
8400b57cec5SDimitry Andric
8410b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
842*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
843*cb14a3feSDimitry Andric                                      const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) {
8440b57cec5SDimitry Andric  if (__x.size() != __y.size())
8450b57cec5SDimitry Andric    return false;
846*cb14a3feSDimitry Andric  typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator const_iterator;
8470b57cec5SDimitry Andric  typedef std::pair<const_iterator, const_iterator> _EqRng;
848*cb14a3feSDimitry Andric  for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) {
8490b57cec5SDimitry Andric    _EqRng __xeq = __x.equal_range(__i->first);
8500b57cec5SDimitry Andric    _EqRng __yeq = __y.equal_range(__i->first);
851*cb14a3feSDimitry Andric    if (std::distance(__xeq.first, __xeq.second) != std::distance(__yeq.first, __yeq.second) ||
8525f757f3fSDimitry Andric        !std::is_permutation(__xeq.first, __xeq.second, __yeq.first))
8530b57cec5SDimitry Andric      return false;
8540b57cec5SDimitry Andric    __i = __xeq.second;
8550b57cec5SDimitry Andric  }
8560b57cec5SDimitry Andric  return true;
8570b57cec5SDimitry Andric}
8580b57cec5SDimitry Andric
8590b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
860*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
861*cb14a3feSDimitry Andric                                             const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) {
8620b57cec5SDimitry Andric  return !(__x == __y);
8630b57cec5SDimitry Andric}
8640b57cec5SDimitry Andric
8650eae32dcSDimitry Andric} // namespace __gnu_cxx
8660b57cec5SDimitry Andric
867bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
868bdd1243dSDimitry Andric#  include <concepts>
869bdd1243dSDimitry Andric#  include <iterator>
87006c3fb27SDimitry Andric#  include <type_traits>
871bdd1243dSDimitry Andric#endif
872bdd1243dSDimitry Andric
8730b57cec5SDimitry Andric#endif // _LIBCPP_HASH_MAP
874