blob: d677e8b73f1ee1cfa11498cee5ea1e30ae2ec05b [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===-------------------------- unordered_set -----------------------------===//
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_SET
12#define _LIBCPP_UNORDERED_SET
13
14/*
15
16 unordered_set synopsis
17
18#include <initializer_list>
19
20namespace std
21{
22
23template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
24 class Alloc = allocator<Value>>
25class unordered_set
26{
27public:
28 // types
29 typedef Value key_type;
30 typedef key_type value_type;
31 typedef Hash hasher;
32 typedef Pred key_equal;
33 typedef Alloc allocator_type;
34 typedef value_type& reference;
35 typedef const value_type& const_reference;
36 typedef typename allocator_traits<allocator_type>::pointer pointer;
37 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
38 typedef typename allocator_traits<allocator_type>::size_type size_type;
39 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
40
41 typedef /unspecified/ iterator;
42 typedef /unspecified/ const_iterator;
43 typedef /unspecified/ local_iterator;
44 typedef /unspecified/ const_local_iterator;
45
46 explicit unordered_set(size_type n = 0, const hasher& hf = hasher(),
47 const key_equal& eql = key_equal(),
48 const allocator_type& a = allocator_type());
49 template <class InputIterator>
50 unordered_set(InputIterator f, InputIterator l,
51 size_type n = 0, const hasher& hf = hasher(),
52 const key_equal& eql = key_equal(),
53 const allocator_type& a = allocator_type());
54 explicit unordered_set(const allocator_type&);
55 unordered_set(const unordered_set&);
56 unordered_set(const unordered_set&, const Allocator&);
57 unordered_set(unordered_set&&);
58 unordered_set(unordered_set&&, const Allocator&);
59 unordered_set(initializer_list<value_type>, size_type n = 0,
60 const hasher& hf = hasher(), const key_equal& eql = key_equal(),
61 const allocator_type& a = allocator_type());
62 ~unordered_set();
63 unordered_set& operator=(const unordered_set&);
64 unordered_set& operator=(unordered_set&&);
65 unordered_set& operator=(initializer_list<value_type>);
66
67 allocator_type get_allocator() const;
68
69 bool empty() const;
70 size_type size() const;
71 size_type max_size() const;
72
73 iterator begin();
74 iterator end();
75 const_iterator begin() const;
76 const_iterator end() const;
77 const_iterator cbegin() const;
78 const_iterator cend() const;
79
80 template <class... Args>
81 pair<iterator, bool> emplace(Args&&... args);
82 template <class... Args>
83 iterator emplace_hint(const_iterator position, Args&&... args);
84 pair<iterator, bool> insert(const value_type& obj);
85 pair<iterator, bool> insert(value_type&& obj);
86 iterator insert(const_iterator hint, const value_type& obj);
87 iterator insert(const_iterator hint, value_type&& obj);
88 template <class InputIterator>
89 void insert(InputIterator first, InputIterator last);
90 void insert(initializer_list<value_type>);
91
92 iterator erase(const_iterator position);
93 size_type erase(const key_type& k);
94 iterator erase(const_iterator first, const_iterator last);
95 void clear();
96
97 void swap(unordered_set&);
98
99 hasher hash_function() const;
100 key_equal key_eq() const;
101
102 iterator find(const key_type& k);
103 const_iterator find(const key_type& k) const;
104 size_type count(const key_type& k) const;
105 pair<iterator, iterator> equal_range(const key_type& k);
106 pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
107
108 size_type bucket_count() const;
109 size_type max_bucket_count() const;
110
111 size_type bucket_size(size_type n) const;
112 size_type bucket(const key_type& k) const;
113
114 local_iterator begin(size_type n);
115 local_iterator end(size_type n);
116 const_local_iterator begin(size_type n) const;
117 const_local_iterator end(size_type n) const;
118 const_local_iterator cbegin(size_type n) const;
119 const_local_iterator cend(size_type n) const;
120
121 float load_factor() const;
122 float max_load_factor() const;
123 void max_load_factor(float z);
124 void rehash(size_type n);
125 void reserve(size_type n);
126};
127
128template <class Value, class Hash, class Pred, class Alloc>
129 void swap(unordered_set<Value, Hash, Pred, Alloc>& x,
130 unordered_set<Value, Hash, Pred, Alloc>& y);
131
132template <class Value, class Hash, class Pred, class Alloc>
133 bool
134 operator==(const unordered_set<Value, Hash, Pred, Alloc>& x,
135 const unordered_set<Value, Hash, Pred, Alloc>& y);
136
137template <class Value, class Hash, class Pred, class Alloc>
138 bool
139 operator!=(const unordered_set<Value, Hash, Pred, Alloc>& x,
140 const unordered_set<Value, Hash, Pred, Alloc>& y);
141
142template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
143 class Alloc = allocator<Value>>
144class unordered_multiset
145{
146public:
147 // types
148 typedef Value key_type;
149 typedef key_type value_type;
150 typedef Hash hasher;
151 typedef Pred key_equal;
152 typedef Alloc allocator_type;
153 typedef value_type& reference;
154 typedef const value_type& const_reference;
155 typedef typename allocator_traits<allocator_type>::pointer pointer;
156 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
157 typedef typename allocator_traits<allocator_type>::size_type size_type;
158 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
159
160 typedef /unspecified/ iterator;
161 typedef /unspecified/ const_iterator;
162 typedef /unspecified/ local_iterator;
163 typedef /unspecified/ const_local_iterator;
164
165 explicit unordered_multiset(size_type n = 0, const hasher& hf = hasher(),
166 const key_equal& eql = key_equal(),
167 const allocator_type& a = allocator_type());
168 template <class InputIterator>
169 unordered_multiset(InputIterator f, InputIterator l,
170 size_type n = 0, const hasher& hf = hasher(),
171 const key_equal& eql = key_equal(),
172 const allocator_type& a = allocator_type());
173 explicit unordered_multiset(const allocator_type&);
174 unordered_multiset(const unordered_multiset&);
175 unordered_multiset(const unordered_multiset&, const Allocator&);
176 unordered_multiset(unordered_multiset&&);
177 unordered_multiset(unordered_multiset&&, const Allocator&);
178 unordered_multiset(initializer_list<value_type>, size_type n = /see below/,
179 const hasher& hf = hasher(), const key_equal& eql = key_equal(),
180 const allocator_type& a = allocator_type());
181 ~unordered_multiset();
182 unordered_multiset& operator=(const unordered_multiset&);
183 unordered_multiset& operator=(unordered_multiset&&);
184 unordered_multiset& operator=(initializer_list<value_type>);
185
186 allocator_type get_allocator() const;
187
188 bool empty() const;
189 size_type size() const;
190 size_type max_size() const;
191
192 iterator begin();
193 iterator end();
194 const_iterator begin() const;
195 const_iterator end() const;
196 const_iterator cbegin() const;
197 const_iterator cend() const;
198
199 template <class... Args>
200 iterator emplace(Args&&... args);
201 template <class... Args>
202 iterator emplace_hint(const_iterator position, Args&&... args);
203 iterator insert(const value_type& obj);
204 iterator insert(value_type&& obj);
205 iterator insert(const_iterator hint, const value_type& obj);
206 iterator insert(const_iterator hint, value_type&& obj);
207 template <class InputIterator>
208 void insert(InputIterator first, InputIterator last);
209 void insert(initializer_list<value_type>);
210
211 iterator erase(const_iterator position);
212 size_type erase(const key_type& k);
213 iterator erase(const_iterator first, const_iterator last);
214 void clear();
215
216 void swap(unordered_multiset&);
217
218 hasher hash_function() const;
219 key_equal key_eq() const;
220
221 iterator find(const key_type& k);
222 const_iterator find(const key_type& k) const;
223 size_type count(const key_type& k) const;
224 pair<iterator, iterator> equal_range(const key_type& k);
225 pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
226
227 size_type bucket_count() const;
228 size_type max_bucket_count() const;
229
230 size_type bucket_size(size_type n) const;
231 size_type bucket(const key_type& k) const;
232
233 local_iterator begin(size_type n);
234 local_iterator end(size_type n);
235 const_local_iterator begin(size_type n) const;
236 const_local_iterator end(size_type n) const;
237 const_local_iterator cbegin(size_type n) const;
238 const_local_iterator cend(size_type n) const;
239
240 float load_factor() const;
241 float max_load_factor() const;
242 void max_load_factor(float z);
243 void rehash(size_type n);
244 void reserve(size_type n);
245};
246
247template <class Value, class Hash, class Pred, class Alloc>
248 void swap(unordered_multiset<Value, Hash, Pred, Alloc>& x,
249 unordered_multiset<Value, Hash, Pred, Alloc>& y);
250
251template <class Value, class Hash, class Pred, class Alloc>
252 bool
253 operator==(const unordered_multiset<Value, Hash, Pred, Alloc>& x,
254 const unordered_multiset<Value, Hash, Pred, Alloc>& y);
255
256template <class Value, class Hash, class Pred, class Alloc>
257 bool
258 operator!=(const unordered_multiset<Value, Hash, Pred, Alloc>& x,
259 const unordered_multiset<Value, Hash, Pred, Alloc>& y);
260} // std
261
262*/
263
264#include <__config>
265#include <__hash_table>
266#include <functional>
267
268#pragma GCC system_header
269
270_LIBCPP_BEGIN_NAMESPACE_STD
271
272template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
273 class _Alloc = allocator<_Value> >
274class unordered_set
275{
276public:
277 // types
278 typedef _Value key_type;
279 typedef key_type value_type;
280 typedef _Hash hasher;
281 typedef _Pred key_equal;
282 typedef _Alloc allocator_type;
283 typedef value_type& reference;
284 typedef const value_type& const_reference;
285
286private:
287 typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
288
289 __table __table_;
290
291public:
292 typedef typename __table::pointer pointer;
293 typedef typename __table::const_pointer const_pointer;
294 typedef typename __table::size_type size_type;
295 typedef typename __table::difference_type difference_type;
296
297 typedef typename __table::const_iterator iterator;
298 typedef typename __table::const_iterator const_iterator;
299 typedef typename __table::const_local_iterator local_iterator;
300 typedef typename __table::const_local_iterator const_local_iterator;
301
302 unordered_set() {} // = default;
303 explicit unordered_set(size_type __n, const hasher& __hf = hasher(),
304 const key_equal& __eql = key_equal());
305 unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql,
306 const allocator_type& __a);
307 template <class _InputIterator>
308 unordered_set(_InputIterator __first, _InputIterator __last);
309 template <class _InputIterator>
310 unordered_set(_InputIterator __first, _InputIterator __last,
311 size_type __n, const hasher& __hf = hasher(),
312 const key_equal& __eql = key_equal());
313 template <class _InputIterator>
314 unordered_set(_InputIterator __first, _InputIterator __last,
315 size_type __n, const hasher& __hf, const key_equal& __eql,
316 const allocator_type& __a);
317 explicit unordered_set(const allocator_type& __a);
318 unordered_set(const unordered_set& __u);
319 unordered_set(const unordered_set& __u, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000320#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000321 unordered_set(unordered_set&& __u);
322 unordered_set(unordered_set&& __u, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000323#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000324 unordered_set(initializer_list<value_type> __il);
325 unordered_set(initializer_list<value_type> __il, size_type __n,
326 const hasher& __hf = hasher(),
327 const key_equal& __eql = key_equal());
328 unordered_set(initializer_list<value_type> __il, size_type __n,
329 const hasher& __hf, const key_equal& __eql,
330 const allocator_type& __a);
331 // ~unordered_set() = default;
332 // unordered_set& operator=(const unordered_set& __u) = default;
Howard Hinnant73d21a42010-09-04 23:28:19 +0000333#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000334 unordered_set& operator=(unordered_set&& __u);
335#endif
336 unordered_set& operator=(initializer_list<value_type> __il);
337
338 allocator_type get_allocator() const
339 {return allocator_type(__table_.__node_alloc());}
340
341 bool empty() const {return __table_.size() == 0;}
342 size_type size() const {return __table_.size();}
343 size_type max_size() const {return __table_.max_size();}
344
345 iterator begin() {return __table_.begin();}
346 iterator end() {return __table_.end();}
347 const_iterator begin() const {return __table_.begin();}
348 const_iterator end() const {return __table_.end();}
349 const_iterator cbegin() const {return __table_.begin();}
350 const_iterator cend() const {return __table_.end();}
351
Howard Hinnant73d21a42010-09-04 23:28:19 +0000352#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000353 template <class... _Args>
354 pair<iterator, bool> emplace(_Args&&... __args)
355 {return __table_.__emplace_unique(_STD::forward<_Args>(__args)...);}
356 template <class... _Args>
357 iterator emplace_hint(const_iterator, _Args&&... __args)
358 {return __table_.__emplace_unique(_STD::forward<_Args>(__args)...).first;}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000359#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000360 pair<iterator, bool> insert(const value_type& __x)
361 {return __table_.__insert_unique(__x);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000362#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000363 pair<iterator, bool> insert(value_type&& __x)
364 {return __table_.__insert_unique(_STD::move(__x));}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000365#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000366 iterator insert(const_iterator, const value_type& __x)
367 {return insert(__x).first;}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000368#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000369 iterator insert(const_iterator, value_type&& __x)
370 {return insert(_STD::move(__x)).first;}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000371#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000372 template <class _InputIterator>
373 void insert(_InputIterator __first, _InputIterator __last);
374 void insert(initializer_list<value_type> __il)
375 {insert(__il.begin(), __il.end());}
376
377 iterator erase(const_iterator __p) {return __table_.erase(__p);}
378 size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
379 iterator erase(const_iterator __first, const_iterator __last)
380 {return __table_.erase(__first, __last);}
381 void clear() {__table_.clear();}
382
383 void swap(unordered_set& __u) {__table_.swap(__u.__table_);}
384
385 hasher hash_function() const {return __table_.hash_function();}
386 key_equal key_eq() const {return __table_.key_eq();}
387
388 iterator find(const key_type& __k) {return __table_.find(__k);}
389 const_iterator find(const key_type& __k) const {return __table_.find(__k);}
390 size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
391 pair<iterator, iterator> equal_range(const key_type& __k)
392 {return __table_.__equal_range_unique(__k);}
393 pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
394 {return __table_.__equal_range_unique(__k);}
395
396 size_type bucket_count() const {return __table_.bucket_count();}
397 size_type max_bucket_count() const {return __table_.max_bucket_count();}
398
399 size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);}
400 size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
401
402 local_iterator begin(size_type __n) {return __table_.begin(__n);}
403 local_iterator end(size_type __n) {return __table_.end(__n);}
404 const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);}
405 const_local_iterator end(size_type __n) const {return __table_.cend(__n);}
406 const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
407 const_local_iterator cend(size_type __n) const {return __table_.cend(__n);}
408
409 float load_factor() const {return __table_.load_factor();}
410 float max_load_factor() const {return __table_.max_load_factor();}
411 void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
412 void rehash(size_type __n) {__table_.rehash(__n);}
413 void reserve(size_type __n) {__table_.reserve(__n);}
414};
415
416template <class _Value, class _Hash, class _Pred, class _Alloc>
417unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
418 const hasher& __hf, const key_equal& __eql)
419 : __table_(__hf, __eql)
420{
421 __table_.rehash(__n);
422}
423
424template <class _Value, class _Hash, class _Pred, class _Alloc>
425unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
426 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
427 : __table_(__hf, __eql, __a)
428{
429 __table_.rehash(__n);
430}
431
432template <class _Value, class _Hash, class _Pred, class _Alloc>
433template <class _InputIterator>
434unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
435 _InputIterator __first, _InputIterator __last)
436{
437 insert(__first, __last);
438}
439
440template <class _Value, class _Hash, class _Pred, class _Alloc>
441template <class _InputIterator>
442unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
443 _InputIterator __first, _InputIterator __last, size_type __n,
444 const hasher& __hf, const key_equal& __eql)
445 : __table_(__hf, __eql)
446{
447 __table_.rehash(__n);
448 insert(__first, __last);
449}
450
451template <class _Value, class _Hash, class _Pred, class _Alloc>
452template <class _InputIterator>
453unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
454 _InputIterator __first, _InputIterator __last, size_type __n,
455 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
456 : __table_(__hf, __eql, __a)
457{
458 __table_.rehash(__n);
459 insert(__first, __last);
460}
461
462template <class _Value, class _Hash, class _Pred, class _Alloc>
463inline
464unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
465 const allocator_type& __a)
466 : __table_(__a)
467{
468}
469
470template <class _Value, class _Hash, class _Pred, class _Alloc>
471unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
472 const unordered_set& __u)
473 : __table_(__u.__table_)
474{
475 __table_.rehash(__u.bucket_count());
476 insert(__u.begin(), __u.end());
477}
478
479template <class _Value, class _Hash, class _Pred, class _Alloc>
480unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
481 const unordered_set& __u, const allocator_type& __a)
482 : __table_(__u.__table_, __a)
483{
484 __table_.rehash(__u.bucket_count());
485 insert(__u.begin(), __u.end());
486}
487
Howard Hinnant73d21a42010-09-04 23:28:19 +0000488#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000489
490template <class _Value, class _Hash, class _Pred, class _Alloc>
491inline
492unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
493 unordered_set&& __u)
494 : __table_(_STD::move(__u.__table_))
495{
496}
497
498template <class _Value, class _Hash, class _Pred, class _Alloc>
499unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
500 unordered_set&& __u, const allocator_type& __a)
501 : __table_(_STD::move(__u.__table_), __a)
502{
503 if (__a != __u.get_allocator())
504 {
505 iterator __i = __u.begin();
506 while (__u.size() != 0)
507 __table_.__insert_unique(_STD::move(__u.__table_.remove(__i++)->__value_));
508 }
509}
510
Howard Hinnant73d21a42010-09-04 23:28:19 +0000511#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000512
513template <class _Value, class _Hash, class _Pred, class _Alloc>
514unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
515 initializer_list<value_type> __il)
516{
517 insert(__il.begin(), __il.end());
518}
519
520template <class _Value, class _Hash, class _Pred, class _Alloc>
521unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
522 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
523 const key_equal& __eql)
524 : __table_(__hf, __eql)
525{
526 __table_.rehash(__n);
527 insert(__il.begin(), __il.end());
528}
529
530template <class _Value, class _Hash, class _Pred, class _Alloc>
531unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
532 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
533 const key_equal& __eql, const allocator_type& __a)
534 : __table_(__hf, __eql, __a)
535{
536 __table_.rehash(__n);
537 insert(__il.begin(), __il.end());
538}
539
Howard Hinnant73d21a42010-09-04 23:28:19 +0000540#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000541
542template <class _Value, class _Hash, class _Pred, class _Alloc>
543inline
544unordered_set<_Value, _Hash, _Pred, _Alloc>&
545unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u)
546{
547 __table_ = _STD::move(__u.__table_);
548 return *this;
549}
550
Howard Hinnant73d21a42010-09-04 23:28:19 +0000551#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000552
553template <class _Value, class _Hash, class _Pred, class _Alloc>
554inline
555unordered_set<_Value, _Hash, _Pred, _Alloc>&
556unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(
557 initializer_list<value_type> __il)
558{
559 __table_.__assign_unique(__il.begin(), __il.end());
560 return *this;
561}
562
563template <class _Value, class _Hash, class _Pred, class _Alloc>
564template <class _InputIterator>
565inline
566void
567unordered_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
568 _InputIterator __last)
569{
570 for (; __first != __last; ++__first)
571 __table_.__insert_unique(*__first);
572}
573
574template <class _Value, class _Hash, class _Pred, class _Alloc>
575inline
576void
577swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
578 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
579{
580 __x.swap(__y);
581}
582
583template <class _Value, class _Hash, class _Pred, class _Alloc>
584bool
585operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
586 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
587{
588 if (__x.size() != __y.size())
589 return false;
590 typedef typename unordered_set<_Value, _Hash, _Pred, _Alloc>::const_iterator
591 const_iterator;
592 for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
593 __i != __ex; ++__i)
594 {
595 const_iterator __j = __y.find(*__i);
596 if (__j == __ey || !(*__i == *__j))
597 return false;
598 }
599 return true;
600}
601
602template <class _Value, class _Hash, class _Pred, class _Alloc>
603inline
604bool
605operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
606 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
607{
608 return !(__x == __y);
609}
610
611template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
612 class _Alloc = allocator<_Value> >
613class unordered_multiset
614{
615public:
616 // types
617 typedef _Value key_type;
618 typedef key_type value_type;
619 typedef _Hash hasher;
620 typedef _Pred key_equal;
621 typedef _Alloc allocator_type;
622 typedef value_type& reference;
623 typedef const value_type& const_reference;
624
625private:
626 typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
627
628 __table __table_;
629
630public:
631 typedef typename __table::pointer pointer;
632 typedef typename __table::const_pointer const_pointer;
633 typedef typename __table::size_type size_type;
634 typedef typename __table::difference_type difference_type;
635
636 typedef typename __table::const_iterator iterator;
637 typedef typename __table::const_iterator const_iterator;
638 typedef typename __table::const_local_iterator local_iterator;
639 typedef typename __table::const_local_iterator const_local_iterator;
640
641 unordered_multiset() {} // = default
642 explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(),
643 const key_equal& __eql = key_equal());
644 unordered_multiset(size_type __n, const hasher& __hf,
645 const key_equal& __eql, const allocator_type& __a);
646 template <class _InputIterator>
647 unordered_multiset(_InputIterator __first, _InputIterator __last);
648 template <class _InputIterator>
649 unordered_multiset(_InputIterator __first, _InputIterator __last,
650 size_type __n, const hasher& __hf = hasher(),
651 const key_equal& __eql = key_equal());
652 template <class _InputIterator>
653 unordered_multiset(_InputIterator __first, _InputIterator __last,
654 size_type __n , const hasher& __hf,
655 const key_equal& __eql, const allocator_type& __a);
656 explicit unordered_multiset(const allocator_type& __a);
657 unordered_multiset(const unordered_multiset& __u);
658 unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000659#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000660 unordered_multiset(unordered_multiset&& __u);
661 unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000662#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000663 unordered_multiset(initializer_list<value_type> __il);
664 unordered_multiset(initializer_list<value_type> __il, size_type __n,
665 const hasher& __hf = hasher(),
666 const key_equal& __eql = key_equal());
667 unordered_multiset(initializer_list<value_type> __il, size_type __n,
668 const hasher& __hf, const key_equal& __eql,
669 const allocator_type& __a);
670 // ~unordered_multiset() = default;
671 // unordered_multiset& operator=(const unordered_multiset& __u) = default;
Howard Hinnant73d21a42010-09-04 23:28:19 +0000672#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000673 unordered_multiset& operator=(unordered_multiset&& __u);
674#endif
675 unordered_multiset& operator=(initializer_list<value_type> __il);
676
677 allocator_type get_allocator() const
678 {return allocator_type(__table_.__node_alloc());}
679
680 bool empty() const {return __table_.size() == 0;}
681 size_type size() const {return __table_.size();}
682 size_type max_size() const {return __table_.max_size();}
683
684 iterator begin() {return __table_.begin();}
685 iterator end() {return __table_.end();}
686 const_iterator begin() const {return __table_.begin();}
687 const_iterator end() const {return __table_.end();}
688 const_iterator cbegin() const {return __table_.begin();}
689 const_iterator cend() const {return __table_.end();}
690
Howard Hinnant73d21a42010-09-04 23:28:19 +0000691#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000692 template <class... _Args>
693 iterator emplace(_Args&&... __args)
694 {return __table_.__emplace_multi(_STD::forward<_Args>(__args)...);}
695 template <class... _Args>
696 iterator emplace_hint(const_iterator __p, _Args&&... __args)
697 {return __table_.__emplace_hint_multi(__p, _STD::forward<_Args>(__args)...);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000698#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000699 iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000700#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000701 iterator insert(value_type&& __x) {return __table_.__insert_multi(_STD::move(__x));}
702#endif
703 iterator insert(const_iterator __p, const value_type& __x)
704 {return __table_.__insert_multi(__p, __x);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000705#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000706 iterator insert(const_iterator __p, value_type&& __x)
707 {return __table_.__insert_multi(__p, _STD::move(__x));}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000708#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000709 template <class _InputIterator>
710 void insert(_InputIterator __first, _InputIterator __last);
711 void insert(initializer_list<value_type> __il)
712 {insert(__il.begin(), __il.end());}
713
714 iterator erase(const_iterator __p) {return __table_.erase(__p);}
715 size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
716 iterator erase(const_iterator __first, const_iterator __last)
717 {return __table_.erase(__first, __last);}
718 void clear() {__table_.clear();}
719
720 void swap(unordered_multiset& __u) {__table_.swap(__u.__table_);}
721
722 hasher hash_function() const {return __table_.hash_function();}
723 key_equal key_eq() const {return __table_.key_eq();}
724
725 iterator find(const key_type& __k) {return __table_.find(__k);}
726 const_iterator find(const key_type& __k) const {return __table_.find(__k);}
727 size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
728 pair<iterator, iterator> equal_range(const key_type& __k)
729 {return __table_.__equal_range_multi(__k);}
730 pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
731 {return __table_.__equal_range_multi(__k);}
732
733 size_type bucket_count() const {return __table_.bucket_count();}
734 size_type max_bucket_count() const {return __table_.max_bucket_count();}
735
736 size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);}
737 size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
738
739 local_iterator begin(size_type __n) {return __table_.begin(__n);}
740 local_iterator end(size_type __n) {return __table_.end(__n);}
741 const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);}
742 const_local_iterator end(size_type __n) const {return __table_.cend(__n);}
743 const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
744 const_local_iterator cend(size_type __n) const {return __table_.cend(__n);}
745
746 float load_factor() const {return __table_.load_factor();}
747 float max_load_factor() const {return __table_.max_load_factor();}
748 void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
749 void rehash(size_type __n) {__table_.rehash(__n);}
750 void reserve(size_type __n) {__table_.reserve(__n);}
751};
752
753template <class _Value, class _Hash, class _Pred, class _Alloc>
754unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
755 size_type __n, const hasher& __hf, const key_equal& __eql)
756 : __table_(__hf, __eql)
757{
758 __table_.rehash(__n);
759}
760
761template <class _Value, class _Hash, class _Pred, class _Alloc>
762unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
763 size_type __n, const hasher& __hf, const key_equal& __eql,
764 const allocator_type& __a)
765 : __table_(__hf, __eql, __a)
766{
767 __table_.rehash(__n);
768}
769
770template <class _Value, class _Hash, class _Pred, class _Alloc>
771template <class _InputIterator>
772unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
773 _InputIterator __first, _InputIterator __last)
774{
775 insert(__first, __last);
776}
777
778template <class _Value, class _Hash, class _Pred, class _Alloc>
779template <class _InputIterator>
780unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
781 _InputIterator __first, _InputIterator __last, size_type __n,
782 const hasher& __hf, const key_equal& __eql)
783 : __table_(__hf, __eql)
784{
785 __table_.rehash(__n);
786 insert(__first, __last);
787}
788
789template <class _Value, class _Hash, class _Pred, class _Alloc>
790template <class _InputIterator>
791unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
792 _InputIterator __first, _InputIterator __last, size_type __n,
793 const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
794 : __table_(__hf, __eql, __a)
795{
796 __table_.rehash(__n);
797 insert(__first, __last);
798}
799
800template <class _Value, class _Hash, class _Pred, class _Alloc>
801inline
802unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
803 const allocator_type& __a)
804 : __table_(__a)
805{
806}
807
808template <class _Value, class _Hash, class _Pred, class _Alloc>
809unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
810 const unordered_multiset& __u)
811 : __table_(__u.__table_)
812{
813 __table_.rehash(__u.bucket_count());
814 insert(__u.begin(), __u.end());
815}
816
817template <class _Value, class _Hash, class _Pred, class _Alloc>
818unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
819 const unordered_multiset& __u, const allocator_type& __a)
820 : __table_(__u.__table_, __a)
821{
822 __table_.rehash(__u.bucket_count());
823 insert(__u.begin(), __u.end());
824}
825
Howard Hinnant73d21a42010-09-04 23:28:19 +0000826#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000827
828template <class _Value, class _Hash, class _Pred, class _Alloc>
829inline
830unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
831 unordered_multiset&& __u)
832 : __table_(_STD::move(__u.__table_))
833{
834}
835
836template <class _Value, class _Hash, class _Pred, class _Alloc>
837unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
838 unordered_multiset&& __u, const allocator_type& __a)
839 : __table_(_STD::move(__u.__table_), __a)
840{
841 if (__a != __u.get_allocator())
842 {
843 iterator __i = __u.begin();
844 while (__u.size() != 0)
845 __table_.__insert_multi(_STD::move(__u.__table_.remove(__i++)->__value_));
846 }
847}
848
Howard Hinnant73d21a42010-09-04 23:28:19 +0000849#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000850
851template <class _Value, class _Hash, class _Pred, class _Alloc>
852unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
853 initializer_list<value_type> __il)
854{
855 insert(__il.begin(), __il.end());
856}
857
858template <class _Value, class _Hash, class _Pred, class _Alloc>
859unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
860 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
861 const key_equal& __eql)
862 : __table_(__hf, __eql)
863{
864 __table_.rehash(__n);
865 insert(__il.begin(), __il.end());
866}
867
868template <class _Value, class _Hash, class _Pred, class _Alloc>
869unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
870 initializer_list<value_type> __il, size_type __n, const hasher& __hf,
871 const key_equal& __eql, const allocator_type& __a)
872 : __table_(__hf, __eql, __a)
873{
874 __table_.rehash(__n);
875 insert(__il.begin(), __il.end());
876}
877
Howard Hinnant73d21a42010-09-04 23:28:19 +0000878#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000879
880template <class _Value, class _Hash, class _Pred, class _Alloc>
881inline
882unordered_multiset<_Value, _Hash, _Pred, _Alloc>&
883unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(
884 unordered_multiset&& __u)
885{
886 __table_ = _STD::move(__u.__table_);
887 return *this;
888}
889
Howard Hinnant73d21a42010-09-04 23:28:19 +0000890#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000891
892template <class _Value, class _Hash, class _Pred, class _Alloc>
893inline
894unordered_multiset<_Value, _Hash, _Pred, _Alloc>&
895unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(
896 initializer_list<value_type> __il)
897{
898 __table_.__assign_multi(__il.begin(), __il.end());
899 return *this;
900}
901
902template <class _Value, class _Hash, class _Pred, class _Alloc>
903template <class _InputIterator>
904inline
905void
906unordered_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
907 _InputIterator __last)
908{
909 for (; __first != __last; ++__first)
910 __table_.__insert_multi(*__first);
911}
912
913template <class _Value, class _Hash, class _Pred, class _Alloc>
914inline
915void
916swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
917 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
918{
919 __x.swap(__y);
920}
921
922template <class _Value, class _Hash, class _Pred, class _Alloc>
923bool
924operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
925 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
926{
927 if (__x.size() != __y.size())
928 return false;
929 typedef typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator
930 const_iterator;
931 typedef pair<const_iterator, const_iterator> _EqRng;
932 for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
933 {
934 _EqRng __xeq = __x.equal_range(*__i);
935 _EqRng __yeq = __y.equal_range(*__i);
936 if (_STD::distance(__xeq.first, __xeq.second) !=
937 _STD::distance(__yeq.first, __yeq.second) ||
938 !_STD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
939 return false;
940 __i = __xeq.second;
941 }
942 return true;
943}
944
945template <class _Value, class _Hash, class _Pred, class _Alloc>
946inline
947bool
948operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
949 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
950{
951 return !(__x == __y);
952}
953
954_LIBCPP_END_NAMESPACE_STD
955
956#endif // _LIBCPP_UNORDERED_SET