blob: 110f599f62f528941953401dbbf446c5cec27a69 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===---------------------------- 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_SET
12#define _LIBCPP_SET
13
14/*
15
16 set synopsis
17
18namespace std
19{
20
21template <class Key, class Compare = less<Key>,
22 class Allocator = allocator<Key>>
23class set
24{
25public:
26 // types:
27 typedef Key key_type;
28 typedef key_type value_type;
29 typedef Compare key_compare;
30 typedef key_compare value_compare;
31 typedef Allocator allocator_type;
32 typedef typename allocator_type::reference reference;
33 typedef typename allocator_type::const_reference const_reference;
34 typedef typename allocator_type::size_type size_type;
35 typedef typename allocator_type::difference_type difference_type;
36 typedef typename allocator_type::pointer pointer;
37 typedef typename allocator_type::const_pointer const_pointer;
38
39 typedef implementation-defined iterator;
40 typedef implementation-defined const_iterator;
41 typedef std::reverse_iterator<iterator> reverse_iterator;
42 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
43
44 // construct/copy/destroy:
45 explicit set(const value_compare& comp = value_compare());
46 set(const value_compare& comp, const allocator_type& a);
47 template <class InputIterator>
48 set(InputIterator first, InputIterator last,
49 const value_compare& comp = value_compare());
50 template <class InputIterator>
51 set(InputIterator first, InputIterator last, const value_compare& comp,
52 const allocator_type& a);
53 set(const set& s);
54 set(set&& s);
55 explicit set(const allocator_type& a);
56 set(const set& s, const allocator_type& a);
57 set(set&& s, const allocator_type& a);
58 set(initializer_list<value_type> il, const value_compare& comp = value_compare());
59 set(initializer_list<value_type> il, const value_compare& comp,
60 const allocator_type& a);
61 ~set();
62
63 set& operator=(const set& s);
64 set& operator=(set&& s);
65 set& operator=(initializer_list<value_type> il);
66
67 // iterators:
68 iterator begin();
69 const_iterator begin() const;
70 iterator end();
71 const_iterator end() const;
72
73 reverse_iterator rbegin();
74 const_reverse_iterator rbegin() const;
75 reverse_iterator rend();
76 const_reverse_iterator rend() const;
77
78 const_iterator cbegin() const;
79 const_iterator cend() const;
80 const_reverse_iterator crbegin() const;
81 const_reverse_iterator crend() const;
82
83 // capacity:
84 bool empty() const;
85 size_type size() const;
86 size_type max_size() const;
87
88 // modifiers:
89 template <class... Args>
90 pair<iterator, bool> emplace(Args&&... args);
91 template <class... Args>
92 iterator emplace_hint(const_iterator position, Args&&... args);
93 pair<iterator,bool> insert(const value_type& v);
94 pair<iterator,bool> insert(value_type&& v);
95 iterator insert(const_iterator position, const value_type& v);
96 iterator insert(const_iterator position, value_type&& v);
97 template <class InputIterator>
98 void insert(InputIterator first, InputIterator last);
99 void insert(initializer_list<value_type> il);
100
101 iterator erase(const_iterator position);
102 size_type erase(const key_type& k);
103 iterator erase(const_iterator first, const_iterator last);
104 void clear();
105
106 void swap(set& s);
107
108 // observers:
109 allocator_type get_allocator() const;
110 key_compare key_comp() const;
111 value_compare value_comp() const;
112
113 // set operations:
114 iterator find(const key_type& k);
115 const_iterator find(const key_type& k) const;
116 size_type count(const key_type& k) const;
117 iterator lower_bound(const key_type& k);
118 const_iterator lower_bound(const key_type& k) const;
119 iterator upper_bound(const key_type& k);
120 const_iterator upper_bound(const key_type& k) const;
121 pair<iterator,iterator> equal_range(const key_type& k);
122 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
123};
124
125template <class Key, class Compare, class Allocator>
126bool
127operator==(const set<Key, Compare, Allocator>& x,
128 const set<Key, Compare, Allocator>& y);
129
130template <class Key, class Compare, class Allocator>
131bool
132operator< (const set<Key, Compare, Allocator>& x,
133 const set<Key, Compare, Allocator>& y);
134
135template <class Key, class Compare, class Allocator>
136bool
137operator!=(const set<Key, Compare, Allocator>& x,
138 const set<Key, Compare, Allocator>& y);
139
140template <class Key, class Compare, class Allocator>
141bool
142operator> (const set<Key, Compare, Allocator>& x,
143 const set<Key, Compare, Allocator>& y);
144
145template <class Key, class Compare, class Allocator>
146bool
147operator>=(const set<Key, Compare, Allocator>& x,
148 const set<Key, Compare, Allocator>& y);
149
150template <class Key, class Compare, class Allocator>
151bool
152operator<=(const set<Key, Compare, Allocator>& x,
153 const set<Key, Compare, Allocator>& y);
154
155// specialized algorithms:
156template <class Key, class Compare, class Allocator>
157void
158swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y);
159
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000160template <class Key, class Compare = less<Key>,
161 class Allocator = allocator<Key>>
162class multiset
163{
164public:
165 // types:
166 typedef Key key_type;
167 typedef key_type value_type;
168 typedef Compare key_compare;
169 typedef key_compare value_compare;
170 typedef Allocator allocator_type;
171 typedef typename allocator_type::reference reference;
172 typedef typename allocator_type::const_reference const_reference;
173 typedef typename allocator_type::size_type size_type;
174 typedef typename allocator_type::difference_type difference_type;
175 typedef typename allocator_type::pointer pointer;
176 typedef typename allocator_type::const_pointer const_pointer;
177
178 typedef implementation-defined iterator;
179 typedef implementation-defined const_iterator;
180 typedef std::reverse_iterator<iterator> reverse_iterator;
181 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
182
183 // construct/copy/destroy:
184 explicit multiset(const value_compare& comp = value_compare());
185 multiset(const value_compare& comp, const allocator_type& a);
186 template <class InputIterator>
187 multiset(InputIterator first, InputIterator last,
188 const value_compare& comp = value_compare());
189 template <class InputIterator>
190 multiset(InputIterator first, InputIterator last,
191 const value_compare& comp, const allocator_type& a);
192 multiset(const multiset& s);
193 multiset(multiset&& s);
194 explicit multiset(const allocator_type& a);
195 multiset(const multiset& s, const allocator_type& a);
196 multiset(multiset&& s, const allocator_type& a);
197 multiset(initializer_list<value_type> il, const value_compare& comp = value_compare());
198 multiset(initializer_list<value_type> il, const value_compare& comp,
199 const allocator_type& a);
200 ~multiset();
201
202 multiset& operator=(const multiset& s);
203 multiset& operator=(multiset&& s);
204 multiset& operator=(initializer_list<value_type> il);
205
206 // iterators:
207 iterator begin();
208 const_iterator begin() const;
209 iterator end();
210 const_iterator end() const;
211
212 reverse_iterator rbegin();
213 const_reverse_iterator rbegin() const;
214 reverse_iterator rend();
215 const_reverse_iterator rend() const;
216
217 const_iterator cbegin() const;
218 const_iterator cend() const;
219 const_reverse_iterator crbegin() const;
220 const_reverse_iterator crend() const;
221
222 // capacity:
223 bool empty() const;
224 size_type size() const;
225 size_type max_size() const;
226
227 // modifiers:
228 template <class... Args>
229 iterator emplace(Args&&... args);
230 template <class... Args>
231 iterator emplace_hint(const_iterator position, Args&&... args);
232 iterator insert(const value_type& v);
233 iterator insert(value_type&& v);
234 iterator insert(const_iterator position, const value_type& v);
235 iterator insert(const_iterator position, value_type&& v);
236 template <class InputIterator>
237 void insert(InputIterator first, InputIterator last);
238 void insert(initializer_list<value_type> il);
239
240 iterator erase(const_iterator position);
241 size_type erase(const key_type& k);
242 iterator erase(const_iterator first, const_iterator last);
243 void clear();
244
245 void swap(multiset& s);
246
247 // observers:
248 allocator_type get_allocator() const;
249 key_compare key_comp() const;
250 value_compare value_comp() const;
251
252 // set operations:
253 iterator find(const key_type& k);
254 const_iterator find(const key_type& k) const;
255 size_type count(const key_type& k) const;
256 iterator lower_bound(const key_type& k);
257 const_iterator lower_bound(const key_type& k) const;
258 iterator upper_bound(const key_type& k);
259 const_iterator upper_bound(const key_type& k) const;
260 pair<iterator,iterator> equal_range(const key_type& k);
261 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
262};
263
264template <class Key, class Compare, class Allocator>
265bool
266operator==(const multiset<Key, Compare, Allocator>& x,
267 const multiset<Key, Compare, Allocator>& y);
268
269template <class Key, class Compare, class Allocator>
270bool
271operator< (const multiset<Key, Compare, Allocator>& x,
272 const multiset<Key, Compare, Allocator>& y);
273
274template <class Key, class Compare, class Allocator>
275bool
276operator!=(const multiset<Key, Compare, Allocator>& x,
277 const multiset<Key, Compare, Allocator>& y);
278
279template <class Key, class Compare, class Allocator>
280bool
281operator> (const multiset<Key, Compare, Allocator>& x,
282 const multiset<Key, Compare, Allocator>& y);
283
284template <class Key, class Compare, class Allocator>
285bool
286operator>=(const multiset<Key, Compare, Allocator>& x,
287 const multiset<Key, Compare, Allocator>& y);
288
289template <class Key, class Compare, class Allocator>
290bool
291operator<=(const multiset<Key, Compare, Allocator>& x,
292 const multiset<Key, Compare, Allocator>& y);
293
294// specialized algorithms:
295template <class Key, class Compare, class Allocator>
296void
297swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y);
298
299} // std
300
301*/
302
303#include <__config>
304#include <__tree>
305#include <functional>
306
307#pragma GCC system_header
308
309_LIBCPP_BEGIN_NAMESPACE_STD
310
311template <class _Key, class _Compare = less<_Key>,
312 class _Allocator = allocator<_Key> >
313class set
314{
315public:
316 // types:
317 typedef _Key key_type;
318 typedef key_type value_type;
319 typedef _Compare key_compare;
320 typedef key_compare value_compare;
321 typedef _Allocator allocator_type;
322 typedef value_type& reference;
323 typedef const value_type& const_reference;
324
325private:
326 typedef __tree<value_type, value_compare, allocator_type> __base;
327 typedef allocator_traits<allocator_type> __alloc_traits;
328 typedef typename __base::__node_holder __node_holder;
329
330 __base __tree_;
331
332public:
333 typedef typename __base::pointer pointer;
334 typedef typename __base::const_pointer const_pointer;
335 typedef typename __base::size_type size_type;
336 typedef typename __base::difference_type difference_type;
337 typedef typename __base::const_iterator iterator;
338 typedef typename __base::const_iterator const_iterator;
339 typedef _STD::reverse_iterator<iterator> reverse_iterator;
340 typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
341
342 explicit set(const value_compare& __comp = value_compare())
343 : __tree_(__comp) {}
344 set(const value_compare& __comp, const allocator_type& __a)
345 : __tree_(__comp, __a) {}
346 template <class _InputIterator>
347 set(_InputIterator __f, _InputIterator __l,
348 const value_compare& __comp = value_compare())
349 : __tree_(__comp)
350 {
351 insert(__f, __l);
352 }
353
354 template <class _InputIterator>
355 set(_InputIterator __f, _InputIterator __l, const value_compare& __comp,
356 const allocator_type& __a)
357 : __tree_(__comp, __a)
358 {
359 insert(__f, __l);
360 }
361
362 set(const set& __s)
363 : __tree_(__s.__tree_)
364 {
365 insert(__s.begin(), __s.end());
366 }
367
Howard Hinnant73d21a42010-09-04 23:28:19 +0000368#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000369 set(set&& __s)
370 : __tree_(_STD::move(__s.__tree_)) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000371#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000372
373 explicit set(const allocator_type& __a)
374 : __tree_(__a) {}
375
376 set(const set& __s, const allocator_type& __a)
377 : __tree_(__s.__tree_.value_comp(), __a)
378 {
379 insert(__s.begin(), __s.end());
380 }
381
Howard Hinnant73d21a42010-09-04 23:28:19 +0000382#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000383 set(set&& __s, const allocator_type& __a);
384#endif
385
386 set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
387 : __tree_(__comp)
388 {
389 insert(__il.begin(), __il.end());
390 }
391
392 set(initializer_list<value_type> __il, const value_compare& __comp,
393 const allocator_type& __a)
394 : __tree_(__comp, __a)
395 {
396 insert(__il.begin(), __il.end());
397 }
398
399 set& operator=(initializer_list<value_type> __il)
400 {
401 __tree_.__assign_unique(__il.begin(), __il.end());
402 return *this;
403 }
404
Howard Hinnant73d21a42010-09-04 23:28:19 +0000405#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000406 set& operator=(set&& __s)
407 {
408 __tree_ = _STD::move(__s.__tree_);
409 return *this;
410 }
Howard Hinnant73d21a42010-09-04 23:28:19 +0000411#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000412
413 iterator begin() {return __tree_.begin();}
414 const_iterator begin() const {return __tree_.begin();}
415 iterator end() {return __tree_.end();}
416 const_iterator end() const {return __tree_.end();}
417
418 reverse_iterator rbegin() {return reverse_iterator(end());}
419 const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
420 reverse_iterator rend() {return reverse_iterator(begin());}
421 const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
422
423 const_iterator cbegin() const {return begin();}
424 const_iterator cend() const {return end();}
425 const_reverse_iterator crbegin() const {return rbegin();}
426 const_reverse_iterator crend() const {return rend();}
427
428 bool empty() const {return __tree_.size() == 0;}
429 size_type size() const {return __tree_.size();}
430 size_type max_size() const {return __tree_.max_size();}
431
432 // modifiers:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000433#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000434 template <class... _Args>
435 pair<iterator, bool> emplace(_Args&&... __args)
436 {return __tree_.__emplace_unique(_STD::forward<_Args>(__args)...);}
437 template <class... _Args>
438 iterator emplace_hint(const_iterator __p, _Args&&... __args)
439 {return __tree_.__emplace_hint_unique(__p, _STD::forward<_Args>(__args)...);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000440#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000441 pair<iterator,bool> insert(const value_type& __v)
442 {return __tree_.__insert_unique(__v);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000443#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000444 pair<iterator,bool> insert(value_type&& __v)
445 {return __tree_.__insert_unique(_STD::move(__v));}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000446#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000447 iterator insert(const_iterator __p, const value_type& __v)
448 {return __tree_.__insert_unique(__p, __v);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000449#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000450 iterator insert(const_iterator __p, value_type&& __v)
451 {return __tree_.__insert_unique(__p, _STD::move(__v));}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000452#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000453 template <class _InputIterator>
454 void insert(_InputIterator __f, _InputIterator __l)
455 {
456 for (const_iterator __e = cend(); __f != __l; ++__f)
457 __tree_.__insert_unique(__e, *__f);
458 }
459
460 void insert(initializer_list<value_type> __il)
461 {insert(__il.begin(), __il.end());}
462
463 iterator erase(const_iterator __p) {return __tree_.erase(__p);}
464 size_type erase(const key_type& __k)
465 {return __tree_.__erase_unique(__k);}
466 iterator erase(const_iterator __f, const_iterator __l)
467 {return __tree_.erase(__f, __l);}
468 void clear() {__tree_.clear();}
469
470 void swap(set& __s) {__tree_.swap(__s.__tree_);}
471
472 allocator_type get_allocator() const {return __tree_.__alloc();}
473 key_compare key_comp() const {return __tree_.value_comp();}
474 value_compare value_comp() const {return __tree_.value_comp();}
475
476 // set operations:
477 iterator find(const key_type& __k) {return __tree_.find(__k);}
478 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
479 size_type count(const key_type& __k) const
480 {return __tree_.__count_unique(__k);}
481 iterator lower_bound(const key_type& __k)
482 {return __tree_.lower_bound(__k);}
483 const_iterator lower_bound(const key_type& __k) const
484 {return __tree_.lower_bound(__k);}
485 iterator upper_bound(const key_type& __k)
486 {return __tree_.upper_bound(__k);}
487 const_iterator upper_bound(const key_type& __k) const
488 {return __tree_.upper_bound(__k);}
489 pair<iterator,iterator> equal_range(const key_type& __k)
490 {return __tree_.__equal_range_unique(__k);}
491 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
492 {return __tree_.__equal_range_unique(__k);}
493};
494
Howard Hinnant73d21a42010-09-04 23:28:19 +0000495#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000496
497template <class _Key, class _Compare, class _Allocator>
498set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a)
499 : __tree_(_STD::move(__s.__tree_), __a)
500{
501 if (__a != __s.get_allocator())
502 {
503 const_iterator __e = cend();
504 while (!__s.empty())
505 insert(__e, _STD::move(__s.__tree_.remove(__s.begin())->__value_));
506 }
507}
508
Howard Hinnant73d21a42010-09-04 23:28:19 +0000509#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000510
511template <class _Key, class _Compare, class _Allocator>
512inline
513bool
514operator==(const set<_Key, _Compare, _Allocator>& __x,
515 const set<_Key, _Compare, _Allocator>& __y)
516{
517 return __x.size() == __y.size() && _STD::equal(__x.begin(), __x.end(), __y.begin());
518}
519
520template <class _Key, class _Compare, class _Allocator>
521inline
522bool
523operator< (const set<_Key, _Compare, _Allocator>& __x,
524 const set<_Key, _Compare, _Allocator>& __y)
525{
526 return _STD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
527}
528
529template <class _Key, class _Compare, class _Allocator>
530inline
531bool
532operator!=(const set<_Key, _Compare, _Allocator>& __x,
533 const set<_Key, _Compare, _Allocator>& __y)
534{
535 return !(__x == __y);
536}
537
538template <class _Key, class _Compare, class _Allocator>
539inline
540bool
541operator> (const set<_Key, _Compare, _Allocator>& __x,
542 const set<_Key, _Compare, _Allocator>& __y)
543{
544 return __y < __x;
545}
546
547template <class _Key, class _Compare, class _Allocator>
548inline
549bool
550operator>=(const set<_Key, _Compare, _Allocator>& __x,
551 const set<_Key, _Compare, _Allocator>& __y)
552{
553 return !(__x < __y);
554}
555
556template <class _Key, class _Compare, class _Allocator>
557inline
558bool
559operator<=(const set<_Key, _Compare, _Allocator>& __x,
560 const set<_Key, _Compare, _Allocator>& __y)
561{
562 return !(__y < __x);
563}
564
565// specialized algorithms:
566template <class _Key, class _Compare, class _Allocator>
567inline
568void
569swap(set<_Key, _Compare, _Allocator>& __x,
570 set<_Key, _Compare, _Allocator>& __y)
571{
572 __x.swap(__y);
573}
574
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000575template <class _Key, class _Compare = less<_Key>,
576 class _Allocator = allocator<_Key> >
577class multiset
578{
579public:
580 // types:
581 typedef _Key key_type;
582 typedef key_type value_type;
583 typedef _Compare key_compare;
584 typedef key_compare value_compare;
585 typedef _Allocator allocator_type;
586 typedef value_type& reference;
587 typedef const value_type& const_reference;
588
589private:
590 typedef __tree<value_type, value_compare, allocator_type> __base;
591 typedef allocator_traits<allocator_type> __alloc_traits;
592 typedef typename __base::__node_holder __node_holder;
593
594 __base __tree_;
595
596public:
597 typedef typename __base::pointer pointer;
598 typedef typename __base::const_pointer const_pointer;
599 typedef typename __base::size_type size_type;
600 typedef typename __base::difference_type difference_type;
601 typedef typename __base::const_iterator iterator;
602 typedef typename __base::const_iterator const_iterator;
603 typedef _STD::reverse_iterator<iterator> reverse_iterator;
604 typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
605
606 // construct/copy/destroy:
607 explicit multiset(const value_compare& __comp = value_compare())
608 : __tree_(__comp) {}
609 multiset(const value_compare& __comp, const allocator_type& __a)
610 : __tree_(__comp, __a) {}
611 template <class _InputIterator>
612 multiset(_InputIterator __f, _InputIterator __l,
613 const value_compare& __comp = value_compare())
614 : __tree_(__comp)
615 {
616 insert(__f, __l);
617 }
618
619 template <class _InputIterator>
620 multiset(_InputIterator __f, _InputIterator __l,
621 const value_compare& __comp, const allocator_type& __a)
622 : __tree_(__comp, __a)
623 {
624 insert(__f, __l);
625 }
626
627 multiset(const multiset& __s)
628 : __tree_(__s.__tree_.value_comp(),
629 __alloc_traits::select_on_container_copy_construction(__s.__tree_.__alloc()))
630 {
631 insert(__s.begin(), __s.end());
632 }
633
Howard Hinnant73d21a42010-09-04 23:28:19 +0000634#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000635 multiset(multiset&& __s)
636 : __tree_(_STD::move(__s.__tree_)) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000637#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000638 explicit multiset(const allocator_type& __a)
639 : __tree_(__a) {}
640 multiset(const multiset& __s, const allocator_type& __a)
641 : __tree_(__s.__tree_.value_comp(), __a)
642 {
643 insert(__s.begin(), __s.end());
644 }
Howard Hinnant73d21a42010-09-04 23:28:19 +0000645#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000646 multiset(multiset&& __s, const allocator_type& __a);
647#endif
648
649 multiset(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
650 : __tree_(__comp)
651 {
652 insert(__il.begin(), __il.end());
653 }
654
655 multiset(initializer_list<value_type> __il, const value_compare& __comp,
656 const allocator_type& __a)
657 : __tree_(__comp, __a)
658 {
659 insert(__il.begin(), __il.end());
660 }
661
662 multiset& operator=(initializer_list<value_type> __il)
663 {
664 __tree_.__assign_multi(__il.begin(), __il.end());
665 return *this;
666 }
667
Howard Hinnant73d21a42010-09-04 23:28:19 +0000668#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000669 multiset& operator=(multiset&& __s)
670 {
671 __tree_ = _STD::move(__s.__tree_);
672 return *this;
673 }
Howard Hinnant73d21a42010-09-04 23:28:19 +0000674#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000675
676 iterator begin() {return __tree_.begin();}
677 const_iterator begin() const {return __tree_.begin();}
678 iterator end() {return __tree_.end();}
679 const_iterator end() const {return __tree_.end();}
680
681 reverse_iterator rbegin() {return reverse_iterator(end());}
682 const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
683 reverse_iterator rend() {return reverse_iterator(begin());}
684 const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
685
686 const_iterator cbegin() const {return begin();}
687 const_iterator cend() const {return end();}
688 const_reverse_iterator crbegin() const {return rbegin();}
689 const_reverse_iterator crend() const {return rend();}
690
691 bool empty() const {return __tree_.size() == 0;}
692 size_type size() const {return __tree_.size();}
693 size_type max_size() const {return __tree_.max_size();}
694
695 // modifiers:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000696#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000697 template <class... _Args>
698 iterator emplace(_Args&&... __args)
699 {return __tree_.__emplace_multi(_STD::forward<_Args>(__args)...);}
700 template <class... _Args>
701 iterator emplace_hint(const_iterator __p, _Args&&... __args)
702 {return __tree_.__emplace_hint_multi(__p, _STD::forward<_Args>(__args)...);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000703#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000704 iterator insert(const value_type& __v)
705 {return __tree_.__insert_multi(__v);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000706#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000707 iterator insert(value_type&& __v)
708 {return __tree_.__insert_multi(_STD::move(__v));}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000709#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000710 iterator insert(const_iterator __p, const value_type& __v)
711 {return __tree_.__insert_multi(__p, __v);}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000712#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000713 iterator insert(const_iterator __p, value_type&& __v)
714 {return __tree_.__insert_multi(_STD::move(__v));}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000715#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000716 template <class _InputIterator>
717 void insert(_InputIterator __f, _InputIterator __l)
718 {
719 for (const_iterator __e = cend(); __f != __l; ++__f)
720 __tree_.__insert_multi(__e, *__f);
721 }
722
723 void insert(initializer_list<value_type> __il)
724 {insert(__il.begin(), __il.end());}
725
726 iterator erase(const_iterator __p) {return __tree_.erase(__p);}
727 size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}
728 iterator erase(const_iterator __f, const_iterator __l)
729 {return __tree_.erase(__f, __l);}
730 void clear() {__tree_.clear();}
731
732 void swap(multiset& __s) {__tree_.swap(__s.__tree_);}
733
734 allocator_type get_allocator() const {return __tree_.__alloc();}
735 key_compare key_comp() const {return __tree_.value_comp();}
736 value_compare value_comp() const {return __tree_.value_comp();}
737
738 // set operations:
739 iterator find(const key_type& __k) {return __tree_.find(__k);}
740 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
741 size_type count(const key_type& __k) const
742 {return __tree_.__count_multi(__k);}
743 iterator lower_bound(const key_type& __k)
744 {return __tree_.lower_bound(__k);}
745 const_iterator lower_bound(const key_type& __k) const
746 {return __tree_.lower_bound(__k);}
747 iterator upper_bound(const key_type& __k)
748 {return __tree_.upper_bound(__k);}
749 const_iterator upper_bound(const key_type& __k) const
750 {return __tree_.upper_bound(__k);}
751 pair<iterator,iterator> equal_range(const key_type& __k)
752 {return __tree_.__equal_range_multi(__k);}
753 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
754 {return __tree_.__equal_range_multi(__k);}
755};
756
Howard Hinnant73d21a42010-09-04 23:28:19 +0000757#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000758
759template <class _Key, class _Compare, class _Allocator>
760multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a)
761 : __tree_(_STD::move(__s.__tree_), __a)
762{
763 if (__a != __s.get_allocator())
764 {
765 const_iterator __e = cend();
766 while (!__s.empty())
767 insert(__e, _STD::move(__s.__tree_.remove(__s.begin())->__value_));
768 }
769}
770
Howard Hinnant73d21a42010-09-04 23:28:19 +0000771#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000772
773template <class _Key, class _Compare, class _Allocator>
774inline
775bool
776operator==(const multiset<_Key, _Compare, _Allocator>& __x,
777 const multiset<_Key, _Compare, _Allocator>& __y)
778{
779 return __x.size() == __y.size() && _STD::equal(__x.begin(), __x.end(), __y.begin());
780}
781
782template <class _Key, class _Compare, class _Allocator>
783inline
784bool
785operator< (const multiset<_Key, _Compare, _Allocator>& __x,
786 const multiset<_Key, _Compare, _Allocator>& __y)
787{
788 return _STD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
789}
790
791template <class _Key, class _Compare, class _Allocator>
792inline
793bool
794operator!=(const multiset<_Key, _Compare, _Allocator>& __x,
795 const multiset<_Key, _Compare, _Allocator>& __y)
796{
797 return !(__x == __y);
798}
799
800template <class _Key, class _Compare, class _Allocator>
801inline
802bool
803operator> (const multiset<_Key, _Compare, _Allocator>& __x,
804 const multiset<_Key, _Compare, _Allocator>& __y)
805{
806 return __y < __x;
807}
808
809template <class _Key, class _Compare, class _Allocator>
810inline
811bool
812operator>=(const multiset<_Key, _Compare, _Allocator>& __x,
813 const multiset<_Key, _Compare, _Allocator>& __y)
814{
815 return !(__x < __y);
816}
817
818template <class _Key, class _Compare, class _Allocator>
819inline
820bool
821operator<=(const multiset<_Key, _Compare, _Allocator>& __x,
822 const multiset<_Key, _Compare, _Allocator>& __y)
823{
824 return !(__y < __x);
825}
826
827template <class _Key, class _Compare, class _Allocator>
828inline
829void
830swap(multiset<_Key, _Compare, _Allocator>& __x,
831 multiset<_Key, _Compare, _Allocator>& __y)
832{
833 __x.swap(__y);
834}
835
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000836_LIBCPP_END_NAMESPACE_STD
837
838#endif // _LIBCPP_SET