blob: 348f57923b528557555dfa67d00f52e153fc1f3f [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:16 +00001// -*- C++ -*-
2//===-------------------------- unordered_map -----------------------------===//
3//
Howard Hinnant5b08a8a2010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnant3e519522010-05-11 19:42:16 +00005//
Howard Hinnant412dbeb2010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnant3e519522010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_UNORDERED_MAP
12#define _LIBCPP_UNORDERED_MAP
13
14/*
15
16 unordered_map synopsis
17
18#include <initializer_list>
19
20namespace std
21{
22
23template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
24 class Alloc = allocator<pair<const Key, T>>>
25class unordered_map
26{
27public:
28 // types
29 typedef Key key_type;
30 typedef T mapped_type;
31 typedef Hash hasher;
32 typedef Pred key_equal;
33 typedef Alloc allocator_type;
34 typedef pair<const key_type, mapped_type> value_type;
35 typedef value_type& reference;
36 typedef const value_type& const_reference;
37 typedef typename allocator_traits<allocator_type>::pointer pointer;
38 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
39 typedef typename allocator_traits<allocator_type>::size_type size_type;
40 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
41
42 typedef /unspecified/ iterator;
43 typedef /unspecified/ const_iterator;
44 typedef /unspecified/ local_iterator;
45 typedef /unspecified/ const_local_iterator;
46
Erik Pilkingtonb0386a52018-08-01 01:33:38 +000047 typedef unspecified node_type; // C++17
48 typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
49
Howard Hinnant37141072011-06-04 18:54:24 +000050 unordered_map()
51 noexcept(
52 is_nothrow_default_constructible<hasher>::value &&
53 is_nothrow_default_constructible<key_equal>::value &&
54 is_nothrow_default_constructible<allocator_type>::value);
55 explicit unordered_map(size_type n, const hasher& hf = hasher(),
Howard Hinnant3e519522010-05-11 19:42:16 +000056 const key_equal& eql = key_equal(),
57 const allocator_type& a = allocator_type());
58 template <class InputIterator>
59 unordered_map(InputIterator f, InputIterator l,
60 size_type n = 0, const hasher& hf = hasher(),
61 const key_equal& eql = key_equal(),
62 const allocator_type& a = allocator_type());
63 explicit unordered_map(const allocator_type&);
64 unordered_map(const unordered_map&);
65 unordered_map(const unordered_map&, const Allocator&);
Howard Hinnant37141072011-06-04 18:54:24 +000066 unordered_map(unordered_map&&)
67 noexcept(
68 is_nothrow_move_constructible<hasher>::value &&
69 is_nothrow_move_constructible<key_equal>::value &&
70 is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +000071 unordered_map(unordered_map&&, const Allocator&);
72 unordered_map(initializer_list<value_type>, size_type n = 0,
73 const hasher& hf = hasher(), const key_equal& eql = key_equal(),
74 const allocator_type& a = allocator_type());
Marshall Clow3cd37e62013-09-12 03:00:31 +000075 unordered_map(size_type n, const allocator_type& a)
76 : unordered_map(n, hasher(), key_equal(), a) {} // C++14
77 unordered_map(size_type n, const hasher& hf, const allocator_type& a)
78 : unordered_map(n, hf, key_equal(), a) {} // C++14
79 template <class InputIterator>
80 unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
81 : unordered_map(f, l, n, hasher(), key_equal(), a) {} // C++14
82 template <class InputIterator>
83 unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
84 const allocator_type& a)
85 : unordered_map(f, l, n, hf, key_equal(), a) {} // C++14
86 unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
87 : unordered_map(il, n, hasher(), key_equal(), a) {} // C++14
88 unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf,
89 const allocator_type& a)
90 : unordered_map(il, n, hf, key_equal(), a) {} // C++14
Howard Hinnant3e519522010-05-11 19:42:16 +000091 ~unordered_map();
92 unordered_map& operator=(const unordered_map&);
Howard Hinnant37141072011-06-04 18:54:24 +000093 unordered_map& operator=(unordered_map&&)
94 noexcept(
95 allocator_type::propagate_on_container_move_assignment::value &&
96 is_nothrow_move_assignable<allocator_type>::value &&
97 is_nothrow_move_assignable<hasher>::value &&
98 is_nothrow_move_assignable<key_equal>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +000099 unordered_map& operator=(initializer_list<value_type>);
100
Howard Hinnant37141072011-06-04 18:54:24 +0000101 allocator_type get_allocator() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000102
Howard Hinnant37141072011-06-04 18:54:24 +0000103 bool empty() const noexcept;
104 size_type size() const noexcept;
105 size_type max_size() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000106
Howard Hinnant37141072011-06-04 18:54:24 +0000107 iterator begin() noexcept;
108 iterator end() noexcept;
109 const_iterator begin() const noexcept;
110 const_iterator end() const noexcept;
111 const_iterator cbegin() const noexcept;
112 const_iterator cend() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000113
114 template <class... Args>
115 pair<iterator, bool> emplace(Args&&... args);
116 template <class... Args>
117 iterator emplace_hint(const_iterator position, Args&&... args);
118 pair<iterator, bool> insert(const value_type& obj);
119 template <class P>
120 pair<iterator, bool> insert(P&& obj);
121 iterator insert(const_iterator hint, const value_type& obj);
122 template <class P>
123 iterator insert(const_iterator hint, P&& obj);
124 template <class InputIterator>
125 void insert(InputIterator first, InputIterator last);
126 void insert(initializer_list<value_type>);
127
Erik Pilkingtonb0386a52018-08-01 01:33:38 +0000128 node_type extract(const_iterator position); // C++17
129 node_type extract(const key_type& x); // C++17
130 insert_return_type insert(node_type&& nh); // C++17
131 iterator insert(const_iterator hint, node_type&& nh); // C++17
132
Marshall Clowbc4c89a2015-07-07 05:45:35 +0000133 template <class... Args>
134 pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
135 template <class... Args>
136 pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17
137 template <class... Args>
138 iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
139 template <class... Args>
140 iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17
141 template <class M>
142 pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
143 template <class M>
144 pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
145 template <class M>
146 iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
147 template <class M>
148 iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
149
Howard Hinnant3e519522010-05-11 19:42:16 +0000150 iterator erase(const_iterator position);
Marshall Clowec392962015-05-10 13:35:00 +0000151 iterator erase(iterator position); // C++14
Howard Hinnant3e519522010-05-11 19:42:16 +0000152 size_type erase(const key_type& k);
153 iterator erase(const_iterator first, const_iterator last);
Howard Hinnant37141072011-06-04 18:54:24 +0000154 void clear() noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000155
Howard Hinnant37141072011-06-04 18:54:24 +0000156 void swap(unordered_map&)
157 noexcept(
158 (!allocator_type::propagate_on_container_swap::value ||
159 __is_nothrow_swappable<allocator_type>::value) &&
160 __is_nothrow_swappable<hasher>::value &&
161 __is_nothrow_swappable<key_equal>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000162
163 hasher hash_function() const;
164 key_equal key_eq() const;
165
166 iterator find(const key_type& k);
167 const_iterator find(const key_type& k) const;
168 size_type count(const key_type& k) const;
169 pair<iterator, iterator> equal_range(const key_type& k);
170 pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
171
172 mapped_type& operator[](const key_type& k);
173 mapped_type& operator[](key_type&& k);
174
175 mapped_type& at(const key_type& k);
176 const mapped_type& at(const key_type& k) const;
177
Howard Hinnant37141072011-06-04 18:54:24 +0000178 size_type bucket_count() const noexcept;
179 size_type max_bucket_count() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000180
181 size_type bucket_size(size_type n) const;
182 size_type bucket(const key_type& k) const;
183
184 local_iterator begin(size_type n);
185 local_iterator end(size_type n);
186 const_local_iterator begin(size_type n) const;
187 const_local_iterator end(size_type n) const;
188 const_local_iterator cbegin(size_type n) const;
189 const_local_iterator cend(size_type n) const;
190
Howard Hinnant37141072011-06-04 18:54:24 +0000191 float load_factor() const noexcept;
192 float max_load_factor() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000193 void max_load_factor(float z);
194 void rehash(size_type n);
195 void reserve(size_type n);
196};
197
198template <class Key, class T, class Hash, class Pred, class Alloc>
199 void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
Howard Hinnant37141072011-06-04 18:54:24 +0000200 unordered_map<Key, T, Hash, Pred, Alloc>& y)
201 noexcept(noexcept(x.swap(y)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000202
203template <class Key, class T, class Hash, class Pred, class Alloc>
204 bool
205 operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& x,
206 const unordered_map<Key, T, Hash, Pred, Alloc>& y);
207
208template <class Key, class T, class Hash, class Pred, class Alloc>
209 bool
210 operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& x,
211 const unordered_map<Key, T, Hash, Pred, Alloc>& y);
212
213template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
214 class Alloc = allocator<pair<const Key, T>>>
215class unordered_multimap
216{
217public:
218 // types
219 typedef Key key_type;
220 typedef T mapped_type;
221 typedef Hash hasher;
222 typedef Pred key_equal;
223 typedef Alloc allocator_type;
224 typedef pair<const key_type, mapped_type> value_type;
225 typedef value_type& reference;
226 typedef const value_type& const_reference;
227 typedef typename allocator_traits<allocator_type>::pointer pointer;
228 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
229 typedef typename allocator_traits<allocator_type>::size_type size_type;
230 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
231
232 typedef /unspecified/ iterator;
233 typedef /unspecified/ const_iterator;
234 typedef /unspecified/ local_iterator;
235 typedef /unspecified/ const_local_iterator;
236
Erik Pilkingtonb0386a52018-08-01 01:33:38 +0000237 typedef unspecified node_type; // C++17
238
Howard Hinnant37141072011-06-04 18:54:24 +0000239 unordered_multimap()
240 noexcept(
241 is_nothrow_default_constructible<hasher>::value &&
242 is_nothrow_default_constructible<key_equal>::value &&
243 is_nothrow_default_constructible<allocator_type>::value);
244 explicit unordered_multimap(size_type n, const hasher& hf = hasher(),
Howard Hinnant3e519522010-05-11 19:42:16 +0000245 const key_equal& eql = key_equal(),
246 const allocator_type& a = allocator_type());
247 template <class InputIterator>
248 unordered_multimap(InputIterator f, InputIterator l,
249 size_type n = 0, const hasher& hf = hasher(),
250 const key_equal& eql = key_equal(),
251 const allocator_type& a = allocator_type());
252 explicit unordered_multimap(const allocator_type&);
253 unordered_multimap(const unordered_multimap&);
254 unordered_multimap(const unordered_multimap&, const Allocator&);
Howard Hinnant37141072011-06-04 18:54:24 +0000255 unordered_multimap(unordered_multimap&&)
256 noexcept(
257 is_nothrow_move_constructible<hasher>::value &&
258 is_nothrow_move_constructible<key_equal>::value &&
259 is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000260 unordered_multimap(unordered_multimap&&, const Allocator&);
261 unordered_multimap(initializer_list<value_type>, size_type n = 0,
262 const hasher& hf = hasher(), const key_equal& eql = key_equal(),
263 const allocator_type& a = allocator_type());
Marshall Clow3cd37e62013-09-12 03:00:31 +0000264 unordered_multimap(size_type n, const allocator_type& a)
265 : unordered_multimap(n, hasher(), key_equal(), a) {} // C++14
266 unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
267 : unordered_multimap(n, hf, key_equal(), a) {} // C++14
268 template <class InputIterator>
269 unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
270 : unordered_multimap(f, l, n, hasher(), key_equal(), a) {} // C++14
271 template <class InputIterator>
272 unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
273 const allocator_type& a)
274 : unordered_multimap(f, l, n, hf, key_equal(), a) {} // C++14
275 unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
276 : unordered_multimap(il, n, hasher(), key_equal(), a) {} // C++14
277 unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf,
278 const allocator_type& a)
279 : unordered_multimap(il, n, hf, key_equal(), a) {} // C++14
Howard Hinnant3e519522010-05-11 19:42:16 +0000280 ~unordered_multimap();
281 unordered_multimap& operator=(const unordered_multimap&);
Howard Hinnant37141072011-06-04 18:54:24 +0000282 unordered_multimap& operator=(unordered_multimap&&)
283 noexcept(
284 allocator_type::propagate_on_container_move_assignment::value &&
285 is_nothrow_move_assignable<allocator_type>::value &&
286 is_nothrow_move_assignable<hasher>::value &&
287 is_nothrow_move_assignable<key_equal>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000288 unordered_multimap& operator=(initializer_list<value_type>);
289
Howard Hinnant37141072011-06-04 18:54:24 +0000290 allocator_type get_allocator() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000291
Howard Hinnant37141072011-06-04 18:54:24 +0000292 bool empty() const noexcept;
293 size_type size() const noexcept;
294 size_type max_size() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000295
Howard Hinnant37141072011-06-04 18:54:24 +0000296 iterator begin() noexcept;
297 iterator end() noexcept;
298 const_iterator begin() const noexcept;
299 const_iterator end() const noexcept;
300 const_iterator cbegin() const noexcept;
301 const_iterator cend() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000302
303 template <class... Args>
304 iterator emplace(Args&&... args);
305 template <class... Args>
306 iterator emplace_hint(const_iterator position, Args&&... args);
307 iterator insert(const value_type& obj);
308 template <class P>
309 iterator insert(P&& obj);
310 iterator insert(const_iterator hint, const value_type& obj);
311 template <class P>
312 iterator insert(const_iterator hint, P&& obj);
313 template <class InputIterator>
314 void insert(InputIterator first, InputIterator last);
315 void insert(initializer_list<value_type>);
316
Erik Pilkingtonb0386a52018-08-01 01:33:38 +0000317 node_type extract(const_iterator position); // C++17
318 node_type extract(const key_type& x); // C++17
319 iterator insert(node_type&& nh); // C++17
320 iterator insert(const_iterator hint, node_type&& nh); // C++17
321
Howard Hinnant3e519522010-05-11 19:42:16 +0000322 iterator erase(const_iterator position);
Marshall Clowec392962015-05-10 13:35:00 +0000323 iterator erase(iterator position); // C++14
Howard Hinnant3e519522010-05-11 19:42:16 +0000324 size_type erase(const key_type& k);
325 iterator erase(const_iterator first, const_iterator last);
Howard Hinnant37141072011-06-04 18:54:24 +0000326 void clear() noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000327
Howard Hinnant37141072011-06-04 18:54:24 +0000328 void swap(unordered_multimap&)
329 noexcept(
330 (!allocator_type::propagate_on_container_swap::value ||
331 __is_nothrow_swappable<allocator_type>::value) &&
332 __is_nothrow_swappable<hasher>::value &&
333 __is_nothrow_swappable<key_equal>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000334
335 hasher hash_function() const;
336 key_equal key_eq() const;
337
338 iterator find(const key_type& k);
339 const_iterator find(const key_type& k) const;
340 size_type count(const key_type& k) const;
341 pair<iterator, iterator> equal_range(const key_type& k);
342 pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
343
Howard Hinnant37141072011-06-04 18:54:24 +0000344 size_type bucket_count() const noexcept;
345 size_type max_bucket_count() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000346
347 size_type bucket_size(size_type n) const;
348 size_type bucket(const key_type& k) const;
349
350 local_iterator begin(size_type n);
351 local_iterator end(size_type n);
352 const_local_iterator begin(size_type n) const;
353 const_local_iterator end(size_type n) const;
354 const_local_iterator cbegin(size_type n) const;
355 const_local_iterator cend(size_type n) const;
356
Howard Hinnant37141072011-06-04 18:54:24 +0000357 float load_factor() const noexcept;
358 float max_load_factor() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000359 void max_load_factor(float z);
360 void rehash(size_type n);
361 void reserve(size_type n);
362};
363
364template <class Key, class T, class Hash, class Pred, class Alloc>
365 void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
Howard Hinnant37141072011-06-04 18:54:24 +0000366 unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
367 noexcept(noexcept(x.swap(y)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000368
369template <class Key, class T, class Hash, class Pred, class Alloc>
370 bool
371 operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
372 const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
373
374template <class Key, class T, class Hash, class Pred, class Alloc>
375 bool
376 operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
377 const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
378
379} // std
380
381*/
382
383#include <__config>
384#include <__hash_table>
Erik Pilkingtonb0386a52018-08-01 01:33:38 +0000385#include <__node_handle>
Howard Hinnant3e519522010-05-11 19:42:16 +0000386#include <functional>
387#include <stdexcept>
Eric Fiselier0f905672016-02-11 21:45:53 +0000388#include <tuple>
Howard Hinnant3e519522010-05-11 19:42:16 +0000389
Eric Fiselierc1bd9192014-08-10 23:53:08 +0000390#include <__debug>
391
Howard Hinnant073458b2011-10-17 20:05:10 +0000392#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant3e519522010-05-11 19:42:16 +0000393#pragma GCC system_header
Howard Hinnant073458b2011-10-17 20:05:10 +0000394#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000395
396_LIBCPP_BEGIN_NAMESPACE_STD
397
Eric Fiselier04333f92017-01-13 22:42:53 +0000398template <class _Key, class _Cp, class _Hash, bool _IsEmpty>
Howard Hinnant3e519522010-05-11 19:42:16 +0000399class __unordered_map_hasher
400 : private _Hash
401{
402public:
Howard Hinnant789847d2010-09-23 18:58:28 +0000403 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000404 __unordered_map_hasher()
405 _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value)
406 : _Hash() {}
Howard Hinnant789847d2010-09-23 18:58:28 +0000407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000408 __unordered_map_hasher(const _Hash& __h)
409 _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value)
410 : _Hash(__h) {}
Howard Hinnant789847d2010-09-23 18:58:28 +0000411 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000412 const _Hash& hash_function() const _NOEXCEPT {return *this;}
Howard Hinnant789847d2010-09-23 18:58:28 +0000413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000414 size_t operator()(const _Cp& __x) const
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000415 {return static_cast<const _Hash&>(*this)(__x.__get_value().first);}
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000416 _LIBCPP_INLINE_VISIBILITY
417 size_t operator()(const _Key& __x) const
Howard Hinnant3e519522010-05-11 19:42:16 +0000418 {return static_cast<const _Hash&>(*this)(__x);}
Marshall Clowe3fbe142015-07-13 20:04:56 +0000419 void swap(__unordered_map_hasher&__y)
420 _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value)
421 {
422 using _VSTD::swap;
Eric Fiselierb3f57422017-04-13 01:02:41 +0000423 swap(static_cast<_Hash&>(*this), static_cast<_Hash&>(__y));
Marshall Clowe3fbe142015-07-13 20:04:56 +0000424 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000425};
426
Howard Hinnantabb160e2013-07-05 18:06:00 +0000427template <class _Key, class _Cp, class _Hash>
428class __unordered_map_hasher<_Key, _Cp, _Hash, false>
Howard Hinnant3e519522010-05-11 19:42:16 +0000429{
430 _Hash __hash_;
431public:
Howard Hinnant789847d2010-09-23 18:58:28 +0000432 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000433 __unordered_map_hasher()
434 _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value)
435 : __hash_() {}
Howard Hinnant789847d2010-09-23 18:58:28 +0000436 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000437 __unordered_map_hasher(const _Hash& __h)
438 _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value)
439 : __hash_(__h) {}
Howard Hinnant789847d2010-09-23 18:58:28 +0000440 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000441 const _Hash& hash_function() const _NOEXCEPT {return __hash_;}
Howard Hinnant789847d2010-09-23 18:58:28 +0000442 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000443 size_t operator()(const _Cp& __x) const
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000444 {return __hash_(__x.__get_value().first);}
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000445 _LIBCPP_INLINE_VISIBILITY
446 size_t operator()(const _Key& __x) const
Howard Hinnant3e519522010-05-11 19:42:16 +0000447 {return __hash_(__x);}
Marshall Clowe3fbe142015-07-13 20:04:56 +0000448 void swap(__unordered_map_hasher&__y)
449 _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value)
450 {
451 using _VSTD::swap;
452 swap(__hash_, __y.__hash_);
453 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000454};
455
Marshall Clowe3fbe142015-07-13 20:04:56 +0000456template <class _Key, class _Cp, class _Hash, bool __b>
457inline _LIBCPP_INLINE_VISIBILITY
458void
459swap(__unordered_map_hasher<_Key, _Cp, _Hash, __b>& __x,
460 __unordered_map_hasher<_Key, _Cp, _Hash, __b>& __y)
461 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
462{
463 __x.swap(__y);
464}
465
Eric Fiselier04333f92017-01-13 22:42:53 +0000466template <class _Key, class _Cp, class _Pred, bool _IsEmpty>
Howard Hinnant3e519522010-05-11 19:42:16 +0000467class __unordered_map_equal
468 : private _Pred
469{
470public:
Howard Hinnant789847d2010-09-23 18:58:28 +0000471 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000472 __unordered_map_equal()
473 _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value)
474 : _Pred() {}
Howard Hinnant789847d2010-09-23 18:58:28 +0000475 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000476 __unordered_map_equal(const _Pred& __p)
477 _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value)
478 : _Pred(__p) {}
Howard Hinnant789847d2010-09-23 18:58:28 +0000479 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000480 const _Pred& key_eq() const _NOEXCEPT {return *this;}
Howard Hinnant789847d2010-09-23 18:58:28 +0000481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000482 bool operator()(const _Cp& __x, const _Cp& __y) const
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000483 {return static_cast<const _Pred&>(*this)(__x.__get_value().first, __y.__get_value().first);}
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000484 _LIBCPP_INLINE_VISIBILITY
485 bool operator()(const _Cp& __x, const _Key& __y) const
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000486 {return static_cast<const _Pred&>(*this)(__x.__get_value().first, __y);}
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000487 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000488 bool operator()(const _Key& __x, const _Cp& __y) const
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000489 {return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);}
Marshall Clowe3fbe142015-07-13 20:04:56 +0000490 void swap(__unordered_map_equal&__y)
491 _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value)
492 {
493 using _VSTD::swap;
Eric Fiselierb3f57422017-04-13 01:02:41 +0000494 swap(static_cast<_Pred&>(*this), static_cast<_Pred&>(__y));
Marshall Clowe3fbe142015-07-13 20:04:56 +0000495 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000496};
497
Howard Hinnantabb160e2013-07-05 18:06:00 +0000498template <class _Key, class _Cp, class _Pred>
499class __unordered_map_equal<_Key, _Cp, _Pred, false>
Howard Hinnant3e519522010-05-11 19:42:16 +0000500{
501 _Pred __pred_;
502public:
Howard Hinnant789847d2010-09-23 18:58:28 +0000503 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000504 __unordered_map_equal()
505 _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value)
506 : __pred_() {}
Howard Hinnant789847d2010-09-23 18:58:28 +0000507 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000508 __unordered_map_equal(const _Pred& __p)
509 _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value)
510 : __pred_(__p) {}
Howard Hinnant789847d2010-09-23 18:58:28 +0000511 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000512 const _Pred& key_eq() const _NOEXCEPT {return __pred_;}
Howard Hinnant789847d2010-09-23 18:58:28 +0000513 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000514 bool operator()(const _Cp& __x, const _Cp& __y) const
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000515 {return __pred_(__x.__get_value().first, __y.__get_value().first);}
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000516 _LIBCPP_INLINE_VISIBILITY
517 bool operator()(const _Cp& __x, const _Key& __y) const
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000518 {return __pred_(__x.__get_value().first, __y);}
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000519 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta1a9e772011-12-12 17:26:24 +0000520 bool operator()(const _Key& __x, const _Cp& __y) const
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000521 {return __pred_(__x, __y.__get_value().first);}
Marshall Clowe3fbe142015-07-13 20:04:56 +0000522 void swap(__unordered_map_equal&__y)
523 _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value)
524 {
525 using _VSTD::swap;
526 swap(__pred_, __y.__pred_);
527 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000528};
529
Marshall Clowe3fbe142015-07-13 20:04:56 +0000530template <class _Key, class _Cp, class _Pred, bool __b>
531inline _LIBCPP_INLINE_VISIBILITY
532void
533swap(__unordered_map_equal<_Key, _Cp, _Pred, __b>& __x,
534 __unordered_map_equal<_Key, _Cp, _Pred, __b>& __y)
535 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
536{
537 __x.swap(__y);
538}
539
Howard Hinnant3e519522010-05-11 19:42:16 +0000540template <class _Alloc>
541class __hash_map_node_destructor
542{
543 typedef _Alloc allocator_type;
544 typedef allocator_traits<allocator_type> __alloc_traits;
Eric Fiselier75d0dcf2016-02-10 20:46:23 +0000545
Howard Hinnant3e519522010-05-11 19:42:16 +0000546public:
Eric Fiselier75d0dcf2016-02-10 20:46:23 +0000547
548 typedef typename __alloc_traits::pointer pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000549private:
Howard Hinnant3e519522010-05-11 19:42:16 +0000550
551 allocator_type& __na_;
552
553 __hash_map_node_destructor& operator=(const __hash_map_node_destructor&);
554
555public:
556 bool __first_constructed;
557 bool __second_constructed;
558
Howard Hinnant789847d2010-09-23 18:58:28 +0000559 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000560 explicit __hash_map_node_destructor(allocator_type& __na) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000561 : __na_(__na),
562 __first_constructed(false),
563 __second_constructed(false)
564 {}
565
Eric Fiselier6a470bc2017-04-18 22:50:56 +0000566#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant789847d2010-09-23 18:58:28 +0000567 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000568 __hash_map_node_destructor(__hash_node_destructor<allocator_type>&& __x)
Howard Hinnant37141072011-06-04 18:54:24 +0000569 _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000570 : __na_(__x.__na_),
571 __first_constructed(__x.__value_constructed),
572 __second_constructed(__x.__value_constructed)
573 {
574 __x.__value_constructed = false;
575 }
Eric Fiselier6a470bc2017-04-18 22:50:56 +0000576#else // _LIBCPP_CXX03_LANG
Howard Hinnant789847d2010-09-23 18:58:28 +0000577 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000578 __hash_map_node_destructor(const __hash_node_destructor<allocator_type>& __x)
579 : __na_(__x.__na_),
580 __first_constructed(__x.__value_constructed),
581 __second_constructed(__x.__value_constructed)
582 {
583 const_cast<bool&>(__x.__value_constructed) = false;
584 }
Eric Fiselier6a470bc2017-04-18 22:50:56 +0000585#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000586
Howard Hinnant789847d2010-09-23 18:58:28 +0000587 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000588 void operator()(pointer __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000589 {
590 if (__second_constructed)
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000591 __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().second));
Howard Hinnant3e519522010-05-11 19:42:16 +0000592 if (__first_constructed)
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000593 __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().first));
Howard Hinnant3e519522010-05-11 19:42:16 +0000594 if (__p)
595 __alloc_traits::deallocate(__na_, __p, 1);
596 }
597};
598
Eric Fiselierfcd02212016-02-11 11:59:44 +0000599#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000600template <class _Key, class _Tp>
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000601struct __hash_value_type
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000602{
603 typedef _Key key_type;
604 typedef _Tp mapped_type;
605 typedef pair<const key_type, mapped_type> value_type;
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000606 typedef pair<key_type&, mapped_type&> __nc_ref_pair_type;
607 typedef pair<key_type&&, mapped_type&&> __nc_rref_pair_type;
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000608
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000609private:
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000610 value_type __cc;
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000611
612public:
613 _LIBCPP_INLINE_VISIBILITY
614 value_type& __get_value()
615 {
616#if _LIBCPP_STD_VER > 14
617 return *_VSTD::launder(_VSTD::addressof(__cc));
618#else
619 return __cc;
620#endif
621 }
622
623 _LIBCPP_INLINE_VISIBILITY
624 const value_type& __get_value() const
625 {
626#if _LIBCPP_STD_VER > 14
627 return *_VSTD::launder(_VSTD::addressof(__cc));
628#else
629 return __cc;
630#endif
631 }
632
633 _LIBCPP_INLINE_VISIBILITY
634 __nc_ref_pair_type __ref()
635 {
636 value_type& __v = __get_value();
637 return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second);
638 }
639
640 _LIBCPP_INLINE_VISIBILITY
641 __nc_rref_pair_type __move()
642 {
643 value_type& __v = __get_value();
644 return __nc_rref_pair_type(
645 _VSTD::move(const_cast<key_type&>(__v.first)),
646 _VSTD::move(__v.second));
647 }
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000648
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000649 _LIBCPP_INLINE_VISIBILITY
650 __hash_value_type& operator=(const __hash_value_type& __v)
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000651 {
652 __ref() = __v.__get_value();
653 return *this;
654 }
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000655
656 _LIBCPP_INLINE_VISIBILITY
657 __hash_value_type& operator=(__hash_value_type&& __v)
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000658 {
659 __ref() = __v.__move();
660 return *this;
661 }
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000662
Eric Fiselierfcd02212016-02-11 11:59:44 +0000663 template <class _ValueTp,
664 class = typename enable_if<
665 __is_same_uncvref<_ValueTp, value_type>::value
666 >::type
667 >
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000668 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000669 __hash_value_type& operator=(_ValueTp&& __v)
670 {
671 __ref() = _VSTD::forward<_ValueTp>(__v);
672 return *this;
Eric Fiselierfcd02212016-02-11 11:59:44 +0000673 }
674
675private:
676 __hash_value_type(const __hash_value_type& __v) = delete;
677 __hash_value_type(__hash_value_type&& __v) = delete;
678 template <class ..._Args>
679 explicit __hash_value_type(_Args&& ...__args) = delete;
680
681 ~__hash_value_type() = delete;
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000682};
683
684#else
685
686template <class _Key, class _Tp>
687struct __hash_value_type
688{
689 typedef _Key key_type;
690 typedef _Tp mapped_type;
691 typedef pair<const key_type, mapped_type> value_type;
692
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000693private:
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000694 value_type __cc;
695
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000696public:
697 _LIBCPP_INLINE_VISIBILITY
698 value_type& __get_value() { return __cc; }
699 _LIBCPP_INLINE_VISIBILITY
700 const value_type& __get_value() const { return __cc; }
701
Eric Fiselierfcd02212016-02-11 11:59:44 +0000702private:
703 ~__hash_value_type();
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000704};
705
706#endif
707
Howard Hinnant3e519522010-05-11 19:42:16 +0000708template <class _HashIterator>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000709class _LIBCPP_TEMPLATE_VIS __hash_map_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000710{
711 _HashIterator __i_;
712
Eric Fiselier75d0dcf2016-02-10 20:46:23 +0000713 typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes;
714
Howard Hinnant3e519522010-05-11 19:42:16 +0000715public:
716 typedef forward_iterator_tag iterator_category;
Eric Fiselier75d0dcf2016-02-10 20:46:23 +0000717 typedef typename _NodeTypes::__map_value_type value_type;
718 typedef typename _NodeTypes::difference_type difference_type;
Howard Hinnant3e519522010-05-11 19:42:16 +0000719 typedef value_type& reference;
Eric Fiselier75d0dcf2016-02-10 20:46:23 +0000720 typedef typename _NodeTypes::__map_value_type_pointer pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000721
Howard Hinnant789847d2010-09-23 18:58:28 +0000722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000723 __hash_map_iterator() _NOEXCEPT {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000724
Howard Hinnant789847d2010-09-23 18:58:28 +0000725 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000726 __hash_map_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000727
Howard Hinnant789847d2010-09-23 18:58:28 +0000728 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000729 reference operator*() const {return __i_->__get_value();}
Howard Hinnant789847d2010-09-23 18:58:28 +0000730 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000731 pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000732
Howard Hinnant789847d2010-09-23 18:58:28 +0000733 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000734 __hash_map_iterator& operator++() {++__i_; return *this;}
Howard Hinnant789847d2010-09-23 18:58:28 +0000735 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000736 __hash_map_iterator operator++(int)
737 {
738 __hash_map_iterator __t(*this);
739 ++(*this);
740 return __t;
741 }
742
Howard Hinnant789847d2010-09-23 18:58:28 +0000743 friend _LIBCPP_INLINE_VISIBILITY
744 bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000745 {return __x.__i_ == __y.__i_;}
Howard Hinnant789847d2010-09-23 18:58:28 +0000746 friend _LIBCPP_INLINE_VISIBILITY
747 bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000748 {return __x.__i_ != __y.__i_;}
749
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000750 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
751 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
752 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
753 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
754 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000755};
756
757template <class _HashIterator>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000758class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000759{
760 _HashIterator __i_;
761
Eric Fiselier75d0dcf2016-02-10 20:46:23 +0000762 typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes;
763
Howard Hinnant3e519522010-05-11 19:42:16 +0000764public:
765 typedef forward_iterator_tag iterator_category;
Eric Fiselier75d0dcf2016-02-10 20:46:23 +0000766 typedef typename _NodeTypes::__map_value_type value_type;
767 typedef typename _NodeTypes::difference_type difference_type;
Howard Hinnant3e519522010-05-11 19:42:16 +0000768 typedef const value_type& reference;
Eric Fiselier75d0dcf2016-02-10 20:46:23 +0000769 typedef typename _NodeTypes::__const_map_value_type_pointer pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000770
Howard Hinnant789847d2010-09-23 18:58:28 +0000771 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000772 __hash_map_const_iterator() _NOEXCEPT {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000773
Howard Hinnant789847d2010-09-23 18:58:28 +0000774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000775 __hash_map_const_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {}
Howard Hinnant789847d2010-09-23 18:58:28 +0000776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000777 __hash_map_const_iterator(
778 __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
Howard Hinnant37141072011-06-04 18:54:24 +0000779 _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000780 : __i_(__i.__i_) {}
781
Howard Hinnant789847d2010-09-23 18:58:28 +0000782 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000783 reference operator*() const {return __i_->__get_value();}
Howard Hinnant789847d2010-09-23 18:58:28 +0000784 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtonf52318b2018-06-04 20:38:23 +0000785 pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000786
Howard Hinnant789847d2010-09-23 18:58:28 +0000787 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000788 __hash_map_const_iterator& operator++() {++__i_; return *this;}
Howard Hinnant789847d2010-09-23 18:58:28 +0000789 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000790 __hash_map_const_iterator operator++(int)
791 {
792 __hash_map_const_iterator __t(*this);
793 ++(*this);
794 return __t;
795 }
796
Howard Hinnant789847d2010-09-23 18:58:28 +0000797 friend _LIBCPP_INLINE_VISIBILITY
798 bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000799 {return __x.__i_ == __y.__i_;}
Howard Hinnant789847d2010-09-23 18:58:28 +0000800 friend _LIBCPP_INLINE_VISIBILITY
801 bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000802 {return __x.__i_ != __y.__i_;}
803
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000804 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
805 template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
806 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
807 template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000808};
809
810template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
811 class _Alloc = allocator<pair<const _Key, _Tp> > >
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000812class _LIBCPP_TEMPLATE_VIS unordered_map
Howard Hinnant3e519522010-05-11 19:42:16 +0000813{
814public:
815 // types
816 typedef _Key key_type;
817 typedef _Tp mapped_type;
818 typedef _Hash hasher;
819 typedef _Pred key_equal;
820 typedef _Alloc allocator_type;
821 typedef pair<const key_type, mapped_type> value_type;
822 typedef value_type& reference;
823 typedef const value_type& const_reference;
Howard Hinnantb24c8022013-07-23 22:01:58 +0000824 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
825 "Invalid allocator::value_type");
Howard Hinnant3e519522010-05-11 19:42:16 +0000826
827private:
Howard Hinnant9fd9f842013-09-30 19:08:22 +0000828 typedef __hash_value_type<key_type, mapped_type> __value_type;
Howard Hinnantabb160e2013-07-05 18:06:00 +0000829 typedef __unordered_map_hasher<key_type, __value_type, hasher> __hasher;
830 typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;
Marshall Clow1f508012015-04-07 05:21:38 +0000831 typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
832 __value_type>::type __allocator_type;
Howard Hinnant3e519522010-05-11 19:42:16 +0000833
834 typedef __hash_table<__value_type, __hasher,
835 __key_equal, __allocator_type> __table;
836
837 __table __table_;
838
Eric Fiselierfcd02212016-02-11 11:59:44 +0000839 typedef typename __table::_NodeTypes _NodeTypes;
Howard Hinnant3e519522010-05-11 19:42:16 +0000840 typedef typename __table::__node_pointer __node_pointer;
841 typedef typename __table::__node_const_pointer __node_const_pointer;
842 typedef typename __table::__node_traits __node_traits;
843 typedef typename __table::__node_allocator __node_allocator;
844 typedef typename __table::__node __node;
Howard Hinnantc003db12011-11-29 18:15:50 +0000845 typedef __hash_map_node_destructor<__node_allocator> _Dp;
846 typedef unique_ptr<__node, _Dp> __node_holder;
Howard Hinnant3e519522010-05-11 19:42:16 +0000847 typedef allocator_traits<allocator_type> __alloc_traits;
Eric Fiselierfcd02212016-02-11 11:59:44 +0000848
849 static_assert((is_same<typename __table::__container_value_type, value_type>::value), "");
850 static_assert((is_same<typename __table::__node_value_type, __value_type>::value), "");
Howard Hinnant3e519522010-05-11 19:42:16 +0000851public:
852 typedef typename __alloc_traits::pointer pointer;
853 typedef typename __alloc_traits::const_pointer const_pointer;
Eric Fiselier75d0dcf2016-02-10 20:46:23 +0000854 typedef typename __table::size_type size_type;
855 typedef typename __table::difference_type difference_type;
Howard Hinnant3e519522010-05-11 19:42:16 +0000856
857 typedef __hash_map_iterator<typename __table::iterator> iterator;
858 typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
859 typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
860 typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
861
Erik Pilkingtonb0386a52018-08-01 01:33:38 +0000862#if _LIBCPP_STD_VER > 14
863 typedef __map_node_handle<__node, allocator_type> node_type;
864 typedef __insert_return_type<iterator, node_type> insert_return_type;
865#endif
866
Howard Hinnant789847d2010-09-23 18:58:28 +0000867 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000868 unordered_map()
869 _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
Howard Hinnantb24c8022013-07-23 22:01:58 +0000870 {
871#if _LIBCPP_DEBUG_LEVEL >= 2
872 __get_db()->__insert_c(this);
873#endif
874 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000875 explicit unordered_map(size_type __n, const hasher& __hf = hasher(),
876 const key_equal& __eql = key_equal());
877 unordered_map(size_type __n, const hasher& __hf,
878 const key_equal& __eql,
879 const allocator_type& __a);
880 template <class _InputIterator>
881 unordered_map(_InputIterator __first, _InputIterator __last);
882 template <class _InputIterator>
883 unordered_map(_InputIterator __first, _InputIterator __last,
884 size_type __n, const hasher& __hf = hasher(),
885 const key_equal& __eql = key_equal());
886 template <class _InputIterator>
887 unordered_map(_InputIterator __first, _InputIterator __last,
888 size_type __n, const hasher& __hf,
889 const key_equal& __eql,
890 const allocator_type& __a);
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000891 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000892 explicit unordered_map(const allocator_type& __a);
893 unordered_map(const unordered_map& __u);
894 unordered_map(const unordered_map& __u, const allocator_type& __a);
Eric Fiselier6a470bc2017-04-18 22:50:56 +0000895#ifndef _LIBCPP_CXX03_LANG
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000896 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000897 unordered_map(unordered_map&& __u)
898 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000899 unordered_map(unordered_map&& __u, const allocator_type& __a);
Howard Hinnant3e519522010-05-11 19:42:16 +0000900 unordered_map(initializer_list<value_type> __il);
901 unordered_map(initializer_list<value_type> __il, size_type __n,
902 const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
903 unordered_map(initializer_list<value_type> __il, size_type __n,
904 const hasher& __hf, const key_equal& __eql,
905 const allocator_type& __a);
Eric Fiselier6a470bc2017-04-18 22:50:56 +0000906#endif // _LIBCPP_CXX03_LANG
Marshall Clow3cd37e62013-09-12 03:00:31 +0000907#if _LIBCPP_STD_VER > 11
908 _LIBCPP_INLINE_VISIBILITY
909 unordered_map(size_type __n, const allocator_type& __a)
910 : unordered_map(__n, hasher(), key_equal(), __a) {}
911 _LIBCPP_INLINE_VISIBILITY
912 unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a)
913 : unordered_map(__n, __hf, key_equal(), __a) {}
914 template <class _InputIterator>
915 _LIBCPP_INLINE_VISIBILITY
916 unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a)
917 : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) {}
918 template <class _InputIterator>
919 _LIBCPP_INLINE_VISIBILITY
920 unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf,
921 const allocator_type& __a)
922 : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {}
923 _LIBCPP_INLINE_VISIBILITY
924 unordered_map(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
925 : unordered_map(__il, __n, hasher(), key_equal(), __a) {}
926 _LIBCPP_INLINE_VISIBILITY
927 unordered_map(initializer_list<value_type> __il, size_type __n, const hasher& __hf,
928 const allocator_type& __a)
929 : unordered_map(__il, __n, __hf, key_equal(), __a) {}
930#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000931 // ~unordered_map() = default;
Howard Hinnant5a336872011-07-01 19:24:36 +0000932 _LIBCPP_INLINE_VISIBILITY
933 unordered_map& operator=(const unordered_map& __u)
934 {
Marshall Clow2ee83722016-07-18 13:19:00 +0000935#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant5a336872011-07-01 19:24:36 +0000936 __table_ = __u.__table_;
Howard Hinnant307f8142013-06-22 15:21:29 +0000937#else
Marshall Clow74cf6ff2014-02-08 04:03:14 +0000938 if (this != &__u) {
939 __table_.clear();
940 __table_.hash_function() = __u.__table_.hash_function();
941 __table_.key_eq() = __u.__table_.key_eq();
942 __table_.max_load_factor() = __u.__table_.max_load_factor();
943 __table_.__copy_assign_alloc(__u.__table_);
944 insert(__u.begin(), __u.end());
945 }
Howard Hinnant307f8142013-06-22 15:21:29 +0000946#endif
Howard Hinnant5a336872011-07-01 19:24:36 +0000947 return *this;
948 }
Eric Fiselier6a470bc2017-04-18 22:50:56 +0000949#ifndef _LIBCPP_CXX03_LANG
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000950 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000951 unordered_map& operator=(unordered_map&& __u)
952 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000953 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000954 unordered_map& operator=(initializer_list<value_type> __il);
Eric Fiselier6a470bc2017-04-18 22:50:56 +0000955#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000956
Howard Hinnant789847d2010-09-23 18:58:28 +0000957 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000958 allocator_type get_allocator() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000959 {return allocator_type(__table_.__node_alloc());}
960
Marshall Clow72c8fad2017-11-15 05:51:26 +0000961 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000962 bool empty() const _NOEXCEPT {return __table_.size() == 0;}
Howard Hinnant789847d2010-09-23 18:58:28 +0000963 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000964 size_type size() const _NOEXCEPT {return __table_.size();}
Howard Hinnant789847d2010-09-23 18:58:28 +0000965 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000966 size_type max_size() const _NOEXCEPT {return __table_.max_size();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000967
Howard Hinnant789847d2010-09-23 18:58:28 +0000968 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000969 iterator begin() _NOEXCEPT {return __table_.begin();}
Howard Hinnant789847d2010-09-23 18:58:28 +0000970 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000971 iterator end() _NOEXCEPT {return __table_.end();}
Howard Hinnant789847d2010-09-23 18:58:28 +0000972 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000973 const_iterator begin() const _NOEXCEPT {return __table_.begin();}
Howard Hinnant789847d2010-09-23 18:58:28 +0000974 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000975 const_iterator end() const _NOEXCEPT {return __table_.end();}
Howard Hinnant789847d2010-09-23 18:58:28 +0000976 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000977 const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}
Howard Hinnant789847d2010-09-23 18:58:28 +0000978 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +0000979 const_iterator cend() const _NOEXCEPT {return __table_.end();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000980
Eric Fiselier7a9f5002016-04-18 01:40:45 +0000981 _LIBCPP_INLINE_VISIBILITY
982 pair<iterator, bool> insert(const value_type& __x)
983 {return __table_.__insert_unique(__x);}
984
985 iterator insert(const_iterator __p, const value_type& __x) {
986#if _LIBCPP_DEBUG_LEVEL >= 2
987 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
988 "unordered_map::insert(const_iterator, const value_type&) called with an iterator not"
989 " referring to this unordered_map");
Eric Fiselierfd838222016-12-23 23:37:52 +0000990#else
991 ((void)__p);
Eric Fiselier7a9f5002016-04-18 01:40:45 +0000992#endif
993 return insert(__x).first;
994 }
995
996 template <class _InputIterator>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000997 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7a9f5002016-04-18 01:40:45 +0000998 void insert(_InputIterator __first, _InputIterator __last);
999
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001000#ifndef _LIBCPP_CXX03_LANG
Eric Fiselier7a9f5002016-04-18 01:40:45 +00001001 _LIBCPP_INLINE_VISIBILITY
1002 void insert(initializer_list<value_type> __il)
1003 {insert(__il.begin(), __il.end());}
Eric Fiselier7a9f5002016-04-18 01:40:45 +00001004
Eric Fiselier7a9f5002016-04-18 01:40:45 +00001005 _LIBCPP_INLINE_VISIBILITY
1006 pair<iterator, bool> insert(value_type&& __x)
1007 {return __table_.__insert_unique(_VSTD::move(__x));}
1008
1009 iterator insert(const_iterator __p, value_type&& __x) {
1010#if _LIBCPP_DEBUG_LEVEL >= 2
1011 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
1012 "unordered_map::insert(const_iterator, const value_type&) called with an iterator not"
1013 " referring to this unordered_map");
Eric Fiselierfd838222016-12-23 23:37:52 +00001014#else
1015 ((void)__p);
Eric Fiselier7a9f5002016-04-18 01:40:45 +00001016#endif
1017 return __table_.__insert_unique(_VSTD::move(__x)).first;
1018 }
1019
1020 template <class _Pp,
1021 class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
1022 _LIBCPP_INLINE_VISIBILITY
1023 pair<iterator, bool> insert(_Pp&& __x)
1024 {return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));}
1025
1026 template <class _Pp,
1027 class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
1028 _LIBCPP_INLINE_VISIBILITY
1029 iterator insert(const_iterator __p, _Pp&& __x)
1030 {
1031#if _LIBCPP_DEBUG_LEVEL >= 2
1032 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
1033 "unordered_map::insert(const_iterator, value_type&&) called with an iterator not"
1034 " referring to this unordered_map");
Eric Fiselierfd838222016-12-23 23:37:52 +00001035#else
1036 ((void)__p);
Eric Fiselier7a9f5002016-04-18 01:40:45 +00001037#endif
1038 return insert(_VSTD::forward<_Pp>(__x)).first;
1039 }
1040
Eric Fiselierfcd02212016-02-11 11:59:44 +00001041 template <class... _Args>
1042 _LIBCPP_INLINE_VISIBILITY
1043 pair<iterator, bool> emplace(_Args&&... __args) {
1044 return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);
1045 }
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001046
Howard Hinnant8b805c92012-05-25 22:04:21 +00001047 template <class... _Args>
Eric Fiselierfcd02212016-02-11 11:59:44 +00001048 _LIBCPP_INLINE_VISIBILITY
1049 iterator emplace_hint(const_iterator __p, _Args&&... __args) {
Howard Hinnant4c80bfb2013-07-30 21:04:42 +00001050#if _LIBCPP_DEBUG_LEVEL >= 2
Eric Fiselierfcd02212016-02-11 11:59:44 +00001051 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
1052 "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not"
1053 " referring to this unordered_map");
Eric Fiselierfd838222016-12-23 23:37:52 +00001054#else
1055 ((void)__p);
Howard Hinnant4c80bfb2013-07-30 21:04:42 +00001056#endif
Eric Fiselierfcd02212016-02-11 11:59:44 +00001057 return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
1058 }
1059
Eric Fiselier7a9f5002016-04-18 01:40:45 +00001060#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001061
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001062#if _LIBCPP_STD_VER > 14
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001063 template <class... _Args>
1064 _LIBCPP_INLINE_VISIBILITY
1065 pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args)
1066 {
Eric Fiselier87c41042016-04-18 06:51:33 +00001067 return __table_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct,
1068 _VSTD::forward_as_tuple(__k),
1069 _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001070 }
1071
1072 template <class... _Args>
1073 _LIBCPP_INLINE_VISIBILITY
1074 pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args)
1075 {
Eric Fiselier87c41042016-04-18 06:51:33 +00001076 return __table_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct,
1077 _VSTD::forward_as_tuple(_VSTD::move(__k)),
1078 _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001079 }
1080
1081 template <class... _Args>
1082 _LIBCPP_INLINE_VISIBILITY
1083 iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args)
1084 {
Eric Fiselier87c41042016-04-18 06:51:33 +00001085#if _LIBCPP_DEBUG_LEVEL >= 2
Oleg Ranevskyyeef9b352016-09-26 21:39:38 +00001086 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__h) == this,
Eric Fiselier87c41042016-04-18 06:51:33 +00001087 "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not"
1088 " referring to this unordered_map");
Eric Fiselierfd838222016-12-23 23:37:52 +00001089#else
1090 ((void)__h);
Eric Fiselier87c41042016-04-18 06:51:33 +00001091#endif
Eric Fiselierfd838222016-12-23 23:37:52 +00001092 return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first;
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001093 }
1094
1095 template <class... _Args>
1096 _LIBCPP_INLINE_VISIBILITY
1097 iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args)
1098 {
Eric Fiselier87c41042016-04-18 06:51:33 +00001099#if _LIBCPP_DEBUG_LEVEL >= 2
Oleg Ranevskyyeef9b352016-09-26 21:39:38 +00001100 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__h) == this,
Eric Fiselier87c41042016-04-18 06:51:33 +00001101 "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not"
1102 " referring to this unordered_map");
Eric Fiselierfd838222016-12-23 23:37:52 +00001103#else
1104 ((void)__h);
Eric Fiselier87c41042016-04-18 06:51:33 +00001105#endif
1106 return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first;
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001107 }
1108
1109 template <class _Vp>
1110 _LIBCPP_INLINE_VISIBILITY
1111 pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v)
1112 {
Eric Fiselier87c41042016-04-18 06:51:33 +00001113 pair<iterator, bool> __res = __table_.__emplace_unique_key_args(__k,
1114 __k, _VSTD::forward<_Vp>(__v));
1115 if (!__res.second) {
1116 __res.first->second = _VSTD::forward<_Vp>(__v);
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001117 }
Eric Fiselier87c41042016-04-18 06:51:33 +00001118 return __res;
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001119 }
Eric Fiselier87c41042016-04-18 06:51:33 +00001120
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001121 template <class _Vp>
1122 _LIBCPP_INLINE_VISIBILITY
1123 pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v)
1124 {
Eric Fiselier87c41042016-04-18 06:51:33 +00001125 pair<iterator, bool> __res = __table_.__emplace_unique_key_args(__k,
1126 _VSTD::move(__k), _VSTD::forward<_Vp>(__v));
1127 if (!__res.second) {
1128 __res.first->second = _VSTD::forward<_Vp>(__v);
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001129 }
Eric Fiselier87c41042016-04-18 06:51:33 +00001130 return __res;
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001131 }
1132
1133 template <class _Vp>
1134 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierfd838222016-12-23 23:37:52 +00001135 iterator insert_or_assign(const_iterator, const key_type& __k, _Vp&& __v)
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001136 {
Eric Fiselierfd838222016-12-23 23:37:52 +00001137 // FIXME: Add debug mode checking for the iterator input
Eric Fiselier87c41042016-04-18 06:51:33 +00001138 return insert_or_assign(__k, _VSTD::forward<_Vp>(__v)).first;
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001139 }
1140
1141 template <class _Vp>
1142 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierfd838222016-12-23 23:37:52 +00001143 iterator insert_or_assign(const_iterator, key_type&& __k, _Vp&& __v)
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001144 {
Eric Fiselierfd838222016-12-23 23:37:52 +00001145 // FIXME: Add debug mode checking for the iterator input
Eric Fiselier87c41042016-04-18 06:51:33 +00001146 return insert_or_assign(_VSTD::move(__k), _VSTD::forward<_Vp>(__v)).first;
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001147 }
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001148#endif // _LIBCPP_STD_VER > 14
Marshall Clowbc4c89a2015-07-07 05:45:35 +00001149
Howard Hinnant789847d2010-09-23 18:58:28 +00001150 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001151 iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001152 _LIBCPP_INLINE_VISIBILITY
Marshall Clowec392962015-05-10 13:35:00 +00001153 iterator erase(iterator __p) {return __table_.erase(__p.__i_);}
1154 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001155 size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001156 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001157 iterator erase(const_iterator __first, const_iterator __last)
1158 {return __table_.erase(__first.__i_, __last.__i_);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001159 _LIBCPP_INLINE_VISIBILITY
Erik Pilkingtonb0386a52018-08-01 01:33:38 +00001160 void clear() _NOEXCEPT {__table_.clear();}
1161
1162#if _LIBCPP_STD_VER > 14
1163 _LIBCPP_INLINE_VISIBILITY
1164 insert_return_type insert(node_type&& __nh)
1165 {
1166 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1167 "node_type with incompatible allocator passed to unordered_map::insert()");
1168 return __table_.template __node_handle_insert_unique<
1169 node_type, insert_return_type>(_VSTD::move(__nh));
1170 }
1171 _LIBCPP_INLINE_VISIBILITY
1172 iterator insert(const_iterator __hint, node_type&& __nh)
1173 {
1174 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1175 "node_type with incompatible allocator passed to unordered_map::insert()");
1176 return __table_.template __node_handle_insert_unique<node_type>(
1177 __hint.__i_, _VSTD::move(__nh));
1178 }
1179 _LIBCPP_INLINE_VISIBILITY
1180 node_type extract(key_type const& __key)
1181 {
1182 return __table_.template __node_handle_extract<node_type>(__key);
1183 }
1184 _LIBCPP_INLINE_VISIBILITY
1185 node_type extract(const_iterator __it)
1186 {
1187 return __table_.template __node_handle_extract<node_type>(
1188 __it.__i_);
1189 }
1190#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001191
Howard Hinnant789847d2010-09-23 18:58:28 +00001192 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001193 void swap(unordered_map& __u)
1194 _NOEXCEPT_(__is_nothrow_swappable<__table>::value)
Eric Fiselier780b51d2016-12-28 05:53:01 +00001195 { __table_.swap(__u.__table_);}
Howard Hinnant3e519522010-05-11 19:42:16 +00001196
Howard Hinnant789847d2010-09-23 18:58:28 +00001197 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001198 hasher hash_function() const
1199 {return __table_.hash_function().hash_function();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001200 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001201 key_equal key_eq() const
1202 {return __table_.key_eq().key_eq();}
1203
Howard Hinnant789847d2010-09-23 18:58:28 +00001204 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001205 iterator find(const key_type& __k) {return __table_.find(__k);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001206 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001207 const_iterator find(const key_type& __k) const {return __table_.find(__k);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001208 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001209 size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001210 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001211 pair<iterator, iterator> equal_range(const key_type& __k)
1212 {return __table_.__equal_range_unique(__k);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001213 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001214 pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
1215 {return __table_.__equal_range_unique(__k);}
1216
1217 mapped_type& operator[](const key_type& __k);
Eric Fiselier0f905672016-02-11 21:45:53 +00001218#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001219 mapped_type& operator[](key_type&& __k);
1220#endif
1221
1222 mapped_type& at(const key_type& __k);
1223 const mapped_type& at(const key_type& __k) const;
1224
Howard Hinnant789847d2010-09-23 18:58:28 +00001225 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001226 size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001227 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001228 size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();}
Howard Hinnant3e519522010-05-11 19:42:16 +00001229
Howard Hinnant789847d2010-09-23 18:58:28 +00001230 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001231 size_type bucket_size(size_type __n) const
1232 {return __table_.bucket_size(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001233 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001234 size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
1235
Howard Hinnant789847d2010-09-23 18:58:28 +00001236 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001237 local_iterator begin(size_type __n) {return __table_.begin(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001238 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001239 local_iterator end(size_type __n) {return __table_.end(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001240 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001241 const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001243 const_local_iterator end(size_type __n) const {return __table_.cend(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001244 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001245 const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001246 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001247 const_local_iterator cend(size_type __n) const {return __table_.cend(__n);}
1248
Howard Hinnant789847d2010-09-23 18:58:28 +00001249 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001250 float load_factor() const _NOEXCEPT {return __table_.load_factor();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001252 float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001253 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001254 void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001255 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001256 void rehash(size_type __n) {__table_.rehash(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001257 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001258 void reserve(size_type __n) {__table_.reserve(__n);}
1259
Howard Hinnantb24c8022013-07-23 22:01:58 +00001260#if _LIBCPP_DEBUG_LEVEL >= 2
1261
1262 bool __dereferenceable(const const_iterator* __i) const
1263 {return __table_.__dereferenceable(&__i->__i_);}
1264 bool __decrementable(const const_iterator* __i) const
1265 {return __table_.__decrementable(&__i->__i_);}
1266 bool __addable(const const_iterator* __i, ptrdiff_t __n) const
1267 {return __table_.__addable(&__i->__i_, __n);}
1268 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
1269 {return __table_.__addable(&__i->__i_, __n);}
1270
1271#endif // _LIBCPP_DEBUG_LEVEL >= 2
1272
Howard Hinnant3e519522010-05-11 19:42:16 +00001273private:
Eric Fiselier0f905672016-02-11 21:45:53 +00001274
1275#ifdef _LIBCPP_CXX03_LANG
Howard Hinnant4a95f9e2013-07-04 20:59:16 +00001276 __node_holder __construct_node_with_key(const key_type& __k);
Eric Fiselier0f905672016-02-11 21:45:53 +00001277#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001278};
1279
1280template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1281unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1282 size_type __n, const hasher& __hf, const key_equal& __eql)
1283 : __table_(__hf, __eql)
1284{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001285#if _LIBCPP_DEBUG_LEVEL >= 2
1286 __get_db()->__insert_c(this);
1287#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001288 __table_.rehash(__n);
1289}
1290
1291template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1292unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1293 size_type __n, const hasher& __hf, const key_equal& __eql,
1294 const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00001295 : __table_(__hf, __eql, typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00001296{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001297#if _LIBCPP_DEBUG_LEVEL >= 2
1298 __get_db()->__insert_c(this);
1299#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001300 __table_.rehash(__n);
1301}
1302
1303template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001304inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001305unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1306 const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00001307 : __table_(typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00001308{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001309#if _LIBCPP_DEBUG_LEVEL >= 2
1310 __get_db()->__insert_c(this);
1311#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001312}
1313
1314template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1315template <class _InputIterator>
1316unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1317 _InputIterator __first, _InputIterator __last)
1318{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001319#if _LIBCPP_DEBUG_LEVEL >= 2
1320 __get_db()->__insert_c(this);
1321#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001322 insert(__first, __last);
1323}
1324
1325template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1326template <class _InputIterator>
1327unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1328 _InputIterator __first, _InputIterator __last, size_type __n,
1329 const hasher& __hf, const key_equal& __eql)
1330 : __table_(__hf, __eql)
1331{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001332#if _LIBCPP_DEBUG_LEVEL >= 2
1333 __get_db()->__insert_c(this);
1334#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001335 __table_.rehash(__n);
1336 insert(__first, __last);
1337}
1338
1339template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1340template <class _InputIterator>
1341unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1342 _InputIterator __first, _InputIterator __last, size_type __n,
1343 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00001344 : __table_(__hf, __eql, typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00001345{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001346#if _LIBCPP_DEBUG_LEVEL >= 2
1347 __get_db()->__insert_c(this);
1348#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001349 __table_.rehash(__n);
1350 insert(__first, __last);
1351}
1352
1353template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1354unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1355 const unordered_map& __u)
1356 : __table_(__u.__table_)
1357{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001358#if _LIBCPP_DEBUG_LEVEL >= 2
1359 __get_db()->__insert_c(this);
1360#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001361 __table_.rehash(__u.bucket_count());
1362 insert(__u.begin(), __u.end());
1363}
1364
1365template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1366unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1367 const unordered_map& __u, const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00001368 : __table_(__u.__table_, typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00001369{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001370#if _LIBCPP_DEBUG_LEVEL >= 2
1371 __get_db()->__insert_c(this);
1372#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001373 __table_.rehash(__u.bucket_count());
1374 insert(__u.begin(), __u.end());
1375}
1376
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001377#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001378
1379template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001380inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001381unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1382 unordered_map&& __u)
Howard Hinnant37141072011-06-04 18:54:24 +00001383 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +00001384 : __table_(_VSTD::move(__u.__table_))
Howard Hinnant3e519522010-05-11 19:42:16 +00001385{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001386#if _LIBCPP_DEBUG_LEVEL >= 2
1387 __get_db()->__insert_c(this);
Howard Hinnant4c80bfb2013-07-30 21:04:42 +00001388 __get_db()->swap(this, &__u);
Howard Hinnantb24c8022013-07-23 22:01:58 +00001389#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001390}
1391
1392template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1393unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1394 unordered_map&& __u, const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00001395 : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00001396{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001397#if _LIBCPP_DEBUG_LEVEL >= 2
1398 __get_db()->__insert_c(this);
1399#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001400 if (__a != __u.get_allocator())
1401 {
1402 iterator __i = __u.begin();
Eric Fiselierfcd02212016-02-11 11:59:44 +00001403 while (__u.size() != 0) {
Erik Pilkingtonf52318b2018-06-04 20:38:23 +00001404 __table_.__emplace_unique(
1405 __u.__table_.remove((__i++).__i_)->__value_.__move());
Eric Fiselierfcd02212016-02-11 11:59:44 +00001406 }
Howard Hinnant3e519522010-05-11 19:42:16 +00001407 }
Howard Hinnant4c80bfb2013-07-30 21:04:42 +00001408#if _LIBCPP_DEBUG_LEVEL >= 2
1409 else
1410 __get_db()->swap(this, &__u);
1411#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001412}
1413
Howard Hinnant3e519522010-05-11 19:42:16 +00001414template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1415unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1416 initializer_list<value_type> __il)
1417{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001418#if _LIBCPP_DEBUG_LEVEL >= 2
1419 __get_db()->__insert_c(this);
1420#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001421 insert(__il.begin(), __il.end());
1422}
1423
1424template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1425unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1426 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1427 const key_equal& __eql)
1428 : __table_(__hf, __eql)
1429{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001430#if _LIBCPP_DEBUG_LEVEL >= 2
1431 __get_db()->__insert_c(this);
1432#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001433 __table_.rehash(__n);
1434 insert(__il.begin(), __il.end());
1435}
1436
1437template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1438unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
1439 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1440 const key_equal& __eql, const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00001441 : __table_(__hf, __eql, typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00001442{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001443#if _LIBCPP_DEBUG_LEVEL >= 2
1444 __get_db()->__insert_c(this);
1445#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001446 __table_.rehash(__n);
1447 insert(__il.begin(), __il.end());
1448}
1449
Howard Hinnant3e519522010-05-11 19:42:16 +00001450template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001451inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001452unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&
1453unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u)
Howard Hinnant37141072011-06-04 18:54:24 +00001454 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +00001455{
Howard Hinnantce48a112011-06-30 21:18:19 +00001456 __table_ = _VSTD::move(__u.__table_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001457 return *this;
1458}
1459
Howard Hinnant3e519522010-05-11 19:42:16 +00001460template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001461inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001462unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&
1463unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(
1464 initializer_list<value_type> __il)
1465{
1466 __table_.__assign_unique(__il.begin(), __il.end());
1467 return *this;
1468}
1469
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001470#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001471
Howard Hinnant3e519522010-05-11 19:42:16 +00001472template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1473template <class _InputIterator>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001474inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001475void
1476unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
1477 _InputIterator __last)
1478{
1479 for (; __first != __last; ++__first)
1480 __table_.__insert_unique(*__first);
1481}
1482
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001483#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001484
Eric Fiselier0f905672016-02-11 21:45:53 +00001485template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1486_Tp&
1487unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
1488{
1489 return __table_.__emplace_unique_key_args(__k,
1490 std::piecewise_construct, std::forward_as_tuple(__k),
Erik Pilkingtonf52318b2018-06-04 20:38:23 +00001491 std::forward_as_tuple()).first->__get_value().second;
Eric Fiselier0f905672016-02-11 21:45:53 +00001492}
Howard Hinnant3e519522010-05-11 19:42:16 +00001493
1494template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1495_Tp&
1496unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k)
1497{
Eric Fiselier0f905672016-02-11 21:45:53 +00001498 return __table_.__emplace_unique_key_args(__k,
1499 std::piecewise_construct, std::forward_as_tuple(std::move(__k)),
Erik Pilkingtonf52318b2018-06-04 20:38:23 +00001500 std::forward_as_tuple()).first->__get_value().second;
Howard Hinnant3e519522010-05-11 19:42:16 +00001501}
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001502#else // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001503
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001504template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1505typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
1506unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const key_type& __k)
1507{
1508 __node_allocator& __na = __table_.__node_alloc();
1509 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
Erik Pilkingtonf52318b2018-06-04 20:38:23 +00001510 __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().first), __k);
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001511 __h.get_deleter().__first_constructed = true;
Erik Pilkingtonf52318b2018-06-04 20:38:23 +00001512 __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().second));
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001513 __h.get_deleter().__second_constructed = true;
1514 return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03
1515}
1516
1517template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1518_Tp&
1519unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
1520{
1521 iterator __i = find(__k);
1522 if (__i != end())
1523 return __i->second;
1524 __node_holder __h = __construct_node_with_key(__k);
1525 pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
1526 __h.release();
1527 return __r.first->second;
1528}
1529
1530#endif // _LIBCPP_CXX03_MODE
Howard Hinnant3e519522010-05-11 19:42:16 +00001531
1532template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1533_Tp&
1534unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k)
1535{
1536 iterator __i = find(__k);
1537#ifndef _LIBCPP_NO_EXCEPTIONS
1538 if (__i == end())
1539 throw out_of_range("unordered_map::at: key not found");
Howard Hinnantb3371f62010-08-22 00:02:43 +00001540#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001541 return __i->second;
1542}
1543
1544template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1545const _Tp&
1546unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k) const
1547{
1548 const_iterator __i = find(__k);
1549#ifndef _LIBCPP_NO_EXCEPTIONS
1550 if (__i == end())
1551 throw out_of_range("unordered_map::at: key not found");
Howard Hinnantb3371f62010-08-22 00:02:43 +00001552#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001553 return __i->second;
1554}
1555
1556template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Howard Hinnant789847d2010-09-23 18:58:28 +00001557inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001558void
1559swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
1560 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
Howard Hinnant37141072011-06-04 18:54:24 +00001561 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnant3e519522010-05-11 19:42:16 +00001562{
1563 __x.swap(__y);
1564}
1565
1566template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1567bool
1568operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
1569 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
1570{
1571 if (__x.size() != __y.size())
1572 return false;
1573 typedef typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
1574 const_iterator;
1575 for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
1576 __i != __ex; ++__i)
1577 {
1578 const_iterator __j = __y.find(__i->first);
1579 if (__j == __ey || !(*__i == *__j))
1580 return false;
1581 }
1582 return true;
1583}
1584
1585template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Howard Hinnant789847d2010-09-23 18:58:28 +00001586inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001587bool
1588operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
1589 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
1590{
1591 return !(__x == __y);
1592}
1593
1594template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
1595 class _Alloc = allocator<pair<const _Key, _Tp> > >
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +00001596class _LIBCPP_TEMPLATE_VIS unordered_multimap
Howard Hinnant3e519522010-05-11 19:42:16 +00001597{
1598public:
1599 // types
1600 typedef _Key key_type;
1601 typedef _Tp mapped_type;
1602 typedef _Hash hasher;
1603 typedef _Pred key_equal;
1604 typedef _Alloc allocator_type;
1605 typedef pair<const key_type, mapped_type> value_type;
1606 typedef value_type& reference;
1607 typedef const value_type& const_reference;
Howard Hinnantb24c8022013-07-23 22:01:58 +00001608 static_assert((is_same<value_type, typename allocator_type::value_type>::value),
1609 "Invalid allocator::value_type");
Howard Hinnant3e519522010-05-11 19:42:16 +00001610
1611private:
Howard Hinnant9fd9f842013-09-30 19:08:22 +00001612 typedef __hash_value_type<key_type, mapped_type> __value_type;
Howard Hinnantabb160e2013-07-05 18:06:00 +00001613 typedef __unordered_map_hasher<key_type, __value_type, hasher> __hasher;
1614 typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;
Marshall Clow1f508012015-04-07 05:21:38 +00001615 typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
1616 __value_type>::type __allocator_type;
Howard Hinnant3e519522010-05-11 19:42:16 +00001617
1618 typedef __hash_table<__value_type, __hasher,
1619 __key_equal, __allocator_type> __table;
1620
1621 __table __table_;
1622
Eric Fiselierfcd02212016-02-11 11:59:44 +00001623 typedef typename __table::_NodeTypes _NodeTypes;
Howard Hinnant3e519522010-05-11 19:42:16 +00001624 typedef typename __table::__node_traits __node_traits;
1625 typedef typename __table::__node_allocator __node_allocator;
1626 typedef typename __table::__node __node;
Howard Hinnantc003db12011-11-29 18:15:50 +00001627 typedef __hash_map_node_destructor<__node_allocator> _Dp;
1628 typedef unique_ptr<__node, _Dp> __node_holder;
Howard Hinnant3e519522010-05-11 19:42:16 +00001629 typedef allocator_traits<allocator_type> __alloc_traits;
Eric Fiselier75d0dcf2016-02-10 20:46:23 +00001630 static_assert((is_same<typename __node_traits::size_type,
1631 typename __alloc_traits::size_type>::value),
1632 "Allocator uses different size_type for different types");
Howard Hinnant3e519522010-05-11 19:42:16 +00001633public:
1634 typedef typename __alloc_traits::pointer pointer;
1635 typedef typename __alloc_traits::const_pointer const_pointer;
Eric Fiselier75d0dcf2016-02-10 20:46:23 +00001636 typedef typename __table::size_type size_type;
1637 typedef typename __table::difference_type difference_type;
Howard Hinnant3e519522010-05-11 19:42:16 +00001638
1639 typedef __hash_map_iterator<typename __table::iterator> iterator;
1640 typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
1641 typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
1642 typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
1643
Erik Pilkingtonb0386a52018-08-01 01:33:38 +00001644#if _LIBCPP_STD_VER > 14
1645 typedef __map_node_handle<__node, allocator_type> node_type;
1646#endif
1647
Howard Hinnant789847d2010-09-23 18:58:28 +00001648 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001649 unordered_multimap()
1650 _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
Howard Hinnantb24c8022013-07-23 22:01:58 +00001651 {
1652#if _LIBCPP_DEBUG_LEVEL >= 2
1653 __get_db()->__insert_c(this);
1654#endif
1655 }
Howard Hinnant3e519522010-05-11 19:42:16 +00001656 explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(),
1657 const key_equal& __eql = key_equal());
1658 unordered_multimap(size_type __n, const hasher& __hf,
1659 const key_equal& __eql,
1660 const allocator_type& __a);
1661 template <class _InputIterator>
1662 unordered_multimap(_InputIterator __first, _InputIterator __last);
1663 template <class _InputIterator>
1664 unordered_multimap(_InputIterator __first, _InputIterator __last,
1665 size_type __n, const hasher& __hf = hasher(),
1666 const key_equal& __eql = key_equal());
1667 template <class _InputIterator>
1668 unordered_multimap(_InputIterator __first, _InputIterator __last,
1669 size_type __n, const hasher& __hf,
1670 const key_equal& __eql,
1671 const allocator_type& __a);
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001672 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001673 explicit unordered_multimap(const allocator_type& __a);
1674 unordered_multimap(const unordered_multimap& __u);
1675 unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001676#ifndef _LIBCPP_CXX03_LANG
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001677 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001678 unordered_multimap(unordered_multimap&& __u)
1679 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +00001680 unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);
Howard Hinnant3e519522010-05-11 19:42:16 +00001681 unordered_multimap(initializer_list<value_type> __il);
1682 unordered_multimap(initializer_list<value_type> __il, size_type __n,
1683 const hasher& __hf = hasher(),
1684 const key_equal& __eql = key_equal());
1685 unordered_multimap(initializer_list<value_type> __il, size_type __n,
1686 const hasher& __hf, const key_equal& __eql,
1687 const allocator_type& __a);
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001688#endif // _LIBCPP_CXX03_LANG
Marshall Clow3cd37e62013-09-12 03:00:31 +00001689#if _LIBCPP_STD_VER > 11
1690 _LIBCPP_INLINE_VISIBILITY
1691 unordered_multimap(size_type __n, const allocator_type& __a)
1692 : unordered_multimap(__n, hasher(), key_equal(), __a) {}
1693 _LIBCPP_INLINE_VISIBILITY
1694 unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a)
1695 : unordered_multimap(__n, __hf, key_equal(), __a) {}
1696 template <class _InputIterator>
1697 _LIBCPP_INLINE_VISIBILITY
1698 unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a)
1699 : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) {}
1700 template <class _InputIterator>
1701 _LIBCPP_INLINE_VISIBILITY
1702 unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf,
1703 const allocator_type& __a)
1704 : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {}
1705 _LIBCPP_INLINE_VISIBILITY
1706 unordered_multimap(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
1707 : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {}
1708 _LIBCPP_INLINE_VISIBILITY
1709 unordered_multimap(initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1710 const allocator_type& __a)
1711 : unordered_multimap(__il, __n, __hf, key_equal(), __a) {}
1712#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001713 // ~unordered_multimap() = default;
Howard Hinnant5a336872011-07-01 19:24:36 +00001714 _LIBCPP_INLINE_VISIBILITY
1715 unordered_multimap& operator=(const unordered_multimap& __u)
1716 {
Marshall Clow2ee83722016-07-18 13:19:00 +00001717#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant5a336872011-07-01 19:24:36 +00001718 __table_ = __u.__table_;
Howard Hinnant307f8142013-06-22 15:21:29 +00001719#else
Marshall Clow74cf6ff2014-02-08 04:03:14 +00001720 if (this != &__u) {
1721 __table_.clear();
1722 __table_.hash_function() = __u.__table_.hash_function();
1723 __table_.key_eq() = __u.__table_.key_eq();
1724 __table_.max_load_factor() = __u.__table_.max_load_factor();
1725 __table_.__copy_assign_alloc(__u.__table_);
1726 insert(__u.begin(), __u.end());
1727 }
Howard Hinnant307f8142013-06-22 15:21:29 +00001728#endif
Howard Hinnant5a336872011-07-01 19:24:36 +00001729 return *this;
1730 }
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001731#ifndef _LIBCPP_CXX03_LANG
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001732 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001733 unordered_multimap& operator=(unordered_multimap&& __u)
1734 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001735 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001736 unordered_multimap& operator=(initializer_list<value_type> __il);
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001737#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001738
Howard Hinnant789847d2010-09-23 18:58:28 +00001739 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001740 allocator_type get_allocator() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +00001741 {return allocator_type(__table_.__node_alloc());}
1742
Marshall Clow72c8fad2017-11-15 05:51:26 +00001743 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001744 bool empty() const _NOEXCEPT {return __table_.size() == 0;}
Howard Hinnant789847d2010-09-23 18:58:28 +00001745 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001746 size_type size() const _NOEXCEPT {return __table_.size();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001747 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001748 size_type max_size() const _NOEXCEPT {return __table_.max_size();}
Howard Hinnant3e519522010-05-11 19:42:16 +00001749
Howard Hinnant789847d2010-09-23 18:58:28 +00001750 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001751 iterator begin() _NOEXCEPT {return __table_.begin();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001752 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001753 iterator end() _NOEXCEPT {return __table_.end();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001754 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001755 const_iterator begin() const _NOEXCEPT {return __table_.begin();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001756 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001757 const_iterator end() const _NOEXCEPT {return __table_.end();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001758 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001759 const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001760 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001761 const_iterator cend() const _NOEXCEPT {return __table_.end();}
Howard Hinnant3e519522010-05-11 19:42:16 +00001762
Eric Fiselier7a9f5002016-04-18 01:40:45 +00001763 _LIBCPP_INLINE_VISIBILITY
1764 iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
1765
1766 _LIBCPP_INLINE_VISIBILITY
1767 iterator insert(const_iterator __p, const value_type& __x)
1768 {return __table_.__insert_multi(__p.__i_, __x);}
1769
1770 template <class _InputIterator>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001771 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier7a9f5002016-04-18 01:40:45 +00001772 void insert(_InputIterator __first, _InputIterator __last);
1773
Eric Fiselier6a470bc2017-04-18 22:50:56 +00001774#ifndef _LIBCPP_CXX03_LANG
Eric Fiselier7a9f5002016-04-18 01:40:45 +00001775 _LIBCPP_INLINE_VISIBILITY
1776 void insert(initializer_list<value_type> __il)
1777 {insert(__il.begin(), __il.end());}
Eric Fiselier7a9f5002016-04-18 01:40:45 +00001778 _LIBCPP_INLINE_VISIBILITY
1779 iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));}
1780
1781 _LIBCPP_INLINE_VISIBILITY
1782 iterator insert(const_iterator __p, value_type&& __x)
1783 {return __table_.__insert_multi(__p.__i_, _VSTD::move(__x));}
1784
1785 template <class _Pp,
1786 class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
1787 _LIBCPP_INLINE_VISIBILITY
1788 iterator insert(_Pp&& __x)
1789 {return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));}
1790
1791 template <class _Pp,
1792 class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
1793 _LIBCPP_INLINE_VISIBILITY
1794 iterator insert(const_iterator __p, _Pp&& __x)
1795 {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));}
1796
Eric Fiselierfcd02212016-02-11 11:59:44 +00001797 template <class... _Args>
1798 iterator emplace(_Args&&... __args) {
1799 return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...);
1800 }
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001801
Howard Hinnant8b805c92012-05-25 22:04:21 +00001802 template <class... _Args>
Eric Fiselierfcd02212016-02-11 11:59:44 +00001803 iterator emplace_hint(const_iterator __p, _Args&&... __args) {
1804 return __table_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...);
1805 }
1806#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001807
Howard Hinnant3e519522010-05-11 19:42:16 +00001808
Howard Hinnant789847d2010-09-23 18:58:28 +00001809 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001810 iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001811 _LIBCPP_INLINE_VISIBILITY
Marshall Clowec392962015-05-10 13:35:00 +00001812 iterator erase(iterator __p) {return __table_.erase(__p.__i_);}
1813 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001814 size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001815 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001816 iterator erase(const_iterator __first, const_iterator __last)
1817 {return __table_.erase(__first.__i_, __last.__i_);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001818 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001819 void clear() _NOEXCEPT {__table_.clear();}
Howard Hinnant3e519522010-05-11 19:42:16 +00001820
Erik Pilkingtonb0386a52018-08-01 01:33:38 +00001821#if _LIBCPP_STD_VER > 14
1822 _LIBCPP_INLINE_VISIBILITY
1823 iterator insert(node_type&& __nh)
1824 {
1825 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1826 "node_type with incompatible allocator passed to unordered_multimap::insert()");
1827 return __table_.template __node_handle_insert_multi<node_type>(
1828 _VSTD::move(__nh));
1829 }
1830 _LIBCPP_INLINE_VISIBILITY
1831 iterator insert(const_iterator __hint, node_type&& __nh)
1832 {
1833 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1834 "node_type with incompatible allocator passed to unordered_multimap::insert()");
1835 return __table_.template __node_handle_insert_multi<node_type>(
1836 __hint.__i_, _VSTD::move(__nh));
1837 }
1838 _LIBCPP_INLINE_VISIBILITY
1839 node_type extract(key_type const& __key)
1840 {
1841 return __table_.template __node_handle_extract<node_type>(__key);
1842 }
1843 _LIBCPP_INLINE_VISIBILITY
1844 node_type extract(const_iterator __it)
1845 {
1846 return __table_.template __node_handle_extract<node_type>(
1847 __it.__i_);
1848 }
1849#endif
1850
Howard Hinnant789847d2010-09-23 18:58:28 +00001851 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001852 void swap(unordered_multimap& __u)
1853 _NOEXCEPT_(__is_nothrow_swappable<__table>::value)
1854 {__table_.swap(__u.__table_);}
Howard Hinnant3e519522010-05-11 19:42:16 +00001855
Howard Hinnant789847d2010-09-23 18:58:28 +00001856 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001857 hasher hash_function() const
1858 {return __table_.hash_function().hash_function();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001859 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001860 key_equal key_eq() const
1861 {return __table_.key_eq().key_eq();}
1862
Howard Hinnant789847d2010-09-23 18:58:28 +00001863 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001864 iterator find(const key_type& __k) {return __table_.find(__k);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001865 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001866 const_iterator find(const key_type& __k) const {return __table_.find(__k);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001867 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001868 size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001869 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001870 pair<iterator, iterator> equal_range(const key_type& __k)
1871 {return __table_.__equal_range_multi(__k);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001872 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001873 pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
1874 {return __table_.__equal_range_multi(__k);}
1875
Howard Hinnant789847d2010-09-23 18:58:28 +00001876 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001877 size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001878 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001879 size_type max_bucket_count() const _NOEXCEPT
1880 {return __table_.max_bucket_count();}
Howard Hinnant3e519522010-05-11 19:42:16 +00001881
Howard Hinnant789847d2010-09-23 18:58:28 +00001882 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001883 size_type bucket_size(size_type __n) const
1884 {return __table_.bucket_size(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001885 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001886 size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
1887
Howard Hinnant789847d2010-09-23 18:58:28 +00001888 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001889 local_iterator begin(size_type __n) {return __table_.begin(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001890 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001891 local_iterator end(size_type __n) {return __table_.end(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001892 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001893 const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001894 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001895 const_local_iterator end(size_type __n) const {return __table_.cend(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001896 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001897 const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001898 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001899 const_local_iterator cend(size_type __n) const {return __table_.cend(__n);}
1900
Howard Hinnant789847d2010-09-23 18:58:28 +00001901 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001902 float load_factor() const _NOEXCEPT {return __table_.load_factor();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001903 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant37141072011-06-04 18:54:24 +00001904 float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}
Howard Hinnant789847d2010-09-23 18:58:28 +00001905 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001906 void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001907 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001908 void rehash(size_type __n) {__table_.rehash(__n);}
Howard Hinnant789847d2010-09-23 18:58:28 +00001909 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001910 void reserve(size_type __n) {__table_.reserve(__n);}
1911
Howard Hinnantb24c8022013-07-23 22:01:58 +00001912#if _LIBCPP_DEBUG_LEVEL >= 2
1913
1914 bool __dereferenceable(const const_iterator* __i) const
1915 {return __table_.__dereferenceable(&__i->__i_);}
1916 bool __decrementable(const const_iterator* __i) const
1917 {return __table_.__decrementable(&__i->__i_);}
1918 bool __addable(const const_iterator* __i, ptrdiff_t __n) const
1919 {return __table_.__addable(&__i->__i_, __n);}
1920 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
1921 {return __table_.__addable(&__i->__i_, __n);}
1922
1923#endif // _LIBCPP_DEBUG_LEVEL >= 2
1924
Eric Fiselierfcd02212016-02-11 11:59:44 +00001925
Howard Hinnant3e519522010-05-11 19:42:16 +00001926};
1927
1928template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1929unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1930 size_type __n, const hasher& __hf, const key_equal& __eql)
1931 : __table_(__hf, __eql)
1932{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001933#if _LIBCPP_DEBUG_LEVEL >= 2
1934 __get_db()->__insert_c(this);
1935#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001936 __table_.rehash(__n);
1937}
1938
1939template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1940unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1941 size_type __n, const hasher& __hf, const key_equal& __eql,
1942 const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00001943 : __table_(__hf, __eql, typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00001944{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001945#if _LIBCPP_DEBUG_LEVEL >= 2
1946 __get_db()->__insert_c(this);
1947#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001948 __table_.rehash(__n);
1949}
1950
1951template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1952template <class _InputIterator>
1953unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1954 _InputIterator __first, _InputIterator __last)
1955{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001956#if _LIBCPP_DEBUG_LEVEL >= 2
1957 __get_db()->__insert_c(this);
1958#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001959 insert(__first, __last);
1960}
1961
1962template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1963template <class _InputIterator>
1964unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1965 _InputIterator __first, _InputIterator __last, size_type __n,
1966 const hasher& __hf, const key_equal& __eql)
1967 : __table_(__hf, __eql)
1968{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001969#if _LIBCPP_DEBUG_LEVEL >= 2
1970 __get_db()->__insert_c(this);
1971#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001972 __table_.rehash(__n);
1973 insert(__first, __last);
1974}
1975
1976template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1977template <class _InputIterator>
1978unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1979 _InputIterator __first, _InputIterator __last, size_type __n,
1980 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00001981 : __table_(__hf, __eql, typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00001982{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001983#if _LIBCPP_DEBUG_LEVEL >= 2
1984 __get_db()->__insert_c(this);
1985#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001986 __table_.rehash(__n);
1987 insert(__first, __last);
1988}
1989
Howard Hinnant3e519522010-05-11 19:42:16 +00001990template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001991inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001992unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1993 const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00001994 : __table_(typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00001995{
Howard Hinnantb24c8022013-07-23 22:01:58 +00001996#if _LIBCPP_DEBUG_LEVEL >= 2
1997 __get_db()->__insert_c(this);
1998#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001999}
2000
2001template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2002unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
2003 const unordered_multimap& __u)
2004 : __table_(__u.__table_)
2005{
Howard Hinnantb24c8022013-07-23 22:01:58 +00002006#if _LIBCPP_DEBUG_LEVEL >= 2
2007 __get_db()->__insert_c(this);
2008#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00002009 __table_.rehash(__u.bucket_count());
2010 insert(__u.begin(), __u.end());
2011}
2012
2013template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2014unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
2015 const unordered_multimap& __u, const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00002016 : __table_(__u.__table_, typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00002017{
Howard Hinnantb24c8022013-07-23 22:01:58 +00002018#if _LIBCPP_DEBUG_LEVEL >= 2
2019 __get_db()->__insert_c(this);
2020#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00002021 __table_.rehash(__u.bucket_count());
2022 insert(__u.begin(), __u.end());
2023}
2024
Eric Fiselier6a470bc2017-04-18 22:50:56 +00002025#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00002026
2027template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00002028inline
Howard Hinnant3e519522010-05-11 19:42:16 +00002029unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
2030 unordered_multimap&& __u)
Howard Hinnant37141072011-06-04 18:54:24 +00002031 _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +00002032 : __table_(_VSTD::move(__u.__table_))
Howard Hinnant3e519522010-05-11 19:42:16 +00002033{
Howard Hinnantb24c8022013-07-23 22:01:58 +00002034#if _LIBCPP_DEBUG_LEVEL >= 2
2035 __get_db()->__insert_c(this);
Howard Hinnant4c80bfb2013-07-30 21:04:42 +00002036 __get_db()->swap(this, &__u);
Howard Hinnantb24c8022013-07-23 22:01:58 +00002037#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00002038}
2039
2040template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2041unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
2042 unordered_multimap&& __u, const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00002043 : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00002044{
Howard Hinnantb24c8022013-07-23 22:01:58 +00002045#if _LIBCPP_DEBUG_LEVEL >= 2
2046 __get_db()->__insert_c(this);
2047#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00002048 if (__a != __u.get_allocator())
2049 {
2050 iterator __i = __u.begin();
2051 while (__u.size() != 0)
Howard Hinnantb24c8022013-07-23 22:01:58 +00002052 {
Howard Hinnant3e519522010-05-11 19:42:16 +00002053 __table_.__insert_multi(
Erik Pilkingtonf52318b2018-06-04 20:38:23 +00002054 __u.__table_.remove((__i++).__i_)->__value_.__move());
Howard Hinnantb24c8022013-07-23 22:01:58 +00002055 }
Howard Hinnant3e519522010-05-11 19:42:16 +00002056 }
Howard Hinnant4c80bfb2013-07-30 21:04:42 +00002057#if _LIBCPP_DEBUG_LEVEL >= 2
2058 else
2059 __get_db()->swap(this, &__u);
2060#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00002061}
2062
Howard Hinnant3e519522010-05-11 19:42:16 +00002063template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2064unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
2065 initializer_list<value_type> __il)
2066{
Howard Hinnantb24c8022013-07-23 22:01:58 +00002067#if _LIBCPP_DEBUG_LEVEL >= 2
2068 __get_db()->__insert_c(this);
2069#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00002070 insert(__il.begin(), __il.end());
2071}
2072
2073template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2074unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
2075 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
2076 const key_equal& __eql)
2077 : __table_(__hf, __eql)
2078{
Howard Hinnantb24c8022013-07-23 22:01:58 +00002079#if _LIBCPP_DEBUG_LEVEL >= 2
2080 __get_db()->__insert_c(this);
2081#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00002082 __table_.rehash(__n);
2083 insert(__il.begin(), __il.end());
2084}
2085
2086template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2087unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
2088 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
2089 const key_equal& __eql, const allocator_type& __a)
Marshall Clow2a10c962016-08-17 05:58:40 +00002090 : __table_(__hf, __eql, typename __table::allocator_type(__a))
Howard Hinnant3e519522010-05-11 19:42:16 +00002091{
Howard Hinnantb24c8022013-07-23 22:01:58 +00002092#if _LIBCPP_DEBUG_LEVEL >= 2
2093 __get_db()->__insert_c(this);
2094#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00002095 __table_.rehash(__n);
2096 insert(__il.begin(), __il.end());
2097}
2098
Howard Hinnant3e519522010-05-11 19:42:16 +00002099template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00002100inline
Howard Hinnant3e519522010-05-11 19:42:16 +00002101unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&
2102unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u)
Howard Hinnant37141072011-06-04 18:54:24 +00002103 _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +00002104{
Howard Hinnantce48a112011-06-30 21:18:19 +00002105 __table_ = _VSTD::move(__u.__table_);
Howard Hinnant3e519522010-05-11 19:42:16 +00002106 return *this;
2107}
2108
Howard Hinnant3e519522010-05-11 19:42:16 +00002109template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00002110inline
Howard Hinnant3e519522010-05-11 19:42:16 +00002111unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&
2112unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(
2113 initializer_list<value_type> __il)
2114{
2115 __table_.__assign_multi(__il.begin(), __il.end());
2116 return *this;
2117}
2118
Eric Fiselier6a470bc2017-04-18 22:50:56 +00002119#endif // _LIBCPP_CXX03_LANG
Howard Hinnant54976f22011-08-12 21:56:02 +00002120
Howard Hinnant3e519522010-05-11 19:42:16 +00002121
Howard Hinnant3e519522010-05-11 19:42:16 +00002122
2123template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2124template <class _InputIterator>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00002125inline
Howard Hinnant3e519522010-05-11 19:42:16 +00002126void
2127unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
2128 _InputIterator __last)
2129{
2130 for (; __first != __last; ++__first)
2131 __table_.__insert_multi(*__first);
2132}
2133
2134template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Howard Hinnant789847d2010-09-23 18:58:28 +00002135inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00002136void
2137swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
2138 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
Howard Hinnant37141072011-06-04 18:54:24 +00002139 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnant3e519522010-05-11 19:42:16 +00002140{
2141 __x.swap(__y);
2142}
2143
2144template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2145bool
2146operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
2147 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
2148{
2149 if (__x.size() != __y.size())
2150 return false;
2151 typedef typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
2152 const_iterator;
2153 typedef pair<const_iterator, const_iterator> _EqRng;
2154 for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
2155 {
2156 _EqRng __xeq = __x.equal_range(__i->first);
2157 _EqRng __yeq = __y.equal_range(__i->first);
Howard Hinnantce48a112011-06-30 21:18:19 +00002158 if (_VSTD::distance(__xeq.first, __xeq.second) !=
2159 _VSTD::distance(__yeq.first, __yeq.second) ||
2160 !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
Howard Hinnant3e519522010-05-11 19:42:16 +00002161 return false;
2162 __i = __xeq.second;
2163 }
2164 return true;
2165}
2166
2167template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
Howard Hinnant789847d2010-09-23 18:58:28 +00002168inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00002169bool
2170operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
2171 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
2172{
2173 return !(__x == __y);
2174}
2175
2176_LIBCPP_END_NAMESPACE_STD
2177
2178#endif // _LIBCPP_UNORDERED_MAP