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