xref: /freebsd/contrib/llvm-project/libcxx/include/ext/hash_map (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric// -*- C++ -*-
2*0b57cec5SDimitry Andric//===-------------------------- hash_map ----------------------------------===//
3*0b57cec5SDimitry Andric//
4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*0b57cec5SDimitry Andric//
8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9*0b57cec5SDimitry Andric
10*0b57cec5SDimitry Andric#ifndef _LIBCPP_HASH_MAP
11*0b57cec5SDimitry Andric#define _LIBCPP_HASH_MAP
12*0b57cec5SDimitry Andric
13*0b57cec5SDimitry Andric/*
14*0b57cec5SDimitry Andric
15*0b57cec5SDimitry Andric    hash_map synopsis
16*0b57cec5SDimitry Andric
17*0b57cec5SDimitry Andricnamespace __gnu_cxx
18*0b57cec5SDimitry Andric{
19*0b57cec5SDimitry Andric
20*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
21*0b57cec5SDimitry Andric          class Alloc = allocator<pair<const Key, T>>>
22*0b57cec5SDimitry Andricclass hash_map
23*0b57cec5SDimitry Andric{
24*0b57cec5SDimitry Andricpublic:
25*0b57cec5SDimitry Andric    // types
26*0b57cec5SDimitry Andric    typedef Key                                                        key_type;
27*0b57cec5SDimitry Andric    typedef T                                                          mapped_type;
28*0b57cec5SDimitry Andric    typedef Hash                                                       hasher;
29*0b57cec5SDimitry Andric    typedef Pred                                                       key_equal;
30*0b57cec5SDimitry Andric    typedef Alloc                                                      allocator_type;
31*0b57cec5SDimitry Andric    typedef pair<const key_type, mapped_type>                          value_type;
32*0b57cec5SDimitry Andric    typedef value_type&                                                reference;
33*0b57cec5SDimitry Andric    typedef const value_type&                                          const_reference;
34*0b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::pointer         pointer;
35*0b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
36*0b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::size_type       size_type;
37*0b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
38*0b57cec5SDimitry Andric
39*0b57cec5SDimitry Andric    typedef /unspecified/ iterator;
40*0b57cec5SDimitry Andric    typedef /unspecified/ const_iterator;
41*0b57cec5SDimitry Andric
42*0b57cec5SDimitry Andric    explicit hash_map(size_type n = 193, const hasher& hf = hasher(),
43*0b57cec5SDimitry Andric                           const key_equal& eql = key_equal(),
44*0b57cec5SDimitry Andric                           const allocator_type& a = allocator_type());
45*0b57cec5SDimitry Andric    template <class InputIterator>
46*0b57cec5SDimitry Andric        hash_map(InputIterator f, InputIterator l,
47*0b57cec5SDimitry Andric                      size_type n = 193, const hasher& hf = hasher(),
48*0b57cec5SDimitry Andric                      const key_equal& eql = key_equal(),
49*0b57cec5SDimitry Andric                      const allocator_type& a = allocator_type());
50*0b57cec5SDimitry Andric    hash_map(const hash_map&);
51*0b57cec5SDimitry Andric    ~hash_map();
52*0b57cec5SDimitry Andric    hash_map& operator=(const hash_map&);
53*0b57cec5SDimitry Andric
54*0b57cec5SDimitry Andric    allocator_type get_allocator() const;
55*0b57cec5SDimitry Andric
56*0b57cec5SDimitry Andric    bool      empty() const;
57*0b57cec5SDimitry Andric    size_type size() const;
58*0b57cec5SDimitry Andric    size_type max_size() const;
59*0b57cec5SDimitry Andric
60*0b57cec5SDimitry Andric    iterator       begin();
61*0b57cec5SDimitry Andric    iterator       end();
62*0b57cec5SDimitry Andric    const_iterator begin()  const;
63*0b57cec5SDimitry Andric    const_iterator end()    const;
64*0b57cec5SDimitry Andric
65*0b57cec5SDimitry Andric    pair<iterator, bool> insert(const value_type& obj);
66*0b57cec5SDimitry Andric    template <class InputIterator>
67*0b57cec5SDimitry Andric        void insert(InputIterator first, InputIterator last);
68*0b57cec5SDimitry Andric
69*0b57cec5SDimitry Andric    void erase(const_iterator position);
70*0b57cec5SDimitry Andric    size_type erase(const key_type& k);
71*0b57cec5SDimitry Andric    void erase(const_iterator first, const_iterator last);
72*0b57cec5SDimitry Andric    void clear();
73*0b57cec5SDimitry Andric
74*0b57cec5SDimitry Andric    void swap(hash_map&);
75*0b57cec5SDimitry Andric
76*0b57cec5SDimitry Andric    hasher hash_funct() const;
77*0b57cec5SDimitry Andric    key_equal key_eq() const;
78*0b57cec5SDimitry Andric
79*0b57cec5SDimitry Andric    iterator       find(const key_type& k);
80*0b57cec5SDimitry Andric    const_iterator find(const key_type& k) const;
81*0b57cec5SDimitry Andric    size_type count(const key_type& k) const;
82*0b57cec5SDimitry Andric    pair<iterator, iterator>             equal_range(const key_type& k);
83*0b57cec5SDimitry Andric    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
84*0b57cec5SDimitry Andric
85*0b57cec5SDimitry Andric    mapped_type& operator[](const key_type& k);
86*0b57cec5SDimitry Andric
87*0b57cec5SDimitry Andric    size_type bucket_count() const;
88*0b57cec5SDimitry Andric    size_type max_bucket_count() const;
89*0b57cec5SDimitry Andric
90*0b57cec5SDimitry Andric    size_type elems_in_bucket(size_type n) const;
91*0b57cec5SDimitry Andric
92*0b57cec5SDimitry Andric    void resize(size_type n);
93*0b57cec5SDimitry Andric};
94*0b57cec5SDimitry Andric
95*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
96*0b57cec5SDimitry Andric    void swap(hash_map<Key, T, Hash, Pred, Alloc>& x,
97*0b57cec5SDimitry Andric              hash_map<Key, T, Hash, Pred, Alloc>& y);
98*0b57cec5SDimitry Andric
99*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
100*0b57cec5SDimitry Andric    bool
101*0b57cec5SDimitry Andric    operator==(const hash_map<Key, T, Hash, Pred, Alloc>& x,
102*0b57cec5SDimitry Andric               const hash_map<Key, T, Hash, Pred, Alloc>& y);
103*0b57cec5SDimitry Andric
104*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
105*0b57cec5SDimitry Andric    bool
106*0b57cec5SDimitry Andric    operator!=(const hash_map<Key, T, Hash, Pred, Alloc>& x,
107*0b57cec5SDimitry Andric               const hash_map<Key, T, Hash, Pred, Alloc>& y);
108*0b57cec5SDimitry Andric
109*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
110*0b57cec5SDimitry Andric          class Alloc = allocator<pair<const Key, T>>>
111*0b57cec5SDimitry Andricclass hash_multimap
112*0b57cec5SDimitry Andric{
113*0b57cec5SDimitry Andricpublic:
114*0b57cec5SDimitry Andric    // types
115*0b57cec5SDimitry Andric    typedef Key                                                        key_type;
116*0b57cec5SDimitry Andric    typedef T                                                          mapped_type;
117*0b57cec5SDimitry Andric    typedef Hash                                                       hasher;
118*0b57cec5SDimitry Andric    typedef Pred                                                       key_equal;
119*0b57cec5SDimitry Andric    typedef Alloc                                                      allocator_type;
120*0b57cec5SDimitry Andric    typedef pair<const key_type, mapped_type>                          value_type;
121*0b57cec5SDimitry Andric    typedef value_type&                                                reference;
122*0b57cec5SDimitry Andric    typedef const value_type&                                          const_reference;
123*0b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::pointer         pointer;
124*0b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
125*0b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::size_type       size_type;
126*0b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
127*0b57cec5SDimitry Andric
128*0b57cec5SDimitry Andric    typedef /unspecified/ iterator;
129*0b57cec5SDimitry Andric    typedef /unspecified/ const_iterator;
130*0b57cec5SDimitry Andric
131*0b57cec5SDimitry Andric    explicit hash_multimap(size_type n = 193, const hasher& hf = hasher(),
132*0b57cec5SDimitry Andric                           const key_equal& eql = key_equal(),
133*0b57cec5SDimitry Andric                           const allocator_type& a = allocator_type());
134*0b57cec5SDimitry Andric    template <class InputIterator>
135*0b57cec5SDimitry Andric        hash_multimap(InputIterator f, InputIterator l,
136*0b57cec5SDimitry Andric                      size_type n = 193, const hasher& hf = hasher(),
137*0b57cec5SDimitry Andric                      const key_equal& eql = key_equal(),
138*0b57cec5SDimitry Andric                      const allocator_type& a = allocator_type());
139*0b57cec5SDimitry Andric    explicit hash_multimap(const allocator_type&);
140*0b57cec5SDimitry Andric    hash_multimap(const hash_multimap&);
141*0b57cec5SDimitry Andric    ~hash_multimap();
142*0b57cec5SDimitry Andric    hash_multimap& operator=(const hash_multimap&);
143*0b57cec5SDimitry Andric
144*0b57cec5SDimitry Andric    allocator_type get_allocator() const;
145*0b57cec5SDimitry Andric
146*0b57cec5SDimitry Andric    bool      empty() const;
147*0b57cec5SDimitry Andric    size_type size() const;
148*0b57cec5SDimitry Andric    size_type max_size() const;
149*0b57cec5SDimitry Andric
150*0b57cec5SDimitry Andric    iterator       begin();
151*0b57cec5SDimitry Andric    iterator       end();
152*0b57cec5SDimitry Andric    const_iterator begin()  const;
153*0b57cec5SDimitry Andric    const_iterator end()    const;
154*0b57cec5SDimitry Andric
155*0b57cec5SDimitry Andric    iterator insert(const value_type& obj);
156*0b57cec5SDimitry Andric    template <class InputIterator>
157*0b57cec5SDimitry Andric        void insert(InputIterator first, InputIterator last);
158*0b57cec5SDimitry Andric
159*0b57cec5SDimitry Andric    void erase(const_iterator position);
160*0b57cec5SDimitry Andric    size_type erase(const key_type& k);
161*0b57cec5SDimitry Andric    void erase(const_iterator first, const_iterator last);
162*0b57cec5SDimitry Andric    void clear();
163*0b57cec5SDimitry Andric
164*0b57cec5SDimitry Andric    void swap(hash_multimap&);
165*0b57cec5SDimitry Andric
166*0b57cec5SDimitry Andric    hasher hash_funct() const;
167*0b57cec5SDimitry Andric    key_equal key_eq() const;
168*0b57cec5SDimitry Andric
169*0b57cec5SDimitry Andric    iterator       find(const key_type& k);
170*0b57cec5SDimitry Andric    const_iterator find(const key_type& k) const;
171*0b57cec5SDimitry Andric    size_type count(const key_type& k) const;
172*0b57cec5SDimitry Andric    pair<iterator, iterator>             equal_range(const key_type& k);
173*0b57cec5SDimitry Andric    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
174*0b57cec5SDimitry Andric
175*0b57cec5SDimitry Andric    size_type bucket_count() const;
176*0b57cec5SDimitry Andric    size_type max_bucket_count() const;
177*0b57cec5SDimitry Andric
178*0b57cec5SDimitry Andric    size_type elems_in_bucket(size_type n) const;
179*0b57cec5SDimitry Andric
180*0b57cec5SDimitry Andric    void resize(size_type n);
181*0b57cec5SDimitry Andric};
182*0b57cec5SDimitry Andric
183*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
184*0b57cec5SDimitry Andric    void swap(hash_multimap<Key, T, Hash, Pred, Alloc>& x,
185*0b57cec5SDimitry Andric              hash_multimap<Key, T, Hash, Pred, Alloc>& y);
186*0b57cec5SDimitry Andric
187*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
188*0b57cec5SDimitry Andric    bool
189*0b57cec5SDimitry Andric    operator==(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
190*0b57cec5SDimitry Andric               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);
191*0b57cec5SDimitry Andric
192*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc>
193*0b57cec5SDimitry Andric    bool
194*0b57cec5SDimitry Andric    operator!=(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
195*0b57cec5SDimitry Andric               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);
196*0b57cec5SDimitry Andric
197*0b57cec5SDimitry Andric}  // __gnu_cxx
198*0b57cec5SDimitry Andric
199*0b57cec5SDimitry Andric*/
200*0b57cec5SDimitry Andric
201*0b57cec5SDimitry Andric#include <__config>
202*0b57cec5SDimitry Andric#include <__hash_table>
203*0b57cec5SDimitry Andric#include <functional>
204*0b57cec5SDimitry Andric#include <stdexcept>
205*0b57cec5SDimitry Andric#include <type_traits>
206*0b57cec5SDimitry Andric#include <ext/__hash>
207*0b57cec5SDimitry Andric
208*0b57cec5SDimitry Andric#if __DEPRECATED
209*0b57cec5SDimitry Andric#if defined(_LIBCPP_WARNING)
210*0b57cec5SDimitry Andric    _LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>")
211*0b57cec5SDimitry Andric#else
212*0b57cec5SDimitry Andric#   warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
213*0b57cec5SDimitry Andric#endif
214*0b57cec5SDimitry Andric#endif
215*0b57cec5SDimitry Andric
216*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
217*0b57cec5SDimitry Andric#pragma GCC system_header
218*0b57cec5SDimitry Andric#endif
219*0b57cec5SDimitry Andric
220*0b57cec5SDimitry Andricnamespace __gnu_cxx {
221*0b57cec5SDimitry Andric
222*0b57cec5SDimitry Andrictemplate <class _Tp, class _Hash,
223*0b57cec5SDimitry Andric          bool = std::is_empty<_Hash>::value && !std::__libcpp_is_final<_Hash>::value
224*0b57cec5SDimitry Andric        >
225*0b57cec5SDimitry Andricclass __hash_map_hasher
226*0b57cec5SDimitry Andric    : private _Hash
227*0b57cec5SDimitry Andric{
228*0b57cec5SDimitry Andricpublic:
229*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : _Hash() {}
230*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : _Hash(__h) {}
231*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return *this;}
232*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
233*0b57cec5SDimitry Andric    size_t operator()(const _Tp& __x) const
234*0b57cec5SDimitry Andric        {return static_cast<const _Hash&>(*this)(__x.first);}
235*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
236*0b57cec5SDimitry Andric    size_t operator()(const typename _Tp::first_type& __x) const
237*0b57cec5SDimitry Andric        {return static_cast<const _Hash&>(*this)(__x);}
238*0b57cec5SDimitry Andric};
239*0b57cec5SDimitry Andric
240*0b57cec5SDimitry Andrictemplate <class _Tp, class _Hash>
241*0b57cec5SDimitry Andricclass __hash_map_hasher<_Tp, _Hash, false>
242*0b57cec5SDimitry Andric{
243*0b57cec5SDimitry Andric    _Hash __hash_;
244*0b57cec5SDimitry Andricpublic:
245*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : __hash_() {}
246*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : __hash_(__h) {}
247*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return __hash_;}
248*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
249*0b57cec5SDimitry Andric    size_t operator()(const _Tp& __x) const
250*0b57cec5SDimitry Andric        {return __hash_(__x.first);}
251*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
252*0b57cec5SDimitry Andric    size_t operator()(const typename _Tp::first_type& __x) const
253*0b57cec5SDimitry Andric        {return __hash_(__x);}
254*0b57cec5SDimitry Andric};
255*0b57cec5SDimitry Andric
256*0b57cec5SDimitry Andrictemplate <class _Tp, class _Pred,
257*0b57cec5SDimitry Andric          bool = std::is_empty<_Pred>::value && !std::__libcpp_is_final<_Pred>::value
258*0b57cec5SDimitry Andric         >
259*0b57cec5SDimitry Andricclass __hash_map_equal
260*0b57cec5SDimitry Andric    : private _Pred
261*0b57cec5SDimitry Andric{
262*0b57cec5SDimitry Andricpublic:
263*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : _Pred() {}
264*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : _Pred(__p) {}
265*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return *this;}
266*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
267*0b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
268*0b57cec5SDimitry Andric        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
269*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
270*0b57cec5SDimitry Andric    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
271*0b57cec5SDimitry Andric        {return static_cast<const _Pred&>(*this)(__x, __y.first);}
272*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
273*0b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
274*0b57cec5SDimitry Andric        {return static_cast<const _Pred&>(*this)(__x.first, __y);}
275*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
276*0b57cec5SDimitry Andric    bool operator()(const typename _Tp::first_type& __x,
277*0b57cec5SDimitry Andric                    const typename _Tp::first_type& __y) const
278*0b57cec5SDimitry Andric        {return static_cast<const _Pred&>(*this)(__x, __y);}
279*0b57cec5SDimitry Andric};
280*0b57cec5SDimitry Andric
281*0b57cec5SDimitry Andrictemplate <class _Tp, class _Pred>
282*0b57cec5SDimitry Andricclass __hash_map_equal<_Tp, _Pred, false>
283*0b57cec5SDimitry Andric{
284*0b57cec5SDimitry Andric    _Pred __pred_;
285*0b57cec5SDimitry Andricpublic:
286*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : __pred_() {}
287*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : __pred_(__p) {}
288*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return __pred_;}
289*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
290*0b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const _Tp& __y) const
291*0b57cec5SDimitry Andric        {return __pred_(__x.first, __y.first);}
292*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
293*0b57cec5SDimitry Andric    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
294*0b57cec5SDimitry Andric        {return __pred_(__x, __y.first);}
295*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
296*0b57cec5SDimitry Andric    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
297*0b57cec5SDimitry Andric        {return __pred_(__x.first, __y);}
298*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
299*0b57cec5SDimitry Andric    bool operator()(const typename _Tp::first_type& __x,
300*0b57cec5SDimitry Andric                    const typename _Tp::first_type& __y) const
301*0b57cec5SDimitry Andric        {return __pred_(__x, __y);}
302*0b57cec5SDimitry Andric};
303*0b57cec5SDimitry Andric
304*0b57cec5SDimitry Andrictemplate <class _Alloc>
305*0b57cec5SDimitry Andricclass __hash_map_node_destructor
306*0b57cec5SDimitry Andric{
307*0b57cec5SDimitry Andric    typedef _Alloc                              allocator_type;
308*0b57cec5SDimitry Andric    typedef std::allocator_traits<allocator_type>    __alloc_traits;
309*0b57cec5SDimitry Andric    typedef typename __alloc_traits::value_type::__node_value_type value_type;
310*0b57cec5SDimitry Andricpublic:
311*0b57cec5SDimitry Andric    typedef typename __alloc_traits::pointer    pointer;
312*0b57cec5SDimitry Andricprivate:
313*0b57cec5SDimitry Andric    typedef typename value_type::first_type     first_type;
314*0b57cec5SDimitry Andric    typedef typename value_type::second_type    second_type;
315*0b57cec5SDimitry Andric
316*0b57cec5SDimitry Andric    allocator_type& __na_;
317*0b57cec5SDimitry Andric
318*0b57cec5SDimitry Andric    __hash_map_node_destructor& operator=(const __hash_map_node_destructor&);
319*0b57cec5SDimitry Andric
320*0b57cec5SDimitry Andricpublic:
321*0b57cec5SDimitry Andric    bool __first_constructed;
322*0b57cec5SDimitry Andric    bool __second_constructed;
323*0b57cec5SDimitry Andric
324*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
325*0b57cec5SDimitry Andric    explicit __hash_map_node_destructor(allocator_type& __na)
326*0b57cec5SDimitry Andric        : __na_(__na),
327*0b57cec5SDimitry Andric          __first_constructed(false),
328*0b57cec5SDimitry Andric          __second_constructed(false)
329*0b57cec5SDimitry Andric        {}
330*0b57cec5SDimitry Andric
331*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
332*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
333*0b57cec5SDimitry Andric    __hash_map_node_destructor(std::__hash_node_destructor<allocator_type>&& __x)
334*0b57cec5SDimitry Andric        : __na_(__x.__na_),
335*0b57cec5SDimitry Andric          __first_constructed(__x.__value_constructed),
336*0b57cec5SDimitry Andric          __second_constructed(__x.__value_constructed)
337*0b57cec5SDimitry Andric        {
338*0b57cec5SDimitry Andric            __x.__value_constructed = false;
339*0b57cec5SDimitry Andric        }
340*0b57cec5SDimitry Andric#else  // _LIBCPP_CXX03_LANG
341*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
342*0b57cec5SDimitry Andric    __hash_map_node_destructor(const std::__hash_node_destructor<allocator_type>& __x)
343*0b57cec5SDimitry Andric        : __na_(__x.__na_),
344*0b57cec5SDimitry Andric          __first_constructed(__x.__value_constructed),
345*0b57cec5SDimitry Andric          __second_constructed(__x.__value_constructed)
346*0b57cec5SDimitry Andric        {
347*0b57cec5SDimitry Andric            const_cast<bool&>(__x.__value_constructed) = false;
348*0b57cec5SDimitry Andric        }
349*0b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
350*0b57cec5SDimitry Andric
351*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
352*0b57cec5SDimitry Andric    void operator()(pointer __p)
353*0b57cec5SDimitry Andric    {
354*0b57cec5SDimitry Andric        if (__second_constructed)
355*0b57cec5SDimitry Andric            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second));
356*0b57cec5SDimitry Andric        if (__first_constructed)
357*0b57cec5SDimitry Andric            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first));
358*0b57cec5SDimitry Andric        if (__p)
359*0b57cec5SDimitry Andric            __alloc_traits::deallocate(__na_, __p, 1);
360*0b57cec5SDimitry Andric    }
361*0b57cec5SDimitry Andric};
362*0b57cec5SDimitry Andric
363*0b57cec5SDimitry Andrictemplate <class _HashIterator>
364*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_iterator
365*0b57cec5SDimitry Andric{
366*0b57cec5SDimitry Andric    _HashIterator __i_;
367*0b57cec5SDimitry Andric
368*0b57cec5SDimitry Andric    typedef const typename _HashIterator::value_type::first_type key_type;
369*0b57cec5SDimitry Andric    typedef typename _HashIterator::value_type::second_type      mapped_type;
370*0b57cec5SDimitry Andricpublic:
371*0b57cec5SDimitry Andric    typedef std::forward_iterator_tag                            iterator_category;
372*0b57cec5SDimitry Andric    typedef std::pair<key_type, mapped_type>                     value_type;
373*0b57cec5SDimitry Andric    typedef typename _HashIterator::difference_type              difference_type;
374*0b57cec5SDimitry Andric    typedef value_type&                                          reference;
375*0b57cec5SDimitry Andric    typedef typename std::__rebind_pointer<typename _HashIterator::pointer, value_type>::type
376*0b57cec5SDimitry Andric        pointer;
377*0b57cec5SDimitry Andric
378*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() {}
379*0b57cec5SDimitry Andric
380*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator(_HashIterator __i) : __i_(__i) {}
381*0b57cec5SDimitry Andric
382*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *operator->();}
383*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return (pointer)__i_.operator->();}
384*0b57cec5SDimitry Andric
385*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;}
386*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
387*0b57cec5SDimitry Andric    __hash_map_iterator operator++(int)
388*0b57cec5SDimitry Andric    {
389*0b57cec5SDimitry Andric        __hash_map_iterator __t(*this);
390*0b57cec5SDimitry Andric        ++(*this);
391*0b57cec5SDimitry Andric        return __t;
392*0b57cec5SDimitry Andric    }
393*0b57cec5SDimitry Andric
394*0b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
395*0b57cec5SDimitry Andric    bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
396*0b57cec5SDimitry Andric        {return __x.__i_ == __y.__i_;}
397*0b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
398*0b57cec5SDimitry Andric    bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
399*0b57cec5SDimitry Andric        {return __x.__i_ != __y.__i_;}
400*0b57cec5SDimitry Andric
401*0b57cec5SDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map;
402*0b57cec5SDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
403*0b57cec5SDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
404*0b57cec5SDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
405*0b57cec5SDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
406*0b57cec5SDimitry Andric};
407*0b57cec5SDimitry Andric
408*0b57cec5SDimitry Andrictemplate <class _HashIterator>
409*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator
410*0b57cec5SDimitry Andric{
411*0b57cec5SDimitry Andric    _HashIterator __i_;
412*0b57cec5SDimitry Andric
413*0b57cec5SDimitry Andric    typedef const typename _HashIterator::value_type::first_type key_type;
414*0b57cec5SDimitry Andric    typedef typename _HashIterator::value_type::second_type      mapped_type;
415*0b57cec5SDimitry Andricpublic:
416*0b57cec5SDimitry Andric    typedef std::forward_iterator_tag                            iterator_category;
417*0b57cec5SDimitry Andric    typedef std::pair<key_type, mapped_type>                     value_type;
418*0b57cec5SDimitry Andric    typedef typename _HashIterator::difference_type              difference_type;
419*0b57cec5SDimitry Andric    typedef const value_type&                                    reference;
420*0b57cec5SDimitry Andric    typedef typename std::__rebind_pointer<typename _HashIterator::pointer, const value_type>::type
421*0b57cec5SDimitry Andric        pointer;
422*0b57cec5SDimitry Andric
423*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() {}
424*0b57cec5SDimitry Andric
425*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
426*0b57cec5SDimitry Andric    __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {}
427*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
428*0b57cec5SDimitry Andric    __hash_map_const_iterator(
429*0b57cec5SDimitry Andric            __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
430*0b57cec5SDimitry Andric                : __i_(__i.__i_) {}
431*0b57cec5SDimitry Andric
432*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
433*0b57cec5SDimitry Andric    reference operator*() const {return *operator->();}
434*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
435*0b57cec5SDimitry Andric    pointer operator->() const {return (pointer)__i_.operator->();}
436*0b57cec5SDimitry Andric
437*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
438*0b57cec5SDimitry Andric    __hash_map_const_iterator& operator++() {++__i_; return *this;}
439*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
440*0b57cec5SDimitry Andric    __hash_map_const_iterator operator++(int)
441*0b57cec5SDimitry Andric    {
442*0b57cec5SDimitry Andric        __hash_map_const_iterator __t(*this);
443*0b57cec5SDimitry Andric        ++(*this);
444*0b57cec5SDimitry Andric        return __t;
445*0b57cec5SDimitry Andric    }
446*0b57cec5SDimitry Andric
447*0b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
448*0b57cec5SDimitry Andric    bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
449*0b57cec5SDimitry Andric        {return __x.__i_ == __y.__i_;}
450*0b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
451*0b57cec5SDimitry Andric    bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
452*0b57cec5SDimitry Andric        {return __x.__i_ != __y.__i_;}
453*0b57cec5SDimitry Andric
454*0b57cec5SDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map;
455*0b57cec5SDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
456*0b57cec5SDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
457*0b57cec5SDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
458*0b57cec5SDimitry Andric};
459*0b57cec5SDimitry Andric
460*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>,
461*0b57cec5SDimitry Andric          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
462*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_map
463*0b57cec5SDimitry Andric{
464*0b57cec5SDimitry Andricpublic:
465*0b57cec5SDimitry Andric    // types
466*0b57cec5SDimitry Andric    typedef _Key                                           key_type;
467*0b57cec5SDimitry Andric    typedef _Tp                                            mapped_type;
468*0b57cec5SDimitry Andric    typedef _Tp                                            data_type;
469*0b57cec5SDimitry Andric    typedef _Hash                                          hasher;
470*0b57cec5SDimitry Andric    typedef _Pred                                          key_equal;
471*0b57cec5SDimitry Andric    typedef _Alloc                                         allocator_type;
472*0b57cec5SDimitry Andric    typedef std::pair<const key_type, mapped_type>         value_type;
473*0b57cec5SDimitry Andric    typedef value_type&                                    reference;
474*0b57cec5SDimitry Andric    typedef const value_type&                              const_reference;
475*0b57cec5SDimitry Andric
476*0b57cec5SDimitry Andricprivate:
477*0b57cec5SDimitry Andric    typedef std::pair<key_type, mapped_type>                    __value_type;
478*0b57cec5SDimitry Andric    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
479*0b57cec5SDimitry Andric    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
480*0b57cec5SDimitry Andric    typedef typename std::__rebind_alloc_helper<
481*0b57cec5SDimitry Andric        std::allocator_traits<allocator_type>, __value_type>::type __allocator_type;
482*0b57cec5SDimitry Andric
483*0b57cec5SDimitry Andric    typedef std::__hash_table<__value_type, __hasher,
484*0b57cec5SDimitry Andric                         __key_equal,  __allocator_type>   __table;
485*0b57cec5SDimitry Andric
486*0b57cec5SDimitry Andric    __table __table_;
487*0b57cec5SDimitry Andric
488*0b57cec5SDimitry Andric    typedef typename __table::__node_pointer               __node_pointer;
489*0b57cec5SDimitry Andric    typedef typename __table::__node_const_pointer         __node_const_pointer;
490*0b57cec5SDimitry Andric    typedef typename __table::__node_traits                __node_traits;
491*0b57cec5SDimitry Andric    typedef typename __table::__node_allocator             __node_allocator;
492*0b57cec5SDimitry Andric    typedef typename __table::__node                       __node;
493*0b57cec5SDimitry Andric    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
494*0b57cec5SDimitry Andric    typedef std::unique_ptr<__node, _Dp>                   __node_holder;
495*0b57cec5SDimitry Andric    typedef std::allocator_traits<allocator_type>          __alloc_traits;
496*0b57cec5SDimitry Andricpublic:
497*0b57cec5SDimitry Andric    typedef typename __alloc_traits::pointer         pointer;
498*0b57cec5SDimitry Andric    typedef typename __alloc_traits::const_pointer   const_pointer;
499*0b57cec5SDimitry Andric    typedef typename __alloc_traits::size_type       size_type;
500*0b57cec5SDimitry Andric    typedef typename __alloc_traits::difference_type difference_type;
501*0b57cec5SDimitry Andric
502*0b57cec5SDimitry Andric    typedef __hash_map_iterator<typename __table::iterator>       iterator;
503*0b57cec5SDimitry Andric    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
504*0b57cec5SDimitry Andric
505*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY hash_map() {__table_.rehash(193);}
506*0b57cec5SDimitry Andric    explicit hash_map(size_type __n, const hasher& __hf = hasher(),
507*0b57cec5SDimitry Andric                           const key_equal& __eql = key_equal());
508*0b57cec5SDimitry Andric    hash_map(size_type __n, const hasher& __hf,
509*0b57cec5SDimitry Andric                  const key_equal& __eql,
510*0b57cec5SDimitry Andric                  const allocator_type& __a);
511*0b57cec5SDimitry Andric    template <class _InputIterator>
512*0b57cec5SDimitry Andric        hash_map(_InputIterator __first, _InputIterator __last);
513*0b57cec5SDimitry Andric    template <class _InputIterator>
514*0b57cec5SDimitry Andric        hash_map(_InputIterator __first, _InputIterator __last,
515*0b57cec5SDimitry Andric                      size_type __n, const hasher& __hf = hasher(),
516*0b57cec5SDimitry Andric                      const key_equal& __eql = key_equal());
517*0b57cec5SDimitry Andric    template <class _InputIterator>
518*0b57cec5SDimitry Andric        hash_map(_InputIterator __first, _InputIterator __last,
519*0b57cec5SDimitry Andric                      size_type __n, const hasher& __hf,
520*0b57cec5SDimitry Andric                      const key_equal& __eql,
521*0b57cec5SDimitry Andric                      const allocator_type& __a);
522*0b57cec5SDimitry Andric    hash_map(const hash_map& __u);
523*0b57cec5SDimitry Andric
524*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
525*0b57cec5SDimitry Andric    allocator_type get_allocator() const
526*0b57cec5SDimitry Andric        {return allocator_type(__table_.__node_alloc());}
527*0b57cec5SDimitry Andric
528*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
529*0b57cec5SDimitry Andric    bool      empty() const {return __table_.size() == 0;}
530*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
531*0b57cec5SDimitry Andric    size_type size() const  {return __table_.size();}
532*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
533*0b57cec5SDimitry Andric    size_type max_size() const {return __table_.max_size();}
534*0b57cec5SDimitry Andric
535*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
536*0b57cec5SDimitry Andric    iterator       begin()        {return __table_.begin();}
537*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
538*0b57cec5SDimitry Andric    iterator       end()          {return __table_.end();}
539*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
540*0b57cec5SDimitry Andric    const_iterator begin()  const {return __table_.begin();}
541*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
542*0b57cec5SDimitry Andric    const_iterator end()    const {return __table_.end();}
543*0b57cec5SDimitry Andric
544*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
545*0b57cec5SDimitry Andric    std::pair<iterator, bool> insert(const value_type& __x)
546*0b57cec5SDimitry Andric        {return __table_.__insert_unique(__x);}
547*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
548*0b57cec5SDimitry Andric    iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}
549*0b57cec5SDimitry Andric    template <class _InputIterator>
550*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
551*0b57cec5SDimitry Andric        void insert(_InputIterator __first, _InputIterator __last);
552*0b57cec5SDimitry Andric
553*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
554*0b57cec5SDimitry Andric    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
555*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
556*0b57cec5SDimitry Andric    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
557*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
558*0b57cec5SDimitry Andric    void erase(const_iterator __first, const_iterator __last)
559*0b57cec5SDimitry Andric        {__table_.erase(__first.__i_, __last.__i_);}
560*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
561*0b57cec5SDimitry Andric    void clear() {__table_.clear();}
562*0b57cec5SDimitry Andric
563*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
564*0b57cec5SDimitry Andric    void swap(hash_map& __u) {__table_.swap(__u.__table_);}
565*0b57cec5SDimitry Andric
566*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
567*0b57cec5SDimitry Andric    hasher hash_funct() const
568*0b57cec5SDimitry Andric        {return __table_.hash_function().hash_function();}
569*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
570*0b57cec5SDimitry Andric    key_equal key_eq() const
571*0b57cec5SDimitry Andric        {return __table_.key_eq().key_eq();}
572*0b57cec5SDimitry Andric
573*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
574*0b57cec5SDimitry Andric    iterator       find(const key_type& __k)       {return __table_.find(__k);}
575*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
576*0b57cec5SDimitry Andric    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
577*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
578*0b57cec5SDimitry Andric    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
579*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
580*0b57cec5SDimitry Andric    std::pair<iterator, iterator>             equal_range(const key_type& __k)
581*0b57cec5SDimitry Andric        {return __table_.__equal_range_unique(__k);}
582*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
583*0b57cec5SDimitry Andric    std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
584*0b57cec5SDimitry Andric        {return __table_.__equal_range_unique(__k);}
585*0b57cec5SDimitry Andric
586*0b57cec5SDimitry Andric    mapped_type& operator[](const key_type& __k);
587*0b57cec5SDimitry Andric
588*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
589*0b57cec5SDimitry Andric    size_type bucket_count() const {return __table_.bucket_count();}
590*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
591*0b57cec5SDimitry Andric    size_type max_bucket_count() const {return __table_.max_bucket_count();}
592*0b57cec5SDimitry Andric
593*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
594*0b57cec5SDimitry Andric    size_type elems_in_bucket(size_type __n) const
595*0b57cec5SDimitry Andric        {return __table_.bucket_size(__n);}
596*0b57cec5SDimitry Andric
597*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
598*0b57cec5SDimitry Andric    void resize(size_type __n) {__table_.rehash(__n);}
599*0b57cec5SDimitry Andric
600*0b57cec5SDimitry Andricprivate:
601*0b57cec5SDimitry Andric    __node_holder __construct_node(const key_type& __k);
602*0b57cec5SDimitry Andric};
603*0b57cec5SDimitry Andric
604*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
605*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
606*0b57cec5SDimitry Andric        size_type __n, const hasher& __hf, const key_equal& __eql)
607*0b57cec5SDimitry Andric    : __table_(__hf, __eql)
608*0b57cec5SDimitry Andric{
609*0b57cec5SDimitry Andric    __table_.rehash(__n);
610*0b57cec5SDimitry Andric}
611*0b57cec5SDimitry Andric
612*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
613*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
614*0b57cec5SDimitry Andric        size_type __n, const hasher& __hf, const key_equal& __eql,
615*0b57cec5SDimitry Andric        const allocator_type& __a)
616*0b57cec5SDimitry Andric    : __table_(__hf, __eql, __a)
617*0b57cec5SDimitry Andric{
618*0b57cec5SDimitry Andric    __table_.rehash(__n);
619*0b57cec5SDimitry Andric}
620*0b57cec5SDimitry Andric
621*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
622*0b57cec5SDimitry Andrictemplate <class _InputIterator>
623*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
624*0b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last)
625*0b57cec5SDimitry Andric{
626*0b57cec5SDimitry Andric    __table_.rehash(193);
627*0b57cec5SDimitry Andric    insert(__first, __last);
628*0b57cec5SDimitry Andric}
629*0b57cec5SDimitry Andric
630*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
631*0b57cec5SDimitry Andrictemplate <class _InputIterator>
632*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
633*0b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last, size_type __n,
634*0b57cec5SDimitry Andric        const hasher& __hf, const key_equal& __eql)
635*0b57cec5SDimitry Andric    : __table_(__hf, __eql)
636*0b57cec5SDimitry Andric{
637*0b57cec5SDimitry Andric    __table_.rehash(__n);
638*0b57cec5SDimitry Andric    insert(__first, __last);
639*0b57cec5SDimitry Andric}
640*0b57cec5SDimitry Andric
641*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
642*0b57cec5SDimitry Andrictemplate <class _InputIterator>
643*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
644*0b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last, size_type __n,
645*0b57cec5SDimitry Andric        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
646*0b57cec5SDimitry Andric    : __table_(__hf, __eql, __a)
647*0b57cec5SDimitry Andric{
648*0b57cec5SDimitry Andric    __table_.rehash(__n);
649*0b57cec5SDimitry Andric    insert(__first, __last);
650*0b57cec5SDimitry Andric}
651*0b57cec5SDimitry Andric
652*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
653*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
654*0b57cec5SDimitry Andric        const hash_map& __u)
655*0b57cec5SDimitry Andric    : __table_(__u.__table_)
656*0b57cec5SDimitry Andric{
657*0b57cec5SDimitry Andric    __table_.rehash(__u.bucket_count());
658*0b57cec5SDimitry Andric    insert(__u.begin(), __u.end());
659*0b57cec5SDimitry Andric}
660*0b57cec5SDimitry Andric
661*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
662*0b57cec5SDimitry Andrictypename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
663*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k)
664*0b57cec5SDimitry Andric{
665*0b57cec5SDimitry Andric    __node_allocator& __na = __table_.__node_alloc();
666*0b57cec5SDimitry Andric    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
667*0b57cec5SDimitry Andric    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k);
668*0b57cec5SDimitry Andric    __h.get_deleter().__first_constructed = true;
669*0b57cec5SDimitry Andric    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
670*0b57cec5SDimitry Andric    __h.get_deleter().__second_constructed = true;
671*0b57cec5SDimitry Andric    return _LIBCPP_EXPLICIT_MOVE(__h);  // explicitly moved for C++03
672*0b57cec5SDimitry Andric}
673*0b57cec5SDimitry Andric
674*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
675*0b57cec5SDimitry Andrictemplate <class _InputIterator>
676*0b57cec5SDimitry Andricinline
677*0b57cec5SDimitry Andricvoid
678*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
679*0b57cec5SDimitry Andric                                                       _InputIterator __last)
680*0b57cec5SDimitry Andric{
681*0b57cec5SDimitry Andric    for (; __first != __last; ++__first)
682*0b57cec5SDimitry Andric        __table_.__insert_unique(*__first);
683*0b57cec5SDimitry Andric}
684*0b57cec5SDimitry Andric
685*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
686*0b57cec5SDimitry Andric_Tp&
687*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
688*0b57cec5SDimitry Andric{
689*0b57cec5SDimitry Andric    iterator __i = find(__k);
690*0b57cec5SDimitry Andric    if (__i != end())
691*0b57cec5SDimitry Andric        return __i->second;
692*0b57cec5SDimitry Andric    __node_holder __h = __construct_node(__k);
693*0b57cec5SDimitry Andric    std::pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
694*0b57cec5SDimitry Andric    __h.release();
695*0b57cec5SDimitry Andric    return __r.first->second;
696*0b57cec5SDimitry Andric}
697*0b57cec5SDimitry Andric
698*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
699*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
700*0b57cec5SDimitry Andricvoid
701*0b57cec5SDimitry Andricswap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
702*0b57cec5SDimitry Andric     hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
703*0b57cec5SDimitry Andric{
704*0b57cec5SDimitry Andric    __x.swap(__y);
705*0b57cec5SDimitry Andric}
706*0b57cec5SDimitry Andric
707*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
708*0b57cec5SDimitry Andricbool
709*0b57cec5SDimitry Andricoperator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
710*0b57cec5SDimitry Andric           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
711*0b57cec5SDimitry Andric{
712*0b57cec5SDimitry Andric    if (__x.size() != __y.size())
713*0b57cec5SDimitry Andric        return false;
714*0b57cec5SDimitry Andric    typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
715*0b57cec5SDimitry Andric                                                                 const_iterator;
716*0b57cec5SDimitry Andric    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
717*0b57cec5SDimitry Andric            __i != __ex; ++__i)
718*0b57cec5SDimitry Andric    {
719*0b57cec5SDimitry Andric        const_iterator __j = __y.find(__i->first);
720*0b57cec5SDimitry Andric        if (__j == __ey || !(*__i == *__j))
721*0b57cec5SDimitry Andric            return false;
722*0b57cec5SDimitry Andric    }
723*0b57cec5SDimitry Andric    return true;
724*0b57cec5SDimitry Andric}
725*0b57cec5SDimitry Andric
726*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
727*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
728*0b57cec5SDimitry Andricbool
729*0b57cec5SDimitry Andricoperator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
730*0b57cec5SDimitry Andric           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
731*0b57cec5SDimitry Andric{
732*0b57cec5SDimitry Andric    return !(__x == __y);
733*0b57cec5SDimitry Andric}
734*0b57cec5SDimitry Andric
735*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>,
736*0b57cec5SDimitry Andric          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
737*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_multimap
738*0b57cec5SDimitry Andric{
739*0b57cec5SDimitry Andricpublic:
740*0b57cec5SDimitry Andric    // types
741*0b57cec5SDimitry Andric    typedef _Key                                           key_type;
742*0b57cec5SDimitry Andric    typedef _Tp                                            mapped_type;
743*0b57cec5SDimitry Andric    typedef _Tp                                            data_type;
744*0b57cec5SDimitry Andric    typedef _Hash                                          hasher;
745*0b57cec5SDimitry Andric    typedef _Pred                                          key_equal;
746*0b57cec5SDimitry Andric    typedef _Alloc                                         allocator_type;
747*0b57cec5SDimitry Andric    typedef std::pair<const key_type, mapped_type>         value_type;
748*0b57cec5SDimitry Andric    typedef value_type&                                    reference;
749*0b57cec5SDimitry Andric    typedef const value_type&                              const_reference;
750*0b57cec5SDimitry Andric
751*0b57cec5SDimitry Andricprivate:
752*0b57cec5SDimitry Andric    typedef std::pair<key_type, mapped_type>               __value_type;
753*0b57cec5SDimitry Andric    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
754*0b57cec5SDimitry Andric    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
755*0b57cec5SDimitry Andric    typedef typename std::__rebind_alloc_helper<std::allocator_traits<allocator_type>, __value_type>::type __allocator_type;
756*0b57cec5SDimitry Andric
757*0b57cec5SDimitry Andric    typedef std::__hash_table<__value_type, __hasher,
758*0b57cec5SDimitry Andric                         __key_equal,  __allocator_type>   __table;
759*0b57cec5SDimitry Andric
760*0b57cec5SDimitry Andric    __table __table_;
761*0b57cec5SDimitry Andric
762*0b57cec5SDimitry Andric    typedef typename __table::__node_traits                __node_traits;
763*0b57cec5SDimitry Andric    typedef typename __table::__node_allocator             __node_allocator;
764*0b57cec5SDimitry Andric    typedef typename __table::__node                       __node;
765*0b57cec5SDimitry Andric    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
766*0b57cec5SDimitry Andric    typedef std::unique_ptr<__node, _Dp>                         __node_holder;
767*0b57cec5SDimitry Andric    typedef std::allocator_traits<allocator_type>               __alloc_traits;
768*0b57cec5SDimitry Andricpublic:
769*0b57cec5SDimitry Andric    typedef typename __alloc_traits::pointer         pointer;
770*0b57cec5SDimitry Andric    typedef typename __alloc_traits::const_pointer   const_pointer;
771*0b57cec5SDimitry Andric    typedef typename __alloc_traits::size_type       size_type;
772*0b57cec5SDimitry Andric    typedef typename __alloc_traits::difference_type difference_type;
773*0b57cec5SDimitry Andric
774*0b57cec5SDimitry Andric    typedef __hash_map_iterator<typename __table::iterator>       iterator;
775*0b57cec5SDimitry Andric    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
776*0b57cec5SDimitry Andric
777*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
778*0b57cec5SDimitry Andric    hash_multimap() {__table_.rehash(193);}
779*0b57cec5SDimitry Andric    explicit hash_multimap(size_type __n, const hasher& __hf = hasher(),
780*0b57cec5SDimitry Andric                                const key_equal& __eql = key_equal());
781*0b57cec5SDimitry Andric    hash_multimap(size_type __n, const hasher& __hf,
782*0b57cec5SDimitry Andric                                const key_equal& __eql,
783*0b57cec5SDimitry Andric                                const allocator_type& __a);
784*0b57cec5SDimitry Andric    template <class _InputIterator>
785*0b57cec5SDimitry Andric        hash_multimap(_InputIterator __first, _InputIterator __last);
786*0b57cec5SDimitry Andric    template <class _InputIterator>
787*0b57cec5SDimitry Andric        hash_multimap(_InputIterator __first, _InputIterator __last,
788*0b57cec5SDimitry Andric                      size_type __n, const hasher& __hf = hasher(),
789*0b57cec5SDimitry Andric                      const key_equal& __eql = key_equal());
790*0b57cec5SDimitry Andric    template <class _InputIterator>
791*0b57cec5SDimitry Andric        hash_multimap(_InputIterator __first, _InputIterator __last,
792*0b57cec5SDimitry Andric                      size_type __n, const hasher& __hf,
793*0b57cec5SDimitry Andric                      const key_equal& __eql,
794*0b57cec5SDimitry Andric                      const allocator_type& __a);
795*0b57cec5SDimitry Andric    hash_multimap(const hash_multimap& __u);
796*0b57cec5SDimitry Andric
797*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
798*0b57cec5SDimitry Andric    allocator_type get_allocator() const
799*0b57cec5SDimitry Andric        {return allocator_type(__table_.__node_alloc());}
800*0b57cec5SDimitry Andric
801*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
802*0b57cec5SDimitry Andric    bool      empty() const {return __table_.size() == 0;}
803*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
804*0b57cec5SDimitry Andric    size_type size() const  {return __table_.size();}
805*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
806*0b57cec5SDimitry Andric    size_type max_size() const {return __table_.max_size();}
807*0b57cec5SDimitry Andric
808*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
809*0b57cec5SDimitry Andric    iterator       begin()        {return __table_.begin();}
810*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
811*0b57cec5SDimitry Andric    iterator       end()          {return __table_.end();}
812*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
813*0b57cec5SDimitry Andric    const_iterator begin()  const {return __table_.begin();}
814*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
815*0b57cec5SDimitry Andric    const_iterator end()    const {return __table_.end();}
816*0b57cec5SDimitry Andric
817*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
818*0b57cec5SDimitry Andric    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
819*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
820*0b57cec5SDimitry Andric    iterator insert(const_iterator, const value_type& __x) {return insert(__x);}
821*0b57cec5SDimitry Andric    template <class _InputIterator>
822*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
823*0b57cec5SDimitry Andric        void insert(_InputIterator __first, _InputIterator __last);
824*0b57cec5SDimitry Andric
825*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
826*0b57cec5SDimitry Andric    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
827*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
828*0b57cec5SDimitry Andric    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
829*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
830*0b57cec5SDimitry Andric    void erase(const_iterator __first, const_iterator __last)
831*0b57cec5SDimitry Andric        {__table_.erase(__first.__i_, __last.__i_);}
832*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
833*0b57cec5SDimitry Andric    void clear() {__table_.clear();}
834*0b57cec5SDimitry Andric
835*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
836*0b57cec5SDimitry Andric    void swap(hash_multimap& __u) {__table_.swap(__u.__table_);}
837*0b57cec5SDimitry Andric
838*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
839*0b57cec5SDimitry Andric    hasher hash_funct() const
840*0b57cec5SDimitry Andric        {return __table_.hash_function().hash_function();}
841*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
842*0b57cec5SDimitry Andric    key_equal key_eq() const
843*0b57cec5SDimitry Andric        {return __table_.key_eq().key_eq();}
844*0b57cec5SDimitry Andric
845*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
846*0b57cec5SDimitry Andric    iterator       find(const key_type& __k)       {return __table_.find(__k);}
847*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
848*0b57cec5SDimitry Andric    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
849*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
850*0b57cec5SDimitry Andric    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
851*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
852*0b57cec5SDimitry Andric    std::pair<iterator, iterator>             equal_range(const key_type& __k)
853*0b57cec5SDimitry Andric        {return __table_.__equal_range_multi(__k);}
854*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
855*0b57cec5SDimitry Andric    std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
856*0b57cec5SDimitry Andric        {return __table_.__equal_range_multi(__k);}
857*0b57cec5SDimitry Andric
858*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
859*0b57cec5SDimitry Andric    size_type bucket_count() const {return __table_.bucket_count();}
860*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
861*0b57cec5SDimitry Andric    size_type max_bucket_count() const {return __table_.max_bucket_count();}
862*0b57cec5SDimitry Andric
863*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
864*0b57cec5SDimitry Andric    size_type elems_in_bucket(size_type __n) const
865*0b57cec5SDimitry Andric        {return __table_.bucket_size(__n);}
866*0b57cec5SDimitry Andric
867*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
868*0b57cec5SDimitry Andric    void resize(size_type __n) {__table_.rehash(__n);}
869*0b57cec5SDimitry Andric};
870*0b57cec5SDimitry Andric
871*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
872*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
873*0b57cec5SDimitry Andric        size_type __n, const hasher& __hf, const key_equal& __eql)
874*0b57cec5SDimitry Andric    : __table_(__hf, __eql)
875*0b57cec5SDimitry Andric{
876*0b57cec5SDimitry Andric    __table_.rehash(__n);
877*0b57cec5SDimitry Andric}
878*0b57cec5SDimitry Andric
879*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
880*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
881*0b57cec5SDimitry Andric        size_type __n, const hasher& __hf, const key_equal& __eql,
882*0b57cec5SDimitry Andric        const allocator_type& __a)
883*0b57cec5SDimitry Andric    : __table_(__hf, __eql, __a)
884*0b57cec5SDimitry Andric{
885*0b57cec5SDimitry Andric    __table_.rehash(__n);
886*0b57cec5SDimitry Andric}
887*0b57cec5SDimitry Andric
888*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
889*0b57cec5SDimitry Andrictemplate <class _InputIterator>
890*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
891*0b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last)
892*0b57cec5SDimitry Andric{
893*0b57cec5SDimitry Andric    __table_.rehash(193);
894*0b57cec5SDimitry Andric    insert(__first, __last);
895*0b57cec5SDimitry Andric}
896*0b57cec5SDimitry Andric
897*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
898*0b57cec5SDimitry Andrictemplate <class _InputIterator>
899*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
900*0b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last, size_type __n,
901*0b57cec5SDimitry Andric        const hasher& __hf, const key_equal& __eql)
902*0b57cec5SDimitry Andric    : __table_(__hf, __eql)
903*0b57cec5SDimitry Andric{
904*0b57cec5SDimitry Andric    __table_.rehash(__n);
905*0b57cec5SDimitry Andric    insert(__first, __last);
906*0b57cec5SDimitry Andric}
907*0b57cec5SDimitry Andric
908*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
909*0b57cec5SDimitry Andrictemplate <class _InputIterator>
910*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
911*0b57cec5SDimitry Andric        _InputIterator __first, _InputIterator __last, size_type __n,
912*0b57cec5SDimitry Andric        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
913*0b57cec5SDimitry Andric    : __table_(__hf, __eql, __a)
914*0b57cec5SDimitry Andric{
915*0b57cec5SDimitry Andric    __table_.rehash(__n);
916*0b57cec5SDimitry Andric    insert(__first, __last);
917*0b57cec5SDimitry Andric}
918*0b57cec5SDimitry Andric
919*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
920*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
921*0b57cec5SDimitry Andric        const hash_multimap& __u)
922*0b57cec5SDimitry Andric    : __table_(__u.__table_)
923*0b57cec5SDimitry Andric{
924*0b57cec5SDimitry Andric    __table_.rehash(__u.bucket_count());
925*0b57cec5SDimitry Andric    insert(__u.begin(), __u.end());
926*0b57cec5SDimitry Andric}
927*0b57cec5SDimitry Andric
928*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
929*0b57cec5SDimitry Andrictemplate <class _InputIterator>
930*0b57cec5SDimitry Andricinline
931*0b57cec5SDimitry Andricvoid
932*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
933*0b57cec5SDimitry Andric                                                            _InputIterator __last)
934*0b57cec5SDimitry Andric{
935*0b57cec5SDimitry Andric    for (; __first != __last; ++__first)
936*0b57cec5SDimitry Andric        __table_.__insert_multi(*__first);
937*0b57cec5SDimitry Andric}
938*0b57cec5SDimitry Andric
939*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
940*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
941*0b57cec5SDimitry Andricvoid
942*0b57cec5SDimitry Andricswap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
943*0b57cec5SDimitry Andric     hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
944*0b57cec5SDimitry Andric{
945*0b57cec5SDimitry Andric    __x.swap(__y);
946*0b57cec5SDimitry Andric}
947*0b57cec5SDimitry Andric
948*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
949*0b57cec5SDimitry Andricbool
950*0b57cec5SDimitry Andricoperator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
951*0b57cec5SDimitry Andric           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
952*0b57cec5SDimitry Andric{
953*0b57cec5SDimitry Andric    if (__x.size() != __y.size())
954*0b57cec5SDimitry Andric        return false;
955*0b57cec5SDimitry Andric    typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
956*0b57cec5SDimitry Andric                                                                 const_iterator;
957*0b57cec5SDimitry Andric    typedef std::pair<const_iterator, const_iterator> _EqRng;
958*0b57cec5SDimitry Andric    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
959*0b57cec5SDimitry Andric    {
960*0b57cec5SDimitry Andric        _EqRng __xeq = __x.equal_range(__i->first);
961*0b57cec5SDimitry Andric        _EqRng __yeq = __y.equal_range(__i->first);
962*0b57cec5SDimitry Andric        if (_VSTD::distance(__xeq.first, __xeq.second) !=
963*0b57cec5SDimitry Andric            _VSTD::distance(__yeq.first, __yeq.second) ||
964*0b57cec5SDimitry Andric                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
965*0b57cec5SDimitry Andric            return false;
966*0b57cec5SDimitry Andric        __i = __xeq.second;
967*0b57cec5SDimitry Andric    }
968*0b57cec5SDimitry Andric    return true;
969*0b57cec5SDimitry Andric}
970*0b57cec5SDimitry Andric
971*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
972*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
973*0b57cec5SDimitry Andricbool
974*0b57cec5SDimitry Andricoperator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
975*0b57cec5SDimitry Andric           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
976*0b57cec5SDimitry Andric{
977*0b57cec5SDimitry Andric    return !(__x == __y);
978*0b57cec5SDimitry Andric}
979*0b57cec5SDimitry Andric
980*0b57cec5SDimitry Andric} // __gnu_cxx
981*0b57cec5SDimitry Andric
982*0b57cec5SDimitry Andric#endif  // _LIBCPP_HASH_MAP
983