blob: 2dd61a5067e9920ee0d78a3f592a2e278fa8cc8c [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===-------------------------- unordered_map -----------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
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
47 explicit unordered_map(size_type n = 0, const hasher& hf = hasher(),
48 const key_equal& eql = key_equal(),
49 const allocator_type& a = allocator_type());
50 template <class InputIterator>
51 unordered_map(InputIterator f, InputIterator l,
52 size_type n = 0, const hasher& hf = hasher(),
53 const key_equal& eql = key_equal(),
54 const allocator_type& a = allocator_type());
55 explicit unordered_map(const allocator_type&);
56 unordered_map(const unordered_map&);
57 unordered_map(const unordered_map&, const Allocator&);
58 unordered_map(unordered_map&&);
59 unordered_map(unordered_map&&, const Allocator&);
60 unordered_map(initializer_list<value_type>, size_type n = 0,
61 const hasher& hf = hasher(), const key_equal& eql = key_equal(),
62 const allocator_type& a = allocator_type());
63 ~unordered_map();
64 unordered_map& operator=(const unordered_map&);
65 unordered_map& operator=(unordered_map&&);
66 unordered_map& operator=(initializer_list<value_type>);
67
68 allocator_type get_allocator() const;
69
70 bool empty() const;
71 size_type size() const;
72 size_type max_size() const;
73
74 iterator begin();
75 iterator end();
76 const_iterator begin() const;
77 const_iterator end() const;
78 const_iterator cbegin() const;
79 const_iterator cend() const;
80
81 template <class... Args>
82 pair<iterator, bool> emplace(Args&&... args);
83 template <class... Args>
84 iterator emplace_hint(const_iterator position, Args&&... args);
85 pair<iterator, bool> insert(const value_type& obj);
86 template <class P>
87 pair<iterator, bool> insert(P&& obj);
88 iterator insert(const_iterator hint, const value_type& obj);
89 template <class P>
90 iterator insert(const_iterator hint, P&& obj);
91 template <class InputIterator>
92 void insert(InputIterator first, InputIterator last);
93 void insert(initializer_list<value_type>);
94
95 iterator erase(const_iterator position);
96 size_type erase(const key_type& k);
97 iterator erase(const_iterator first, const_iterator last);
98 void clear();
99
100 void swap(unordered_map&);
101
102 hasher hash_function() const;
103 key_equal key_eq() const;
104
105 iterator find(const key_type& k);
106 const_iterator find(const key_type& k) const;
107 size_type count(const key_type& k) const;
108 pair<iterator, iterator> equal_range(const key_type& k);
109 pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
110
111 mapped_type& operator[](const key_type& k);
112 mapped_type& operator[](key_type&& k);
113
114 mapped_type& at(const key_type& k);
115 const mapped_type& at(const key_type& k) const;
116
117 size_type bucket_count() const;
118 size_type max_bucket_count() const;
119
120 size_type bucket_size(size_type n) const;
121 size_type bucket(const key_type& k) const;
122
123 local_iterator begin(size_type n);
124 local_iterator end(size_type n);
125 const_local_iterator begin(size_type n) const;
126 const_local_iterator end(size_type n) const;
127 const_local_iterator cbegin(size_type n) const;
128 const_local_iterator cend(size_type n) const;
129
130 float load_factor() const;
131 float max_load_factor() const;
132 void max_load_factor(float z);
133 void rehash(size_type n);
134 void reserve(size_type n);
135};
136
137template <class Key, class T, class Hash, class Pred, class Alloc>
138 void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
139 unordered_map<Key, T, Hash, Pred, Alloc>& y);
140
141template <class Key, class T, class Hash, class Pred, class Alloc>
142 bool
143 operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& x,
144 const unordered_map<Key, T, Hash, Pred, Alloc>& y);
145
146template <class Key, class T, class Hash, class Pred, class Alloc>
147 bool
148 operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& x,
149 const unordered_map<Key, T, Hash, Pred, Alloc>& y);
150
151template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
152 class Alloc = allocator<pair<const Key, T>>>
153class unordered_multimap
154{
155public:
156 // types
157 typedef Key key_type;
158 typedef T mapped_type;
159 typedef Hash hasher;
160 typedef Pred key_equal;
161 typedef Alloc allocator_type;
162 typedef pair<const key_type, mapped_type> value_type;
163 typedef value_type& reference;
164 typedef const value_type& const_reference;
165 typedef typename allocator_traits<allocator_type>::pointer pointer;
166 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
167 typedef typename allocator_traits<allocator_type>::size_type size_type;
168 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
169
170 typedef /unspecified/ iterator;
171 typedef /unspecified/ const_iterator;
172 typedef /unspecified/ local_iterator;
173 typedef /unspecified/ const_local_iterator;
174
175 explicit unordered_multimap(size_type n = 0, const hasher& hf = hasher(),
176 const key_equal& eql = key_equal(),
177 const allocator_type& a = allocator_type());
178 template <class InputIterator>
179 unordered_multimap(InputIterator f, InputIterator l,
180 size_type n = 0, const hasher& hf = hasher(),
181 const key_equal& eql = key_equal(),
182 const allocator_type& a = allocator_type());
183 explicit unordered_multimap(const allocator_type&);
184 unordered_multimap(const unordered_multimap&);
185 unordered_multimap(const unordered_multimap&, const Allocator&);
186 unordered_multimap(unordered_multimap&&);
187 unordered_multimap(unordered_multimap&&, const Allocator&);
188 unordered_multimap(initializer_list<value_type>, size_type n = 0,
189 const hasher& hf = hasher(), const key_equal& eql = key_equal(),
190 const allocator_type& a = allocator_type());
191 ~unordered_multimap();
192 unordered_multimap& operator=(const unordered_multimap&);
193 unordered_multimap& operator=(unordered_multimap&&);
194 unordered_multimap& operator=(initializer_list<value_type>);
195
196 allocator_type get_allocator() const;
197
198 bool empty() const;
199 size_type size() const;
200 size_type max_size() const;
201
202 iterator begin();
203 iterator end();
204 const_iterator begin() const;
205 const_iterator end() const;
206 const_iterator cbegin() const;
207 const_iterator cend() const;
208
209 template <class... Args>
210 iterator emplace(Args&&... args);
211 template <class... Args>
212 iterator emplace_hint(const_iterator position, Args&&... args);
213 iterator insert(const value_type& obj);
214 template <class P>
215 iterator insert(P&& obj);
216 iterator insert(const_iterator hint, const value_type& obj);
217 template <class P>
218 iterator insert(const_iterator hint, P&& obj);
219 template <class InputIterator>
220 void insert(InputIterator first, InputIterator last);
221 void insert(initializer_list<value_type>);
222
223 iterator erase(const_iterator position);
224 size_type erase(const key_type& k);
225 iterator erase(const_iterator first, const_iterator last);
226 void clear();
227
228 void swap(unordered_multimap&);
229
230 hasher hash_function() const;
231 key_equal key_eq() const;
232
233 iterator find(const key_type& k);
234 const_iterator find(const key_type& k) const;
235 size_type count(const key_type& k) const;
236 pair<iterator, iterator> equal_range(const key_type& k);
237 pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
238
239 size_type bucket_count() const;
240 size_type max_bucket_count() const;
241
242 size_type bucket_size(size_type n) const;
243 size_type bucket(const key_type& k) const;
244
245 local_iterator begin(size_type n);
246 local_iterator end(size_type n);
247 const_local_iterator begin(size_type n) const;
248 const_local_iterator end(size_type n) const;
249 const_local_iterator cbegin(size_type n) const;
250 const_local_iterator cend(size_type n) const;
251
252 float load_factor() const;
253 float max_load_factor() const;
254 void max_load_factor(float z);
255 void rehash(size_type n);
256 void reserve(size_type n);
257};
258
259template <class Key, class T, class Hash, class Pred, class Alloc>
260 void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
261 unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
262
263template <class Key, class T, class Hash, class Pred, class Alloc>
264 bool
265 operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
266 const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
267
268template <class Key, class T, class Hash, class Pred, class Alloc>
269 bool
270 operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
271 const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
272
273} // std
274
275*/
276
277#include <__config>
278#include <__hash_table>
279#include <functional>
280#include <stdexcept>
281
282#pragma GCC system_header
283
284_LIBCPP_BEGIN_NAMESPACE_STD
285
286template <class _Tp, class _Hash, bool = is_empty<_Hash>::value>
287class __unordered_map_hasher
288 : private _Hash
289{
290public:
291 __unordered_map_hasher() : _Hash() {}
292 __unordered_map_hasher(const _Hash& __h) : _Hash(__h) {}
293 const _Hash& hash_function() const {return *this;}
294 size_t operator()(const _Tp& __x) const
295 {return static_cast<const _Hash&>(*this)(__x.first);}
296 size_t operator()(const typename _Tp::first_type& __x) const
297 {return static_cast<const _Hash&>(*this)(__x);}
298};
299
300template <class _Tp, class _Hash>
301class __unordered_map_hasher<_Tp, _Hash, false>
302{
303 _Hash __hash_;
304public:
305 __unordered_map_hasher() : __hash_() {}
306 __unordered_map_hasher(const _Hash& __h) : __hash_(__h) {}
307 const _Hash& hash_function() const {return __hash_;}
308 size_t operator()(const _Tp& __x) const
309 {return __hash_(__x.first);}
310 size_t operator()(const typename _Tp::first_type& __x) const
311 {return __hash_(__x);}
312};
313
314template <class _Tp, class _Pred, bool = is_empty<_Pred>::value>
315class __unordered_map_equal
316 : private _Pred
317{
318public:
319 __unordered_map_equal() : _Pred() {}
320 __unordered_map_equal(const _Pred& __p) : _Pred(__p) {}
321 const _Pred& key_eq() const {return *this;}
322 bool operator()(const _Tp& __x, const _Tp& __y) const
323 {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
324 bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
325 {return static_cast<const _Pred&>(*this)(__x, __y.first);}
326 bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
327 {return static_cast<const _Pred&>(*this)(__x.first, __y);}
Howard Hinnant324bb032010-08-22 00:02:43 +0000328 bool operator()(const typename _Tp::first_type& __x,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000329 const typename _Tp::first_type& __y) const
330 {return static_cast<const _Pred&>(*this)(__x, __y);}
331};
332
333template <class _Tp, class _Pred>
334class __unordered_map_equal<_Tp, _Pred, false>
335{
336 _Pred __pred_;
337public:
338 __unordered_map_equal() : __pred_() {}
339 __unordered_map_equal(const _Pred& __p) : __pred_(__p) {}
340 const _Pred& key_eq() const {return __pred_;}
341 bool operator()(const _Tp& __x, const _Tp& __y) const
342 {return __pred_(__x.first, __y.first);}
343 bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
344 {return __pred_(__x, __y.first);}
345 bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
346 {return __pred_(__x.first, __y);}
347 bool operator()(const typename _Tp::first_type& __x,
348 const typename _Tp::first_type& __y) const
349 {return __pred_(__x, __y);}
350};
351
352template <class _Alloc>
353class __hash_map_node_destructor
354{
355 typedef _Alloc allocator_type;
356 typedef allocator_traits<allocator_type> __alloc_traits;
357 typedef typename __alloc_traits::value_type::value_type value_type;
358public:
359 typedef typename __alloc_traits::pointer pointer;
360private:
361 typedef typename value_type::first_type first_type;
362 typedef typename value_type::second_type second_type;
363
364 allocator_type& __na_;
365
366 __hash_map_node_destructor& operator=(const __hash_map_node_destructor&);
367
368public:
369 bool __first_constructed;
370 bool __second_constructed;
371
372 explicit __hash_map_node_destructor(allocator_type& __na)
373 : __na_(__na),
374 __first_constructed(false),
375 __second_constructed(false)
376 {}
377
Howard Hinnant73d21a42010-09-04 23:28:19 +0000378#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000379 __hash_map_node_destructor(__hash_node_destructor<allocator_type>&& __x)
380 : __na_(__x.__na_),
381 __first_constructed(__x.__value_constructed),
382 __second_constructed(__x.__value_constructed)
383 {
384 __x.__value_constructed = false;
385 }
Howard Hinnant73d21a42010-09-04 23:28:19 +0000386#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000387 __hash_map_node_destructor(const __hash_node_destructor<allocator_type>& __x)
388 : __na_(__x.__na_),
389 __first_constructed(__x.__value_constructed),
390 __second_constructed(__x.__value_constructed)
391 {
392 const_cast<bool&>(__x.__value_constructed) = false;
393 }
Howard Hinnant73d21a42010-09-04 23:28:19 +0000394#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000395
396 void operator()(pointer __p)
397 {
398 if (__second_constructed)
399 __alloc_traits::destroy(__na_, addressof(__p->__value_.second));
400 if (__first_constructed)
401 __alloc_traits::destroy(__na_, addressof(__p->__value_.first));
402 if (__p)
403 __alloc_traits::deallocate(__na_, __p, 1);
404 }
405};
406
407template <class _HashIterator>
408class __hash_map_iterator
409{
410 _HashIterator __i_;
411
412 typedef pointer_traits<typename _HashIterator::pointer> __pointer_traits;
413 typedef const typename _HashIterator::value_type::first_type key_type;
414 typedef typename _HashIterator::value_type::second_type mapped_type;
415public:
416 typedef forward_iterator_tag iterator_category;
417 typedef pair<key_type, mapped_type> value_type;
418 typedef typename _HashIterator::difference_type difference_type;
419 typedef value_type& reference;
420 typedef typename __pointer_traits::template
421#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
422 rebind<value_type>
423#else
424 rebind<value_type>::other
425#endif
426 pointer;
427
428 __hash_map_iterator() {}
429
430 __hash_map_iterator(_HashIterator __i) : __i_(__i) {}
431
432 reference operator*() const {return *operator->();}
433 pointer operator->() const {return (pointer)__i_.operator->();}
434
435 __hash_map_iterator& operator++() {++__i_; return *this;}
436 __hash_map_iterator operator++(int)
437 {
438 __hash_map_iterator __t(*this);
439 ++(*this);
440 return __t;
441 }
442
443 friend bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
444 {return __x.__i_ == __y.__i_;}
445 friend bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
446 {return __x.__i_ != __y.__i_;}
447
448 template <class, class, class, class, class> friend class unordered_map;
449 template <class, class, class, class, class> friend class unordered_multimap;
450 template <class> friend class __hash_const_iterator;
451 template <class> friend class __hash_const_local_iterator;
452 template <class> friend class __hash_map_const_iterator;
453};
454
455template <class _HashIterator>
456class __hash_map_const_iterator
457{
458 _HashIterator __i_;
459
460 typedef pointer_traits<typename _HashIterator::pointer> __pointer_traits;
461 typedef const typename _HashIterator::value_type::first_type key_type;
462 typedef typename _HashIterator::value_type::second_type mapped_type;
463public:
464 typedef forward_iterator_tag iterator_category;
465 typedef pair<key_type, mapped_type> value_type;
466 typedef typename _HashIterator::difference_type difference_type;
467 typedef const value_type& reference;
468 typedef typename __pointer_traits::template
469#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
470 rebind<value_type>
471#else
472 rebind<value_type>::other
473#endif
474 pointer;
475
476 __hash_map_const_iterator() {}
477
478 __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {}
479 __hash_map_const_iterator(
480 __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
481 : __i_(__i.__i_) {}
482
483 reference operator*() const {return *operator->();}
484 pointer operator->() const {return (pointer)__i_.operator->();}
485
486 __hash_map_const_iterator& operator++() {++__i_; return *this;}
487 __hash_map_const_iterator operator++(int)
488 {
489 __hash_map_const_iterator __t(*this);
490 ++(*this);
491 return __t;
492 }
493
494 friend bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
495 {return __x.__i_ == __y.__i_;}
496 friend bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
497 {return __x.__i_ != __y.__i_;}
498
499 template <class, class, class, class, class> friend class unordered_map;
500 template <class, class, class, class, class> friend class unordered_multimap;
501 template <class> friend class __hash_const_iterator;
502 template <class> friend class __hash_const_local_iterator;
503};
504
505template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
506 class _Alloc = allocator<pair<const _Key, _Tp> > >
507class unordered_map
508{
509public:
510 // types
511 typedef _Key key_type;
512 typedef _Tp mapped_type;
513 typedef _Hash hasher;
514 typedef _Pred key_equal;
515 typedef _Alloc allocator_type;
516 typedef pair<const key_type, mapped_type> value_type;
517 typedef value_type& reference;
518 typedef const value_type& const_reference;
519
520private:
521 typedef pair<key_type, mapped_type> __value_type;
522 typedef __unordered_map_hasher<__value_type, hasher> __hasher;
523 typedef __unordered_map_equal<__value_type, key_equal> __key_equal;
524 typedef typename allocator_traits<allocator_type>::template
525#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
526 rebind_alloc<__value_type>
527#else
528 rebind_alloc<__value_type>::other
529#endif
530 __allocator_type;
531
532 typedef __hash_table<__value_type, __hasher,
533 __key_equal, __allocator_type> __table;
534
535 __table __table_;
536
537 typedef typename __table::__node_pointer __node_pointer;
538 typedef typename __table::__node_const_pointer __node_const_pointer;
539 typedef typename __table::__node_traits __node_traits;
540 typedef typename __table::__node_allocator __node_allocator;
541 typedef typename __table::__node __node;
542 typedef __hash_map_node_destructor<__node_allocator> _D;
543 typedef unique_ptr<__node, _D> __node_holder;
544 typedef allocator_traits<allocator_type> __alloc_traits;
545public:
546 typedef typename __alloc_traits::pointer pointer;
547 typedef typename __alloc_traits::const_pointer const_pointer;
548 typedef typename __alloc_traits::size_type size_type;
549 typedef typename __alloc_traits::difference_type difference_type;
550
551 typedef __hash_map_iterator<typename __table::iterator> iterator;
552 typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
553 typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
554 typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
555
556 unordered_map() {} // = default;
557 explicit unordered_map(size_type __n, const hasher& __hf = hasher(),
558 const key_equal& __eql = key_equal());
559 unordered_map(size_type __n, const hasher& __hf,
560 const key_equal& __eql,
561 const allocator_type& __a);
562 template <class _InputIterator>
563 unordered_map(_InputIterator __first, _InputIterator __last);
564 template <class _InputIterator>
565 unordered_map(_InputIterator __first, _InputIterator __last,
566 size_type __n, const hasher& __hf = hasher(),
567 const key_equal& __eql = key_equal());
568 template <class _InputIterator>
569 unordered_map(_InputIterator __first, _InputIterator __last,
570 size_type __n, const hasher& __hf,
571 const key_equal& __eql,
572 const allocator_type& __a);
573 explicit unordered_map(const allocator_type& __a);
574 unordered_map(const unordered_map& __u);
575 unordered_map(const unordered_map& __u, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000576#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000577 unordered_map(unordered_map&& __u);
578 unordered_map(unordered_map&& __u, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000579#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000580 unordered_map(initializer_list<value_type> __il);
581 unordered_map(initializer_list<value_type> __il, size_type __n,
582 const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
583 unordered_map(initializer_list<value_type> __il, size_type __n,
584 const hasher& __hf, const key_equal& __eql,
585 const allocator_type& __a);
586 // ~unordered_map() = default;
587 // unordered_map& operator=(const unordered_map& __u) = default;
Howard Hinnant73d21a42010-09-04 23:28:19 +0000588#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000589 unordered_map& operator=(unordered_map&& __u);
590#endif
591 unordered_map& operator=(initializer_list<value_type> __il);
592
593 allocator_type get_allocator() const
594 {return allocator_type(__table_.__node_alloc());}
595
596 bool empty() const {return __table_.size() == 0;}
597 size_type size() const {return __table_.size();}
598 size_type max_size() const {return __table_.max_size();}
599
600 iterator begin() {return __table_.begin();}
601 iterator end() {return __table_.end();}
602 const_iterator begin() const {return __table_.begin();}
603 const_iterator end() const {return __table_.end();}
604 const_iterator cbegin() const {return __table_.begin();}
605 const_iterator cend() const {return __table_.end();}
606
Howard Hinnant73d21a42010-09-04 23:28:19 +0000607#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000608 pair<iterator, bool> emplace()
609 {return __table_.__emplace_unique();}
610
611 template <class _A0,
612 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
613 pair<iterator, bool> emplace(_A0&& __a0)
614 {return __table_.__emplace_unique(_STD::forward<_A0>(__a0));}
615
Howard Hinnant73d21a42010-09-04 23:28:19 +0000616#ifndef _LIBCPP_HAS_NO_VARIADICS
617
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000618 template <class _A0, class... _Args,
619 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
620 pair<iterator, bool> emplace(_A0&& __a0, _Args&&... __args);
621
Howard Hinnant73d21a42010-09-04 23:28:19 +0000622#endif // _LIBCPP_HAS_NO_VARIADICS
623
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000624 iterator emplace_hint(const_iterator)
625 {return __table_.__emplace_unique().first;}
626
627 template <class _A0,
628 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
629 iterator emplace_hint(const_iterator, _A0&& __a0)
630 {return __table_.__emplace_unique(_STD::forward<_A0>(__a0)).first;}
631
Howard Hinnant73d21a42010-09-04 23:28:19 +0000632#ifndef _LIBCPP_HAS_NO_VARIADICS
633
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000634 template <class _A0, class... _Args,
635 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
636 iterator emplace_hint(const_iterator, _A0&& __a0, _Args&&... __args)
637 {return emplace(_STD::forward<_A0>(__a0),
638 _STD::forward<_Args>(__args)...).first;}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000639#endif // _LIBCPP_HAS_NO_VARIADICS
640#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000641 pair<iterator, bool> insert(const value_type& __x)
642 {return __table_.__insert_unique(__x);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000643#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000644 template <class _P,
645 class = typename enable_if<is_convertible<_P, value_type>::value>::type>
646 pair<iterator, bool> insert(_P&& __x)
647 {return __table_.__insert_unique(_STD::forward<_P>(__x));}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000648#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000649 iterator insert(const_iterator, const value_type& __x)
650 {return insert(__x).first;}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000651#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000652 template <class _P,
653 class = typename enable_if<is_convertible<_P, value_type>::value>::type>
654 iterator insert(const_iterator, _P&& __x)
655 {return insert(_STD::forward<_P>(__x)).first;}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000656#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000657 template <class _InputIterator>
658 void insert(_InputIterator __first, _InputIterator __last);
659 void insert(initializer_list<value_type> __il)
660 {insert(__il.begin(), __il.end());}
661
662 iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}
663 size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
664 iterator erase(const_iterator __first, const_iterator __last)
665 {return __table_.erase(__first.__i_, __last.__i_);}
666 void clear() {__table_.clear();}
667
668 void swap(unordered_map& __u) {__table_.swap(__u.__table_);}
669
670 hasher hash_function() const
671 {return __table_.hash_function().hash_function();}
672 key_equal key_eq() const
673 {return __table_.key_eq().key_eq();}
674
675 iterator find(const key_type& __k) {return __table_.find(__k);}
676 const_iterator find(const key_type& __k) const {return __table_.find(__k);}
677 size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
678 pair<iterator, iterator> equal_range(const key_type& __k)
679 {return __table_.__equal_range_unique(__k);}
680 pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
681 {return __table_.__equal_range_unique(__k);}
682
683 mapped_type& operator[](const key_type& __k);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000684#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000685 mapped_type& operator[](key_type&& __k);
686#endif
687
688 mapped_type& at(const key_type& __k);
689 const mapped_type& at(const key_type& __k) const;
690
691 size_type bucket_count() const {return __table_.bucket_count();}
692 size_type max_bucket_count() const {return __table_.max_bucket_count();}
693
694 size_type bucket_size(size_type __n) const
695 {return __table_.bucket_size(__n);}
696 size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
697
698 local_iterator begin(size_type __n) {return __table_.begin(__n);}
699 local_iterator end(size_type __n) {return __table_.end(__n);}
700 const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);}
701 const_local_iterator end(size_type __n) const {return __table_.cend(__n);}
702 const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
703 const_local_iterator cend(size_type __n) const {return __table_.cend(__n);}
704
705 float load_factor() const {return __table_.load_factor();}
706 float max_load_factor() const {return __table_.max_load_factor();}
707 void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
708 void rehash(size_type __n) {__table_.rehash(__n);}
709 void reserve(size_type __n) {__table_.reserve(__n);}
710
711private:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000712#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
713#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000714 template <class _A0, class... _Args,
715 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
716 __node_holder __construct_node(_A0&& __a0, _Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000717#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000718 template <class _A0,
719 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
720 __node_holder __construct_node(_A0&& __a0);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000721#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000722 __node_holder __construct_node(const key_type& __k);
723#endif
724};
725
726template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
727unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
728 size_type __n, const hasher& __hf, const key_equal& __eql)
729 : __table_(__hf, __eql)
730{
731 __table_.rehash(__n);
732}
733
734template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
735unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
736 size_type __n, const hasher& __hf, const key_equal& __eql,
737 const allocator_type& __a)
738 : __table_(__hf, __eql, __a)
739{
740 __table_.rehash(__n);
741}
742
743template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
744inline
745unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
746 const allocator_type& __a)
747 : __table_(__a)
748{
749}
750
751template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
752template <class _InputIterator>
753unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
754 _InputIterator __first, _InputIterator __last)
755{
756 insert(__first, __last);
757}
758
759template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
760template <class _InputIterator>
761unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
762 _InputIterator __first, _InputIterator __last, size_type __n,
763 const hasher& __hf, const key_equal& __eql)
764 : __table_(__hf, __eql)
765{
766 __table_.rehash(__n);
767 insert(__first, __last);
768}
769
770template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
771template <class _InputIterator>
772unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
773 _InputIterator __first, _InputIterator __last, size_type __n,
774 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
775 : __table_(__hf, __eql, __a)
776{
777 __table_.rehash(__n);
778 insert(__first, __last);
779}
780
781template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
782unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
783 const unordered_map& __u)
784 : __table_(__u.__table_)
785{
786 __table_.rehash(__u.bucket_count());
787 insert(__u.begin(), __u.end());
788}
789
790template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
791unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
792 const unordered_map& __u, const allocator_type& __a)
793 : __table_(__u.__table_, __a)
794{
795 __table_.rehash(__u.bucket_count());
796 insert(__u.begin(), __u.end());
797}
798
Howard Hinnant73d21a42010-09-04 23:28:19 +0000799#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000800
801template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
802inline
803unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
804 unordered_map&& __u)
805 : __table_(_STD::move(__u.__table_))
806{
807}
808
809template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
810unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
811 unordered_map&& __u, const allocator_type& __a)
812 : __table_(_STD::move(__u.__table_), __a)
813{
814 if (__a != __u.get_allocator())
815 {
816 iterator __i = __u.begin();
817 while (__u.size() != 0)
818 __table_.__insert_unique(
819 _STD::move(__u.__table_.remove((__i++).__i_)->__value_)
820 );
821 }
822}
823
Howard Hinnant73d21a42010-09-04 23:28:19 +0000824#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000825
826template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
827unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
828 initializer_list<value_type> __il)
829{
830 insert(__il.begin(), __il.end());
831}
832
833template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
834unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
835 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
836 const key_equal& __eql)
837 : __table_(__hf, __eql)
838{
839 __table_.rehash(__n);
840 insert(__il.begin(), __il.end());
841}
842
843template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
844unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
845 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
846 const key_equal& __eql, const allocator_type& __a)
847 : __table_(__hf, __eql, __a)
848{
849 __table_.rehash(__n);
850 insert(__il.begin(), __il.end());
851}
852
Howard Hinnant73d21a42010-09-04 23:28:19 +0000853#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000854
855template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
856inline
857unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&
858unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u)
859{
860 __table_ = _STD::move(__u.__table_);
861 return *this;
862}
863
Howard Hinnant73d21a42010-09-04 23:28:19 +0000864#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000865
866template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
867inline
868unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&
869unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(
870 initializer_list<value_type> __il)
871{
872 __table_.__assign_unique(__il.begin(), __il.end());
873 return *this;
874}
875
Howard Hinnant73d21a42010-09-04 23:28:19 +0000876#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
877#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000878
879template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
880template <class _A0, class... _Args,
881 class // = typename enable_if<is_convertible<_A0, key_type>::value>::type
882 >
883typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
884unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0,
885 _Args&&... __args)
886{
887 __node_allocator& __na = __table_.__node_alloc();
888 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
889 __node_traits::construct(__na, addressof(__h->__value_.first),
890 _STD::forward<_A0>(__a0));
891 __h.get_deleter().__first_constructed = true;
892 __node_traits::construct(__na, addressof(__h->__value_.second),
893 _STD::forward<_Args>(__args)...);
894 __h.get_deleter().__second_constructed = true;
895 return __h;
896}
897
Howard Hinnant73d21a42010-09-04 23:28:19 +0000898#endif // _LIBCPP_HAS_NO_VARIADICS
899
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000900template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
901template <class _A0,
902 class // = typename enable_if<is_convertible<_A0, value_type>::value>::type
903 >
904typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
905unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
906{
907 __node_allocator& __na = __table_.__node_alloc();
908 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
909 __node_traits::construct(__na, addressof(__h->__value_),
910 _STD::forward<_A0>(__a0));
911 __h.get_deleter().__first_constructed = true;
912 __h.get_deleter().__second_constructed = true;
913 return __h;
914}
915
Howard Hinnant73d21a42010-09-04 23:28:19 +0000916#ifndef _LIBCPP_HAS_NO_VARIADICS
917
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000918template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
919template <class _A0, class... _Args,
920 class // = typename enable_if<is_convertible<_A0, key_type>::value>::type
921 >
922pair<typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator, bool>
923unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_A0&& __a0, _Args&&... __args)
924{
925 __node_holder __h = __construct_node(_STD::forward<_A0>(__a0),
926 _STD::forward<_Args>(__args)...);
927 pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
928 if (__r.second)
929 __h.release();
930 return __r;
931}
932
Howard Hinnant73d21a42010-09-04 23:28:19 +0000933#endif // _LIBCPP_HAS_NO_VARIADICS
934#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000935
936template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
937typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
938unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k)
939{
940 __node_allocator& __na = __table_.__node_alloc();
941 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
942 __node_traits::construct(__na, addressof(__h->__value_.first), __k);
943 __h.get_deleter().__first_constructed = true;
944 __node_traits::construct(__na, addressof(__h->__value_.second));
945 __h.get_deleter().__second_constructed = true;
946 return _STD::move(__h);
947}
948
Howard Hinnant73d21a42010-09-04 23:28:19 +0000949#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000950
951template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
952template <class _InputIterator>
953inline
954void
955unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
956 _InputIterator __last)
957{
958 for (; __first != __last; ++__first)
959 __table_.__insert_unique(*__first);
960}
961
962template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
963_Tp&
964unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
965{
966 iterator __i = find(__k);
967 if (__i != end())
968 return __i->second;
969 __node_holder __h = __construct_node(__k);
970 pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
971 __h.release();
972 return __r.first->second;
973}
974
Howard Hinnant73d21a42010-09-04 23:28:19 +0000975#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000976
977template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
978_Tp&
979unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k)
980{
981 iterator __i = find(__k);
982 if (__i != end())
983 return __i->second;
984 __node_holder __h = __construct_node(_STD::move(__k));
985 pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
986 __h.release();
987 return __r.first->second;
988}
989
Howard Hinnant73d21a42010-09-04 23:28:19 +0000990#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000991
992template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
993_Tp&
994unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k)
995{
996 iterator __i = find(__k);
997#ifndef _LIBCPP_NO_EXCEPTIONS
998 if (__i == end())
999 throw out_of_range("unordered_map::at: key not found");
Howard Hinnant324bb032010-08-22 00:02:43 +00001000#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001001 return __i->second;
1002}
1003
1004template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1005const _Tp&
1006unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k) const
1007{
1008 const_iterator __i = find(__k);
1009#ifndef _LIBCPP_NO_EXCEPTIONS
1010 if (__i == end())
1011 throw out_of_range("unordered_map::at: key not found");
Howard Hinnant324bb032010-08-22 00:02:43 +00001012#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001013 return __i->second;
1014}
1015
1016template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1017inline
1018void
1019swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
1020 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
1021{
1022 __x.swap(__y);
1023}
1024
1025template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1026bool
1027operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
1028 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
1029{
1030 if (__x.size() != __y.size())
1031 return false;
1032 typedef typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
1033 const_iterator;
1034 for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
1035 __i != __ex; ++__i)
1036 {
1037 const_iterator __j = __y.find(__i->first);
1038 if (__j == __ey || !(*__i == *__j))
1039 return false;
1040 }
1041 return true;
1042}
1043
1044template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1045inline
1046bool
1047operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
1048 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
1049{
1050 return !(__x == __y);
1051}
1052
1053template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
1054 class _Alloc = allocator<pair<const _Key, _Tp> > >
1055class unordered_multimap
1056{
1057public:
1058 // types
1059 typedef _Key key_type;
1060 typedef _Tp mapped_type;
1061 typedef _Hash hasher;
1062 typedef _Pred key_equal;
1063 typedef _Alloc allocator_type;
1064 typedef pair<const key_type, mapped_type> value_type;
1065 typedef value_type& reference;
1066 typedef const value_type& const_reference;
1067
1068private:
1069 typedef pair<key_type, mapped_type> __value_type;
1070 typedef __unordered_map_hasher<__value_type, hasher> __hasher;
1071 typedef __unordered_map_equal<__value_type, key_equal> __key_equal;
1072 typedef typename allocator_traits<allocator_type>::template
1073#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1074 rebind_alloc<__value_type>
1075#else
1076 rebind_alloc<__value_type>::other
1077#endif
1078 __allocator_type;
1079
1080 typedef __hash_table<__value_type, __hasher,
1081 __key_equal, __allocator_type> __table;
1082
1083 __table __table_;
1084
1085 typedef typename __table::__node_traits __node_traits;
1086 typedef typename __table::__node_allocator __node_allocator;
1087 typedef typename __table::__node __node;
1088 typedef __hash_map_node_destructor<__node_allocator> _D;
1089 typedef unique_ptr<__node, _D> __node_holder;
1090 typedef allocator_traits<allocator_type> __alloc_traits;
1091public:
1092 typedef typename __alloc_traits::pointer pointer;
1093 typedef typename __alloc_traits::const_pointer const_pointer;
1094 typedef typename __alloc_traits::size_type size_type;
1095 typedef typename __alloc_traits::difference_type difference_type;
1096
1097 typedef __hash_map_iterator<typename __table::iterator> iterator;
1098 typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
1099 typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
1100 typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
1101
1102 unordered_multimap() {} // = default
1103 explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(),
1104 const key_equal& __eql = key_equal());
1105 unordered_multimap(size_type __n, const hasher& __hf,
1106 const key_equal& __eql,
1107 const allocator_type& __a);
1108 template <class _InputIterator>
1109 unordered_multimap(_InputIterator __first, _InputIterator __last);
1110 template <class _InputIterator>
1111 unordered_multimap(_InputIterator __first, _InputIterator __last,
1112 size_type __n, const hasher& __hf = hasher(),
1113 const key_equal& __eql = key_equal());
1114 template <class _InputIterator>
1115 unordered_multimap(_InputIterator __first, _InputIterator __last,
1116 size_type __n, const hasher& __hf,
1117 const key_equal& __eql,
1118 const allocator_type& __a);
1119 explicit unordered_multimap(const allocator_type& __a);
1120 unordered_multimap(const unordered_multimap& __u);
1121 unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001122#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001123 unordered_multimap(unordered_multimap&& __u);
1124 unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001125#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001126 unordered_multimap(initializer_list<value_type> __il);
1127 unordered_multimap(initializer_list<value_type> __il, size_type __n,
1128 const hasher& __hf = hasher(),
1129 const key_equal& __eql = key_equal());
1130 unordered_multimap(initializer_list<value_type> __il, size_type __n,
1131 const hasher& __hf, const key_equal& __eql,
1132 const allocator_type& __a);
1133 // ~unordered_multimap() = default;
1134 // unordered_multimap& operator=(const unordered_multimap& __u) = default;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001135#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001136 unordered_multimap& operator=(unordered_multimap&& __u);
1137#endif
1138 unordered_multimap& operator=(initializer_list<value_type> __il);
1139
1140 allocator_type get_allocator() const
1141 {return allocator_type(__table_.__node_alloc());}
1142
1143 bool empty() const {return __table_.size() == 0;}
1144 size_type size() const {return __table_.size();}
1145 size_type max_size() const {return __table_.max_size();}
1146
1147 iterator begin() {return __table_.begin();}
1148 iterator end() {return __table_.end();}
1149 const_iterator begin() const {return __table_.begin();}
1150 const_iterator end() const {return __table_.end();}
1151 const_iterator cbegin() const {return __table_.begin();}
1152 const_iterator cend() const {return __table_.end();}
1153
Howard Hinnant73d21a42010-09-04 23:28:19 +00001154#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001155 iterator emplace()
1156 {return __table_.__emplace_multi();}
1157
1158 template <class _A0,
1159 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
1160 iterator emplace(_A0&& __a0)
1161 {return __table_.__emplace_multi(_STD::forward<_A0>(__a0));}
1162
Howard Hinnant73d21a42010-09-04 23:28:19 +00001163#ifndef _LIBCPP_HAS_NO_VARIADICS
1164
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001165 template <class _A0, class... _Args,
1166 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
1167 iterator emplace(_A0&& __a0, _Args&&... __args);
1168
Howard Hinnant73d21a42010-09-04 23:28:19 +00001169#endif // _LIBCPP_HAS_NO_VARIADICS
1170
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001171 iterator emplace_hint(const_iterator __p)
1172 {return __table_.__emplace_hint_multi(__p.__i_);}
1173
1174 template <class _A0,
1175 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
1176 iterator emplace_hint(const_iterator __p, _A0&& __a0)
1177 {return __table_.__emplace_hint_multi(__p.__i_, _STD::forward<_A0>(__a0));}
1178
Howard Hinnant73d21a42010-09-04 23:28:19 +00001179#ifndef _LIBCPP_HAS_NO_VARIADICS
1180
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001181 template <class _A0, class... _Args,
1182 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
1183 iterator emplace_hint(const_iterator __p, _A0&& __a0, _Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001184#endif // _LIBCPP_HAS_NO_VARIADICS
1185#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001186 iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001187#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001188 template <class _P,
1189 class = typename enable_if<is_convertible<_P, value_type>::value>::type>
1190 iterator insert(_P&& __x)
1191 {return __table_.__insert_multi(_STD::forward<_P>(__x));}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001192#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001193 iterator insert(const_iterator __p, const value_type& __x)
1194 {return __table_.__insert_multi(__p.__i_, __x);}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001195#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001196 template <class _P,
1197 class = typename enable_if<is_convertible<_P, value_type>::value>::type>
1198 iterator insert(const_iterator __p, _P&& __x)
1199 {return __table_.__insert_multi(__p.__i_, _STD::forward<_P>(__x));}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001200#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001201 template <class _InputIterator>
1202 void insert(_InputIterator __first, _InputIterator __last);
1203 void insert(initializer_list<value_type> __il)
1204 {insert(__il.begin(), __il.end());}
1205
1206 iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}
1207 size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
1208 iterator erase(const_iterator __first, const_iterator __last)
1209 {return __table_.erase(__first.__i_, __last.__i_);}
1210 void clear() {__table_.clear();}
1211
1212 void swap(unordered_multimap& __u) {__table_.swap(__u.__table_);}
1213
1214 hasher hash_function() const
1215 {return __table_.hash_function().hash_function();}
1216 key_equal key_eq() const
1217 {return __table_.key_eq().key_eq();}
1218
1219 iterator find(const key_type& __k) {return __table_.find(__k);}
1220 const_iterator find(const key_type& __k) const {return __table_.find(__k);}
1221 size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
1222 pair<iterator, iterator> equal_range(const key_type& __k)
1223 {return __table_.__equal_range_multi(__k);}
1224 pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
1225 {return __table_.__equal_range_multi(__k);}
1226
1227 size_type bucket_count() const {return __table_.bucket_count();}
1228 size_type max_bucket_count() const {return __table_.max_bucket_count();}
1229
1230 size_type bucket_size(size_type __n) const
1231 {return __table_.bucket_size(__n);}
1232 size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
1233
1234 local_iterator begin(size_type __n) {return __table_.begin(__n);}
1235 local_iterator end(size_type __n) {return __table_.end(__n);}
1236 const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);}
1237 const_local_iterator end(size_type __n) const {return __table_.cend(__n);}
1238 const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
1239 const_local_iterator cend(size_type __n) const {return __table_.cend(__n);}
1240
1241 float load_factor() const {return __table_.load_factor();}
1242 float max_load_factor() const {return __table_.max_load_factor();}
1243 void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
1244 void rehash(size_type __n) {__table_.rehash(__n);}
1245 void reserve(size_type __n) {__table_.reserve(__n);}
1246
1247private:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001248#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001249 template <class _A0, class... _Args,
1250 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
1251 __node_holder __construct_node(_A0&& __a0, _Args&&... __args);
1252 template <class _A0,
1253 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
1254 __node_holder __construct_node(_A0&& __a0);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001255#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001256};
1257
1258template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1259unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1260 size_type __n, const hasher& __hf, const key_equal& __eql)
1261 : __table_(__hf, __eql)
1262{
1263 __table_.rehash(__n);
1264}
1265
1266template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1267unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1268 size_type __n, const hasher& __hf, const key_equal& __eql,
1269 const allocator_type& __a)
1270 : __table_(__hf, __eql, __a)
1271{
1272 __table_.rehash(__n);
1273}
1274
1275template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1276template <class _InputIterator>
1277unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1278 _InputIterator __first, _InputIterator __last)
1279{
1280 insert(__first, __last);
1281}
1282
1283template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1284template <class _InputIterator>
1285unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1286 _InputIterator __first, _InputIterator __last, size_type __n,
1287 const hasher& __hf, const key_equal& __eql)
1288 : __table_(__hf, __eql)
1289{
1290 __table_.rehash(__n);
1291 insert(__first, __last);
1292}
1293
1294template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1295template <class _InputIterator>
1296unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1297 _InputIterator __first, _InputIterator __last, size_type __n,
1298 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
1299 : __table_(__hf, __eql, __a)
1300{
1301 __table_.rehash(__n);
1302 insert(__first, __last);
1303}
1304
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001305template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1306inline
1307unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1308 const allocator_type& __a)
1309 : __table_(__a)
1310{
1311}
1312
1313template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1314unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1315 const unordered_multimap& __u)
1316 : __table_(__u.__table_)
1317{
1318 __table_.rehash(__u.bucket_count());
1319 insert(__u.begin(), __u.end());
1320}
1321
1322template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1323unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1324 const unordered_multimap& __u, const allocator_type& __a)
1325 : __table_(__u.__table_, __a)
1326{
1327 __table_.rehash(__u.bucket_count());
1328 insert(__u.begin(), __u.end());
1329}
1330
Howard Hinnant73d21a42010-09-04 23:28:19 +00001331#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001332
1333template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1334inline
1335unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1336 unordered_multimap&& __u)
1337 : __table_(_STD::move(__u.__table_))
1338{
1339}
1340
1341template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1342unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1343 unordered_multimap&& __u, const allocator_type& __a)
1344 : __table_(_STD::move(__u.__table_), __a)
1345{
1346 if (__a != __u.get_allocator())
1347 {
1348 iterator __i = __u.begin();
1349 while (__u.size() != 0)
1350{
1351 __table_.__insert_multi(
1352 _STD::move(__u.__table_.remove((__i++).__i_)->__value_)
1353 );
1354}
1355 }
1356}
1357
Howard Hinnant73d21a42010-09-04 23:28:19 +00001358#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001359
1360template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1361unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1362 initializer_list<value_type> __il)
1363{
1364 insert(__il.begin(), __il.end());
1365}
1366
1367template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1368unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1369 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1370 const key_equal& __eql)
1371 : __table_(__hf, __eql)
1372{
1373 __table_.rehash(__n);
1374 insert(__il.begin(), __il.end());
1375}
1376
1377template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1378unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
1379 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1380 const key_equal& __eql, const allocator_type& __a)
1381 : __table_(__hf, __eql, __a)
1382{
1383 __table_.rehash(__n);
1384 insert(__il.begin(), __il.end());
1385}
1386
Howard Hinnant73d21a42010-09-04 23:28:19 +00001387#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001388
1389template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1390inline
1391unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&
1392unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u)
1393{
1394 __table_ = _STD::move(__u.__table_);
1395 return *this;
1396}
1397
Howard Hinnant73d21a42010-09-04 23:28:19 +00001398#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001399
1400template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1401inline
1402unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&
1403unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(
1404 initializer_list<value_type> __il)
1405{
1406 __table_.__assign_multi(__il.begin(), __il.end());
1407 return *this;
1408}
1409
Howard Hinnant73d21a42010-09-04 23:28:19 +00001410#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1411#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001412
1413template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1414template <class _A0, class... _Args,
1415 class // = typename enable_if<is_convertible<_A0, key_type>::value>::type
1416 >
1417typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
1418unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(
1419 _A0&& __a0, _Args&&... __args)
1420{
1421 __node_allocator& __na = __table_.__node_alloc();
1422 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
1423 __node_traits::construct(__na, addressof(__h->__value_.first),
1424 _STD::forward<_A0>(__a0));
1425 __h.get_deleter().__first_constructed = true;
1426 __node_traits::construct(__na, addressof(__h->__value_.second),
1427 _STD::forward<_Args>(__args)...);
1428 __h.get_deleter().__second_constructed = true;
1429 return __h;
1430}
1431
Howard Hinnant73d21a42010-09-04 23:28:19 +00001432#endif // _LIBCPP_HAS_NO_VARIADICS
1433
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001434template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1435template <class _A0,
1436 class // = typename enable_if<is_convertible<_A0, value_type>::value>::type
1437 >
1438typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
1439unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
1440{
1441 __node_allocator& __na = __table_.__node_alloc();
1442 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
1443 __node_traits::construct(__na, addressof(__h->__value_),
1444 _STD::forward<_A0>(__a0));
1445 __h.get_deleter().__first_constructed = true;
1446 __h.get_deleter().__second_constructed = true;
1447 return __h;
1448}
1449
Howard Hinnant73d21a42010-09-04 23:28:19 +00001450#ifndef _LIBCPP_HAS_NO_VARIADICS
1451
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001452template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1453template <class _A0, class... _Args,
1454 class // = typename enable_if<is_convertible<_A0, key_type>::value>::type
1455 >
1456typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator
1457unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_A0&& __a0, _Args&&... __args)
1458{
1459 __node_holder __h = __construct_node(_STD::forward<_A0>(__a0),
1460 _STD::forward<_Args>(__args)...);
1461 iterator __r = __table_.__node_insert_multi(__h.get());
1462 __h.release();
1463 return __r;
1464}
1465
1466template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1467template <class _A0, class... _Args,
1468 class // = typename enable_if<is_convertible<_A0, key_type>::value>::type
1469 >
1470typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator
1471unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace_hint(
1472 const_iterator __p, _A0&& __a0, _Args&&... __args)
1473{
1474 __node_holder __h = __construct_node(_STD::forward<_A0>(__a0),
1475 _STD::forward<_Args>(__args)...);
1476 iterator __r = __table_.__node_insert_multi(__p.__i_, __h.get());
1477 __h.release();
1478 return __r;
1479}
1480
Howard Hinnant73d21a42010-09-04 23:28:19 +00001481#endif // _LIBCPP_HAS_NO_VARIADICS
1482#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001483
1484template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1485template <class _InputIterator>
1486inline
1487void
1488unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
1489 _InputIterator __last)
1490{
1491 for (; __first != __last; ++__first)
1492 __table_.__insert_multi(*__first);
1493}
1494
1495template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1496inline
1497void
1498swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
1499 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
1500{
1501 __x.swap(__y);
1502}
1503
1504template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1505bool
1506operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
1507 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
1508{
1509 if (__x.size() != __y.size())
1510 return false;
1511 typedef typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
1512 const_iterator;
1513 typedef pair<const_iterator, const_iterator> _EqRng;
1514 for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
1515 {
1516 _EqRng __xeq = __x.equal_range(__i->first);
1517 _EqRng __yeq = __y.equal_range(__i->first);
1518 if (_STD::distance(__xeq.first, __xeq.second) !=
1519 _STD::distance(__yeq.first, __yeq.second) ||
1520 !_STD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
1521 return false;
1522 __i = __xeq.second;
1523 }
1524 return true;
1525}
1526
1527template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
1528inline
1529bool
1530operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
1531 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
1532{
1533 return !(__x == __y);
1534}
1535
1536_LIBCPP_END_NAMESPACE_STD
1537
1538#endif // _LIBCPP_UNORDERED_MAP