xref: /freebsd/contrib/llvm-project/libcxx/include/ext/hash_map (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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
2250b57cec5SDimitry Andrictemplate <class _Tp, class _Hash,
2260b57cec5SDimitry Andric          bool = std::is_empty<_Hash>::value && !std::__libcpp_is_final<_Hash>::value
2270b57cec5SDimitry Andric        >
2280b57cec5SDimitry Andricclass __hash_map_hasher
2290b57cec5SDimitry Andric    : private _Hash
2300b57cec5SDimitry Andric{
2310b57cec5SDimitry Andricpublic:
232*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_hasher() : _Hash() {}
233*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_hasher(const _Hash& __h) : _Hash(__h) {}
234*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI const _Hash& hash_function() const {return *this;}
235*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2360b57cec5SDimitry Andric    size_t operator()(const _Tp& __x) const
2370b57cec5SDimitry Andric        {return static_cast<const _Hash&>(*this)(__x.first);}
238*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2390b57cec5SDimitry Andric    size_t operator()(const typename _Tp::first_type& __x) const
2400b57cec5SDimitry Andric        {return static_cast<const _Hash&>(*this)(__x);}
2410b57cec5SDimitry Andric};
2420b57cec5SDimitry Andric
2430b57cec5SDimitry Andrictemplate <class _Tp, class _Hash>
2440b57cec5SDimitry Andricclass __hash_map_hasher<_Tp, _Hash, false>
2450b57cec5SDimitry Andric{
2460b57cec5SDimitry Andric    _Hash __hash_;
2470b57cec5SDimitry Andricpublic:
248*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_hasher() : __hash_() {}
249*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_hasher(const _Hash& __h) : __hash_(__h) {}
250*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI const _Hash& hash_function() const {return __hash_;}
251*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2520b57cec5SDimitry Andric    size_t operator()(const _Tp& __x) const
2530b57cec5SDimitry Andric        {return __hash_(__x.first);}
254*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2550b57cec5SDimitry Andric    size_t operator()(const typename _Tp::first_type& __x) const
2560b57cec5SDimitry Andric        {return __hash_(__x);}
2570b57cec5SDimitry Andric};
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andrictemplate <class _Tp, class _Pred,
2600b57cec5SDimitry Andric          bool = std::is_empty<_Pred>::value && !std::__libcpp_is_final<_Pred>::value
2610b57cec5SDimitry Andric         >
2620b57cec5SDimitry Andricclass __hash_map_equal
2630b57cec5SDimitry Andric    : private _Pred
2640b57cec5SDimitry Andric{
2650b57cec5SDimitry Andricpublic:
266*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_equal() : _Pred() {}
267*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_equal(const _Pred& __p) : _Pred(__p) {}
268*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI const _Pred& key_eq() const {return *this;}
269*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2700b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
2710b57cec5SDimitry Andric        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
272*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2730b57cec5SDimitry Andric    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
2740b57cec5SDimitry Andric        {return static_cast<const _Pred&>(*this)(__x, __y.first);}
275*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2760b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
2770b57cec5SDimitry Andric        {return static_cast<const _Pred&>(*this)(__x.first, __y);}
278*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2790b57cec5SDimitry Andric    bool operator()(const typename _Tp::first_type& __x,
2800b57cec5SDimitry Andric                    const typename _Tp::first_type& __y) const
2810b57cec5SDimitry Andric        {return static_cast<const _Pred&>(*this)(__x, __y);}
2820b57cec5SDimitry Andric};
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andrictemplate <class _Tp, class _Pred>
2850b57cec5SDimitry Andricclass __hash_map_equal<_Tp, _Pred, false>
2860b57cec5SDimitry Andric{
2870b57cec5SDimitry Andric    _Pred __pred_;
2880b57cec5SDimitry Andricpublic:
289*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_equal() : __pred_() {}
290*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_equal(const _Pred& __p) : __pred_(__p) {}
291*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI const _Pred& key_eq() const {return __pred_;}
292*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2930b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
2940b57cec5SDimitry Andric        {return __pred_(__x.first, __y.first);}
295*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2960b57cec5SDimitry Andric    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
2970b57cec5SDimitry Andric        {return __pred_(__x, __y.first);}
298*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2990b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
3000b57cec5SDimitry Andric        {return __pred_(__x.first, __y);}
301*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3020b57cec5SDimitry Andric    bool operator()(const typename _Tp::first_type& __x,
3030b57cec5SDimitry Andric                    const typename _Tp::first_type& __y) const
3040b57cec5SDimitry Andric        {return __pred_(__x, __y);}
3050b57cec5SDimitry Andric};
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andrictemplate <class _Alloc>
3080b57cec5SDimitry Andricclass __hash_map_node_destructor
3090b57cec5SDimitry Andric{
3100b57cec5SDimitry Andric    typedef _Alloc                              allocator_type;
3110b57cec5SDimitry Andric    typedef std::allocator_traits<allocator_type>    __alloc_traits;
3120b57cec5SDimitry Andric    typedef typename __alloc_traits::value_type::__node_value_type value_type;
3130b57cec5SDimitry Andricpublic:
3140b57cec5SDimitry Andric    typedef typename __alloc_traits::pointer    pointer;
3150b57cec5SDimitry Andricprivate:
3160b57cec5SDimitry Andric    typedef typename value_type::first_type     first_type;
3170b57cec5SDimitry Andric    typedef typename value_type::second_type    second_type;
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric    allocator_type& __na_;
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andricpublic:
3220b57cec5SDimitry Andric    bool __first_constructed;
3230b57cec5SDimitry Andric    bool __second_constructed;
3240b57cec5SDimitry Andric
32506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_node_destructor(__hash_map_node_destructor const&) = default;
326cd0c3137SDimitry Andric    __hash_map_node_destructor& operator=(const __hash_map_node_destructor&) = delete;
327cd0c3137SDimitry Andric
328*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3290b57cec5SDimitry Andric    explicit __hash_map_node_destructor(allocator_type& __na)
3300b57cec5SDimitry Andric        : __na_(__na),
3310b57cec5SDimitry Andric          __first_constructed(false),
3320b57cec5SDimitry Andric          __second_constructed(false)
3330b57cec5SDimitry Andric        {}
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
336*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3370b57cec5SDimitry Andric    __hash_map_node_destructor(std::__hash_node_destructor<allocator_type>&& __x)
3380b57cec5SDimitry Andric        : __na_(__x.__na_),
3390b57cec5SDimitry Andric          __first_constructed(__x.__value_constructed),
3400b57cec5SDimitry Andric          __second_constructed(__x.__value_constructed)
3410b57cec5SDimitry Andric        {
3420b57cec5SDimitry Andric            __x.__value_constructed = false;
3430b57cec5SDimitry Andric        }
3440b57cec5SDimitry Andric#else  // _LIBCPP_CXX03_LANG
345*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3460b57cec5SDimitry Andric    __hash_map_node_destructor(const std::__hash_node_destructor<allocator_type>& __x)
3470b57cec5SDimitry Andric        : __na_(__x.__na_),
3480b57cec5SDimitry Andric          __first_constructed(__x.__value_constructed),
3490b57cec5SDimitry Andric          __second_constructed(__x.__value_constructed)
3500b57cec5SDimitry Andric        {
3510b57cec5SDimitry Andric            const_cast<bool&>(__x.__value_constructed) = false;
3520b57cec5SDimitry Andric        }
3530b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
3540b57cec5SDimitry Andric
355*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3560b57cec5SDimitry Andric    void operator()(pointer __p)
3570b57cec5SDimitry Andric    {
3580b57cec5SDimitry Andric        if (__second_constructed)
359*5f757f3fSDimitry Andric            __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().second));
3600b57cec5SDimitry Andric        if (__first_constructed)
361*5f757f3fSDimitry Andric            __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().first));
3620b57cec5SDimitry Andric        if (__p)
3630b57cec5SDimitry Andric            __alloc_traits::deallocate(__na_, __p, 1);
3640b57cec5SDimitry Andric    }
3650b57cec5SDimitry Andric};
3660b57cec5SDimitry Andric
3670b57cec5SDimitry Andrictemplate <class _HashIterator>
3680b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_iterator
3690b57cec5SDimitry Andric{
3700b57cec5SDimitry Andric    _HashIterator __i_;
3710b57cec5SDimitry Andric
3720b57cec5SDimitry Andric    typedef const typename _HashIterator::value_type::first_type key_type;
3730b57cec5SDimitry Andric    typedef typename _HashIterator::value_type::second_type      mapped_type;
3740b57cec5SDimitry Andricpublic:
3750b57cec5SDimitry Andric    typedef std::forward_iterator_tag                            iterator_category;
3760b57cec5SDimitry Andric    typedef std::pair<key_type, mapped_type>                     value_type;
3770b57cec5SDimitry Andric    typedef typename _HashIterator::difference_type              difference_type;
3780b57cec5SDimitry Andric    typedef value_type&                                          reference;
379bdd1243dSDimitry Andric    typedef std::__rebind_pointer_t<typename _HashIterator::pointer, value_type>
3800b57cec5SDimitry Andric        pointer;
3810b57cec5SDimitry Andric
382*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_iterator() {}
3830b57cec5SDimitry Andric
384*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_iterator(_HashIterator __i) : __i_(__i) {}
3850b57cec5SDimitry Andric
386*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI reference operator*() const {return *operator->();}
387*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI pointer operator->() const {return (pointer)__i_.operator->();}
3880b57cec5SDimitry Andric
389*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_iterator& operator++() {++__i_; return *this;}
390*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
3910b57cec5SDimitry Andric    __hash_map_iterator operator++(int)
3920b57cec5SDimitry Andric    {
3930b57cec5SDimitry Andric        __hash_map_iterator __t(*this);
3940b57cec5SDimitry Andric        ++(*this);
3950b57cec5SDimitry Andric        return __t;
3960b57cec5SDimitry Andric    }
3970b57cec5SDimitry Andric
398*5f757f3fSDimitry Andric    friend _LIBCPP_HIDE_FROM_ABI
3990b57cec5SDimitry Andric    bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
4000b57cec5SDimitry Andric        {return __x.__i_ == __y.__i_;}
401*5f757f3fSDimitry Andric    friend _LIBCPP_HIDE_FROM_ABI
4020b57cec5SDimitry Andric    bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
4030b57cec5SDimitry Andric        {return __x.__i_ != __y.__i_;}
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map;
4060b57cec5SDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
4070b57cec5SDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
4080b57cec5SDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
4090b57cec5SDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
4100b57cec5SDimitry Andric};
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andrictemplate <class _HashIterator>
4130b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator
4140b57cec5SDimitry Andric{
4150b57cec5SDimitry Andric    _HashIterator __i_;
4160b57cec5SDimitry Andric
4170b57cec5SDimitry Andric    typedef const typename _HashIterator::value_type::first_type key_type;
4180b57cec5SDimitry Andric    typedef typename _HashIterator::value_type::second_type      mapped_type;
4190b57cec5SDimitry Andricpublic:
4200b57cec5SDimitry Andric    typedef std::forward_iterator_tag                            iterator_category;
4210b57cec5SDimitry Andric    typedef std::pair<key_type, mapped_type>                     value_type;
4220b57cec5SDimitry Andric    typedef typename _HashIterator::difference_type              difference_type;
4230b57cec5SDimitry Andric    typedef const value_type&                                    reference;
424bdd1243dSDimitry Andric    typedef std::__rebind_pointer_t<typename _HashIterator::pointer, const value_type>
4250b57cec5SDimitry Andric        pointer;
4260b57cec5SDimitry Andric
427*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator() {}
4280b57cec5SDimitry Andric
429*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
4300b57cec5SDimitry Andric    __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {}
431*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
4320b57cec5SDimitry Andric    __hash_map_const_iterator(
4330b57cec5SDimitry Andric            __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
4340b57cec5SDimitry Andric                : __i_(__i.__i_) {}
4350b57cec5SDimitry Andric
436*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
4370b57cec5SDimitry Andric    reference operator*() const {return *operator->();}
438*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
4390b57cec5SDimitry Andric    pointer operator->() const {return (pointer)__i_.operator->();}
4400b57cec5SDimitry Andric
441*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
4420b57cec5SDimitry Andric    __hash_map_const_iterator& operator++() {++__i_; return *this;}
443*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
4440b57cec5SDimitry Andric    __hash_map_const_iterator operator++(int)
4450b57cec5SDimitry Andric    {
4460b57cec5SDimitry Andric        __hash_map_const_iterator __t(*this);
4470b57cec5SDimitry Andric        ++(*this);
4480b57cec5SDimitry Andric        return __t;
4490b57cec5SDimitry Andric    }
4500b57cec5SDimitry Andric
451*5f757f3fSDimitry Andric    friend _LIBCPP_HIDE_FROM_ABI
4520b57cec5SDimitry Andric    bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
4530b57cec5SDimitry Andric        {return __x.__i_ == __y.__i_;}
454*5f757f3fSDimitry Andric    friend _LIBCPP_HIDE_FROM_ABI
4550b57cec5SDimitry Andric    bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
4560b57cec5SDimitry Andric        {return __x.__i_ != __y.__i_;}
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map;
4590b57cec5SDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
4600b57cec5SDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
4610b57cec5SDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
4620b57cec5SDimitry Andric};
4630b57cec5SDimitry Andric
4640b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>,
4650b57cec5SDimitry Andric          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
4660b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_map
4670b57cec5SDimitry Andric{
4680b57cec5SDimitry Andricpublic:
4690b57cec5SDimitry Andric    // types
4700b57cec5SDimitry Andric    typedef _Key                                           key_type;
4710b57cec5SDimitry Andric    typedef _Tp                                            mapped_type;
4720b57cec5SDimitry Andric    typedef _Tp                                            data_type;
4730b57cec5SDimitry Andric    typedef _Hash                                          hasher;
4740b57cec5SDimitry Andric    typedef _Pred                                          key_equal;
4750b57cec5SDimitry Andric    typedef _Alloc                                         allocator_type;
4760b57cec5SDimitry Andric    typedef std::pair<const key_type, mapped_type>         value_type;
4770b57cec5SDimitry Andric    typedef value_type&                                    reference;
4780b57cec5SDimitry Andric    typedef const value_type&                              const_reference;
4790b57cec5SDimitry Andric
4800b57cec5SDimitry Andricprivate:
4810b57cec5SDimitry Andric    typedef std::pair<key_type, mapped_type>                    __value_type;
4820b57cec5SDimitry Andric    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
4830b57cec5SDimitry Andric    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
484bdd1243dSDimitry Andric    typedef std::__rebind_alloc<std::allocator_traits<allocator_type>, __value_type> __allocator_type;
4850b57cec5SDimitry Andric
4860b57cec5SDimitry Andric    typedef std::__hash_table<__value_type, __hasher,
4870b57cec5SDimitry Andric                         __key_equal,  __allocator_type>   __table;
4880b57cec5SDimitry Andric
4890b57cec5SDimitry Andric    __table __table_;
4900b57cec5SDimitry Andric
4910b57cec5SDimitry Andric    typedef typename __table::__node_pointer               __node_pointer;
4920b57cec5SDimitry Andric    typedef typename __table::__node_const_pointer         __node_const_pointer;
4930b57cec5SDimitry Andric    typedef typename __table::__node_traits                __node_traits;
4940b57cec5SDimitry Andric    typedef typename __table::__node_allocator             __node_allocator;
4950b57cec5SDimitry Andric    typedef typename __table::__node                       __node;
4960b57cec5SDimitry Andric    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
4970b57cec5SDimitry Andric    typedef std::unique_ptr<__node, _Dp>                   __node_holder;
4980b57cec5SDimitry Andric    typedef std::allocator_traits<allocator_type>          __alloc_traits;
4990b57cec5SDimitry Andricpublic:
5000b57cec5SDimitry Andric    typedef typename __alloc_traits::pointer         pointer;
5010b57cec5SDimitry Andric    typedef typename __alloc_traits::const_pointer   const_pointer;
5020b57cec5SDimitry Andric    typedef typename __alloc_traits::size_type       size_type;
5030b57cec5SDimitry Andric    typedef typename __alloc_traits::difference_type difference_type;
5040b57cec5SDimitry Andric
5050b57cec5SDimitry Andric    typedef __hash_map_iterator<typename __table::iterator>       iterator;
5060b57cec5SDimitry Andric    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
5070b57cec5SDimitry Andric
508*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_map() { }
50906c3fb27SDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI hash_map(size_type __n, const hasher& __hf = hasher(),
5100b57cec5SDimitry Andric                           const key_equal& __eql = key_equal());
51106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_map(size_type __n, const hasher& __hf,
5120b57cec5SDimitry Andric                  const key_equal& __eql,
5130b57cec5SDimitry Andric                  const allocator_type& __a);
5140b57cec5SDimitry Andric    template <class _InputIterator>
51506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last);
5160b57cec5SDimitry Andric    template <class _InputIterator>
51706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last,
5180b57cec5SDimitry Andric                      size_type __n, const hasher& __hf = hasher(),
5190b57cec5SDimitry Andric                      const key_equal& __eql = key_equal());
5200b57cec5SDimitry Andric    template <class _InputIterator>
52106c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last,
5220b57cec5SDimitry Andric                      size_type __n, const hasher& __hf,
5230b57cec5SDimitry Andric                      const key_equal& __eql,
5240b57cec5SDimitry Andric                      const allocator_type& __a);
52506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_map(const hash_map& __u);
5260b57cec5SDimitry Andric
527*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5280b57cec5SDimitry Andric    allocator_type get_allocator() const
5290b57cec5SDimitry Andric        {return allocator_type(__table_.__node_alloc());}
5300b57cec5SDimitry Andric
531*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5320b57cec5SDimitry Andric    bool      empty() const {return __table_.size() == 0;}
533*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5340b57cec5SDimitry Andric    size_type size() const  {return __table_.size();}
535*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5360b57cec5SDimitry Andric    size_type max_size() const {return __table_.max_size();}
5370b57cec5SDimitry Andric
538*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5390b57cec5SDimitry Andric    iterator       begin()        {return __table_.begin();}
540*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5410b57cec5SDimitry Andric    iterator       end()          {return __table_.end();}
542*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5430b57cec5SDimitry Andric    const_iterator begin()  const {return __table_.begin();}
544*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5450b57cec5SDimitry Andric    const_iterator end()    const {return __table_.end();}
5460b57cec5SDimitry Andric
547*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5480b57cec5SDimitry Andric    std::pair<iterator, bool> insert(const value_type& __x)
5490b57cec5SDimitry Andric        {return __table_.__insert_unique(__x);}
550*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5510b57cec5SDimitry Andric    iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}
5520b57cec5SDimitry Andric    template <class _InputIterator>
553*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
5540b57cec5SDimitry Andric        void insert(_InputIterator __first, _InputIterator __last);
5550b57cec5SDimitry Andric
556*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5570b57cec5SDimitry Andric    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
558*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5590b57cec5SDimitry Andric    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
560*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5610b57cec5SDimitry Andric    void erase(const_iterator __first, const_iterator __last)
5620b57cec5SDimitry Andric        {__table_.erase(__first.__i_, __last.__i_);}
563*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5640b57cec5SDimitry Andric    void clear() {__table_.clear();}
5650b57cec5SDimitry Andric
566*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5670b57cec5SDimitry Andric    void swap(hash_map& __u) {__table_.swap(__u.__table_);}
5680b57cec5SDimitry Andric
569*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5700b57cec5SDimitry Andric    hasher hash_funct() const
5710b57cec5SDimitry Andric        {return __table_.hash_function().hash_function();}
572*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5730b57cec5SDimitry Andric    key_equal key_eq() const
5740b57cec5SDimitry Andric        {return __table_.key_eq().key_eq();}
5750b57cec5SDimitry Andric
576*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5770b57cec5SDimitry Andric    iterator       find(const key_type& __k)       {return __table_.find(__k);}
578*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5790b57cec5SDimitry Andric    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
580*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5810b57cec5SDimitry Andric    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
582*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5830b57cec5SDimitry Andric    std::pair<iterator, iterator>             equal_range(const key_type& __k)
5840b57cec5SDimitry Andric        {return __table_.__equal_range_unique(__k);}
585*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5860b57cec5SDimitry Andric    std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
5870b57cec5SDimitry Andric        {return __table_.__equal_range_unique(__k);}
5880b57cec5SDimitry Andric
58906c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
5900b57cec5SDimitry Andric
591*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5920b57cec5SDimitry Andric    size_type bucket_count() const {return __table_.bucket_count();}
593*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5940b57cec5SDimitry Andric    size_type max_bucket_count() const {return __table_.max_bucket_count();}
5950b57cec5SDimitry Andric
596*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
5970b57cec5SDimitry Andric    size_type elems_in_bucket(size_type __n) const
5980b57cec5SDimitry Andric        {return __table_.bucket_size(__n);}
5990b57cec5SDimitry Andric
600*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
601753f127fSDimitry Andric    void resize(size_type __n) {__table_.__rehash_unique(__n);}
6020b57cec5SDimitry Andric
6030b57cec5SDimitry Andricprivate:
60406c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(const key_type& __k);
6050b57cec5SDimitry Andric};
6060b57cec5SDimitry Andric
6070b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6080b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6090b57cec5SDimitry Andric        size_type __n, const hasher& __hf, const key_equal& __eql)
6100b57cec5SDimitry Andric    : __table_(__hf, __eql)
6110b57cec5SDimitry Andric{
612753f127fSDimitry Andric    __table_.__rehash_unique(__n);
6130b57cec5SDimitry Andric}
6140b57cec5SDimitry Andric
6150b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6160b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6170b57cec5SDimitry Andric        size_type __n, const hasher& __hf, const key_equal& __eql,
6180b57cec5SDimitry Andric        const allocator_type& __a)
6190b57cec5SDimitry Andric    : __table_(__hf, __eql, __a)
6200b57cec5SDimitry Andric{
621753f127fSDimitry Andric    __table_.__rehash_unique(__n);
6220b57cec5SDimitry Andric}
6230b57cec5SDimitry Andric
6240b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6250b57cec5SDimitry Andrictemplate <class _InputIterator>
6260b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6270b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last)
6280b57cec5SDimitry Andric{
6290b57cec5SDimitry Andric    insert(__first, __last);
6300b57cec5SDimitry Andric}
6310b57cec5SDimitry Andric
6320b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6330b57cec5SDimitry Andrictemplate <class _InputIterator>
6340b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6350b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last, size_type __n,
6360b57cec5SDimitry Andric        const hasher& __hf, const key_equal& __eql)
6370b57cec5SDimitry Andric    : __table_(__hf, __eql)
6380b57cec5SDimitry Andric{
639753f127fSDimitry Andric    __table_.__rehash_unique(__n);
6400b57cec5SDimitry Andric    insert(__first, __last);
6410b57cec5SDimitry Andric}
6420b57cec5SDimitry Andric
6430b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6440b57cec5SDimitry Andrictemplate <class _InputIterator>
6450b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6460b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last, size_type __n,
6470b57cec5SDimitry Andric        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
6480b57cec5SDimitry Andric    : __table_(__hf, __eql, __a)
6490b57cec5SDimitry Andric{
650753f127fSDimitry Andric    __table_.__rehash_unique(__n);
6510b57cec5SDimitry Andric    insert(__first, __last);
6520b57cec5SDimitry Andric}
6530b57cec5SDimitry Andric
6540b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6550b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6560b57cec5SDimitry Andric        const hash_map& __u)
6570b57cec5SDimitry Andric    : __table_(__u.__table_)
6580b57cec5SDimitry Andric{
659753f127fSDimitry Andric    __table_.__rehash_unique(__u.bucket_count());
6600b57cec5SDimitry Andric    insert(__u.begin(), __u.end());
6610b57cec5SDimitry Andric}
6620b57cec5SDimitry Andric
6630b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6640b57cec5SDimitry Andrictypename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
6650b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k)
6660b57cec5SDimitry Andric{
6670b57cec5SDimitry Andric    __node_allocator& __na = __table_.__node_alloc();
6680b57cec5SDimitry Andric    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
669*5f757f3fSDimitry Andric    __node_traits::construct(__na, std::addressof(__h->__get_value().first), __k);
6700b57cec5SDimitry Andric    __h.get_deleter().__first_constructed = true;
671*5f757f3fSDimitry Andric    __node_traits::construct(__na, std::addressof(__h->__get_value().second));
6720b57cec5SDimitry Andric    __h.get_deleter().__second_constructed = true;
673e8d8bef9SDimitry Andric    return __h;
6740b57cec5SDimitry Andric}
6750b57cec5SDimitry Andric
6760b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6770b57cec5SDimitry Andrictemplate <class _InputIterator>
6780b57cec5SDimitry Andricinline
6790b57cec5SDimitry Andricvoid
6800b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
6810b57cec5SDimitry Andric                                                       _InputIterator __last)
6820b57cec5SDimitry Andric{
6830b57cec5SDimitry Andric    for (; __first != __last; ++__first)
6840b57cec5SDimitry Andric        __table_.__insert_unique(*__first);
6850b57cec5SDimitry Andric}
6860b57cec5SDimitry Andric
6870b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6880b57cec5SDimitry Andric_Tp&
6890b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
6900b57cec5SDimitry Andric{
6910b57cec5SDimitry Andric    iterator __i = find(__k);
6920b57cec5SDimitry Andric    if (__i != end())
6930b57cec5SDimitry Andric        return __i->second;
6940b57cec5SDimitry Andric    __node_holder __h = __construct_node(__k);
6950b57cec5SDimitry Andric    std::pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
6960b57cec5SDimitry Andric    __h.release();
6970b57cec5SDimitry Andric    return __r.first->second;
6980b57cec5SDimitry Andric}
6990b57cec5SDimitry Andric
7000b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
701*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
7020b57cec5SDimitry Andricvoid
7030b57cec5SDimitry Andricswap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
7040b57cec5SDimitry Andric     hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
7050b57cec5SDimitry Andric{
7060b57cec5SDimitry Andric    __x.swap(__y);
7070b57cec5SDimitry Andric}
7080b57cec5SDimitry Andric
7090b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
710bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool
7110b57cec5SDimitry Andricoperator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
7120b57cec5SDimitry Andric           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
7130b57cec5SDimitry Andric{
7140b57cec5SDimitry Andric    if (__x.size() != __y.size())
7150b57cec5SDimitry Andric        return false;
7160b57cec5SDimitry Andric    typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
7170b57cec5SDimitry Andric                                                                 const_iterator;
7180b57cec5SDimitry Andric    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
7190b57cec5SDimitry Andric            __i != __ex; ++__i)
7200b57cec5SDimitry Andric    {
7210b57cec5SDimitry Andric        const_iterator __j = __y.find(__i->first);
7220b57cec5SDimitry Andric        if (__j == __ey || !(*__i == *__j))
7230b57cec5SDimitry Andric            return false;
7240b57cec5SDimitry Andric    }
7250b57cec5SDimitry Andric    return true;
7260b57cec5SDimitry Andric}
7270b57cec5SDimitry Andric
7280b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
729*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
7300b57cec5SDimitry Andricbool
7310b57cec5SDimitry Andricoperator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
7320b57cec5SDimitry Andric           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
7330b57cec5SDimitry Andric{
7340b57cec5SDimitry Andric    return !(__x == __y);
7350b57cec5SDimitry Andric}
7360b57cec5SDimitry Andric
7370b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>,
7380b57cec5SDimitry Andric          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
7390b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_multimap
7400b57cec5SDimitry Andric{
7410b57cec5SDimitry Andricpublic:
7420b57cec5SDimitry Andric    // types
7430b57cec5SDimitry Andric    typedef _Key                                           key_type;
7440b57cec5SDimitry Andric    typedef _Tp                                            mapped_type;
7450b57cec5SDimitry Andric    typedef _Tp                                            data_type;
7460b57cec5SDimitry Andric    typedef _Hash                                          hasher;
7470b57cec5SDimitry Andric    typedef _Pred                                          key_equal;
7480b57cec5SDimitry Andric    typedef _Alloc                                         allocator_type;
7490b57cec5SDimitry Andric    typedef std::pair<const key_type, mapped_type>         value_type;
7500b57cec5SDimitry Andric    typedef value_type&                                    reference;
7510b57cec5SDimitry Andric    typedef const value_type&                              const_reference;
7520b57cec5SDimitry Andric
7530b57cec5SDimitry Andricprivate:
7540b57cec5SDimitry Andric    typedef std::pair<key_type, mapped_type>               __value_type;
7550b57cec5SDimitry Andric    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
7560b57cec5SDimitry Andric    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
757bdd1243dSDimitry Andric    typedef std::__rebind_alloc<std::allocator_traits<allocator_type>, __value_type> __allocator_type;
7580b57cec5SDimitry Andric
7590b57cec5SDimitry Andric    typedef std::__hash_table<__value_type, __hasher,
7600b57cec5SDimitry Andric                         __key_equal,  __allocator_type>   __table;
7610b57cec5SDimitry Andric
7620b57cec5SDimitry Andric    __table __table_;
7630b57cec5SDimitry Andric
7640b57cec5SDimitry Andric    typedef typename __table::__node_traits                __node_traits;
7650b57cec5SDimitry Andric    typedef typename __table::__node_allocator             __node_allocator;
7660b57cec5SDimitry Andric    typedef typename __table::__node                       __node;
7670b57cec5SDimitry Andric    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
7680b57cec5SDimitry Andric    typedef std::unique_ptr<__node, _Dp>                         __node_holder;
7690b57cec5SDimitry Andric    typedef std::allocator_traits<allocator_type>               __alloc_traits;
7700b57cec5SDimitry Andricpublic:
7710b57cec5SDimitry Andric    typedef typename __alloc_traits::pointer         pointer;
7720b57cec5SDimitry Andric    typedef typename __alloc_traits::const_pointer   const_pointer;
7730b57cec5SDimitry Andric    typedef typename __alloc_traits::size_type       size_type;
7740b57cec5SDimitry Andric    typedef typename __alloc_traits::difference_type difference_type;
7750b57cec5SDimitry Andric
7760b57cec5SDimitry Andric    typedef __hash_map_iterator<typename __table::iterator>       iterator;
7770b57cec5SDimitry Andric    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
7780b57cec5SDimitry Andric
779*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
780e40139ffSDimitry Andric    hash_multimap() { }
78106c3fb27SDimitry Andric    explicit _LIBCPP_HIDE_FROM_ABI hash_multimap(size_type __n, const hasher& __hf = hasher(),
7820b57cec5SDimitry Andric                                const key_equal& __eql = key_equal());
78306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_multimap(size_type __n, const hasher& __hf,
7840b57cec5SDimitry Andric                                const key_equal& __eql,
7850b57cec5SDimitry Andric                                const allocator_type& __a);
7860b57cec5SDimitry Andric    template <class _InputIterator>
78706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last);
7880b57cec5SDimitry Andric    template <class _InputIterator>
78906c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last,
7900b57cec5SDimitry Andric                      size_type __n, const hasher& __hf = hasher(),
7910b57cec5SDimitry Andric                      const key_equal& __eql = key_equal());
7920b57cec5SDimitry Andric    template <class _InputIterator>
79306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last,
7940b57cec5SDimitry Andric                      size_type __n, const hasher& __hf,
7950b57cec5SDimitry Andric                      const key_equal& __eql,
7960b57cec5SDimitry Andric                      const allocator_type& __a);
79706c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI hash_multimap(const hash_multimap& __u);
7980b57cec5SDimitry Andric
799*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8000b57cec5SDimitry Andric    allocator_type get_allocator() const
8010b57cec5SDimitry Andric        {return allocator_type(__table_.__node_alloc());}
8020b57cec5SDimitry Andric
803*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8040b57cec5SDimitry Andric    bool      empty() const {return __table_.size() == 0;}
805*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8060b57cec5SDimitry Andric    size_type size() const  {return __table_.size();}
807*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8080b57cec5SDimitry Andric    size_type max_size() const {return __table_.max_size();}
8090b57cec5SDimitry Andric
810*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8110b57cec5SDimitry Andric    iterator       begin()        {return __table_.begin();}
812*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8130b57cec5SDimitry Andric    iterator       end()          {return __table_.end();}
814*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8150b57cec5SDimitry Andric    const_iterator begin()  const {return __table_.begin();}
816*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8170b57cec5SDimitry Andric    const_iterator end()    const {return __table_.end();}
8180b57cec5SDimitry Andric
819*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8200b57cec5SDimitry Andric    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
821*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8220b57cec5SDimitry Andric    iterator insert(const_iterator, const value_type& __x) {return insert(__x);}
8230b57cec5SDimitry Andric    template <class _InputIterator>
824*5f757f3fSDimitry Andric        _LIBCPP_HIDE_FROM_ABI
8250b57cec5SDimitry Andric        void insert(_InputIterator __first, _InputIterator __last);
8260b57cec5SDimitry Andric
827*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8280b57cec5SDimitry Andric    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
829*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8300b57cec5SDimitry Andric    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
831*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8320b57cec5SDimitry Andric    void erase(const_iterator __first, const_iterator __last)
8330b57cec5SDimitry Andric        {__table_.erase(__first.__i_, __last.__i_);}
834*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8350b57cec5SDimitry Andric    void clear() {__table_.clear();}
8360b57cec5SDimitry Andric
837*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8380b57cec5SDimitry Andric    void swap(hash_multimap& __u) {__table_.swap(__u.__table_);}
8390b57cec5SDimitry Andric
840*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8410b57cec5SDimitry Andric    hasher hash_funct() const
8420b57cec5SDimitry Andric        {return __table_.hash_function().hash_function();}
843*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8440b57cec5SDimitry Andric    key_equal key_eq() const
8450b57cec5SDimitry Andric        {return __table_.key_eq().key_eq();}
8460b57cec5SDimitry Andric
847*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8480b57cec5SDimitry Andric    iterator       find(const key_type& __k)       {return __table_.find(__k);}
849*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8500b57cec5SDimitry Andric    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
851*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8520b57cec5SDimitry Andric    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
853*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8540b57cec5SDimitry Andric    std::pair<iterator, iterator>             equal_range(const key_type& __k)
8550b57cec5SDimitry Andric        {return __table_.__equal_range_multi(__k);}
856*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8570b57cec5SDimitry Andric    std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
8580b57cec5SDimitry Andric        {return __table_.__equal_range_multi(__k);}
8590b57cec5SDimitry Andric
860*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8610b57cec5SDimitry Andric    size_type bucket_count() const {return __table_.bucket_count();}
862*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8630b57cec5SDimitry Andric    size_type max_bucket_count() const {return __table_.max_bucket_count();}
8640b57cec5SDimitry Andric
865*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
8660b57cec5SDimitry Andric    size_type elems_in_bucket(size_type __n) const
8670b57cec5SDimitry Andric        {return __table_.bucket_size(__n);}
8680b57cec5SDimitry Andric
869*5f757f3fSDimitry Andric    _LIBCPP_HIDE_FROM_ABI
870753f127fSDimitry Andric    void resize(size_type __n) {__table_.__rehash_multi(__n);}
8710b57cec5SDimitry Andric};
8720b57cec5SDimitry Andric
8730b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
8740b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
8750b57cec5SDimitry Andric        size_type __n, const hasher& __hf, const key_equal& __eql)
8760b57cec5SDimitry Andric    : __table_(__hf, __eql)
8770b57cec5SDimitry Andric{
878753f127fSDimitry Andric    __table_.__rehash_multi(__n);
8790b57cec5SDimitry Andric}
8800b57cec5SDimitry Andric
8810b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
8820b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
8830b57cec5SDimitry Andric        size_type __n, const hasher& __hf, const key_equal& __eql,
8840b57cec5SDimitry Andric        const allocator_type& __a)
8850b57cec5SDimitry Andric    : __table_(__hf, __eql, __a)
8860b57cec5SDimitry Andric{
887753f127fSDimitry Andric    __table_.__rehash_multi(__n);
8880b57cec5SDimitry Andric}
8890b57cec5SDimitry Andric
8900b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
8910b57cec5SDimitry Andrictemplate <class _InputIterator>
8920b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
8930b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last)
8940b57cec5SDimitry Andric{
8950b57cec5SDimitry Andric    insert(__first, __last);
8960b57cec5SDimitry Andric}
8970b57cec5SDimitry Andric
8980b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
8990b57cec5SDimitry Andrictemplate <class _InputIterator>
9000b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
9010b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last, size_type __n,
9020b57cec5SDimitry Andric        const hasher& __hf, const key_equal& __eql)
9030b57cec5SDimitry Andric    : __table_(__hf, __eql)
9040b57cec5SDimitry Andric{
905753f127fSDimitry Andric    __table_.__rehash_multi(__n);
9060b57cec5SDimitry Andric    insert(__first, __last);
9070b57cec5SDimitry Andric}
9080b57cec5SDimitry Andric
9090b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
9100b57cec5SDimitry Andrictemplate <class _InputIterator>
9110b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
9120b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last, size_type __n,
9130b57cec5SDimitry Andric        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
9140b57cec5SDimitry Andric    : __table_(__hf, __eql, __a)
9150b57cec5SDimitry Andric{
916753f127fSDimitry Andric    __table_.__rehash_multi(__n);
9170b57cec5SDimitry Andric    insert(__first, __last);
9180b57cec5SDimitry Andric}
9190b57cec5SDimitry Andric
9200b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
9210b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
9220b57cec5SDimitry Andric        const hash_multimap& __u)
9230b57cec5SDimitry Andric    : __table_(__u.__table_)
9240b57cec5SDimitry Andric{
925753f127fSDimitry Andric    __table_.__rehash_multi(__u.bucket_count());
9260b57cec5SDimitry Andric    insert(__u.begin(), __u.end());
9270b57cec5SDimitry Andric}
9280b57cec5SDimitry Andric
9290b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
9300b57cec5SDimitry Andrictemplate <class _InputIterator>
9310b57cec5SDimitry Andricinline
9320b57cec5SDimitry Andricvoid
9330b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
9340b57cec5SDimitry Andric                                                            _InputIterator __last)
9350b57cec5SDimitry Andric{
9360b57cec5SDimitry Andric    for (; __first != __last; ++__first)
9370b57cec5SDimitry Andric        __table_.__insert_multi(*__first);
9380b57cec5SDimitry Andric}
9390b57cec5SDimitry Andric
9400b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
941*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
9420b57cec5SDimitry Andricvoid
9430b57cec5SDimitry Andricswap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
9440b57cec5SDimitry Andric     hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
9450b57cec5SDimitry Andric{
9460b57cec5SDimitry Andric    __x.swap(__y);
9470b57cec5SDimitry Andric}
9480b57cec5SDimitry Andric
9490b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
950bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool
9510b57cec5SDimitry Andricoperator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
9520b57cec5SDimitry Andric           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
9530b57cec5SDimitry Andric{
9540b57cec5SDimitry Andric    if (__x.size() != __y.size())
9550b57cec5SDimitry Andric        return false;
9560b57cec5SDimitry Andric    typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
9570b57cec5SDimitry Andric                                                                 const_iterator;
9580b57cec5SDimitry Andric    typedef std::pair<const_iterator, const_iterator> _EqRng;
9590b57cec5SDimitry Andric    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
9600b57cec5SDimitry Andric    {
9610b57cec5SDimitry Andric        _EqRng __xeq = __x.equal_range(__i->first);
9620b57cec5SDimitry Andric        _EqRng __yeq = __y.equal_range(__i->first);
963*5f757f3fSDimitry Andric        if (std::distance(__xeq.first, __xeq.second) !=
964*5f757f3fSDimitry Andric            std::distance(__yeq.first, __yeq.second) ||
965*5f757f3fSDimitry Andric                  !std::is_permutation(__xeq.first, __xeq.second, __yeq.first))
9660b57cec5SDimitry Andric            return false;
9670b57cec5SDimitry Andric        __i = __xeq.second;
9680b57cec5SDimitry Andric    }
9690b57cec5SDimitry Andric    return true;
9700b57cec5SDimitry Andric}
9710b57cec5SDimitry Andric
9720b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
973*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI
9740b57cec5SDimitry Andricbool
9750b57cec5SDimitry Andricoperator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
9760b57cec5SDimitry Andric           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
9770b57cec5SDimitry Andric{
9780b57cec5SDimitry Andric    return !(__x == __y);
9790b57cec5SDimitry Andric}
9800b57cec5SDimitry Andric
9810eae32dcSDimitry Andric} // namespace __gnu_cxx
9820b57cec5SDimitry Andric
983bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
984bdd1243dSDimitry Andric#  include <concepts>
985bdd1243dSDimitry Andric#  include <iterator>
98606c3fb27SDimitry Andric#  include <type_traits>
987bdd1243dSDimitry Andric#endif
988bdd1243dSDimitry Andric
9890b57cec5SDimitry Andric#endif // _LIBCPP_HASH_MAP
990