blob: 1c77c49c5ca82dcc1137ca71b12a89a50579450f [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------- map ------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_MAP
12#define _LIBCPP_MAP
13
14/*
15
16 map synopsis
17
18namespace std
19{
20
21template <class Key, class T, class Compare = less<Key>,
22 class Allocator = allocator<pair<const Key, T>>>
23class map
24{
25public:
26 // types:
27 typedef Key key_type;
28 typedef T mapped_type;
29 typedef pair<const key_type, mapped_type> value_type;
30 typedef Compare key_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::pointer pointer;
35 typedef typename allocator_type::const_pointer const_pointer;
36 typedef typename allocator_type::size_type size_type;
37 typedef typename allocator_type::difference_type difference_type;
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 class value_compare
45 : public binary_function<value_type, value_type, bool>
46 {
47 friend class map;
48 protected:
49 key_compare comp;
50
51 value_compare(key_compare c);
52 public:
53 bool operator()(const value_type& x, const value_type& y) const;
54 };
55
56 // construct/copy/destroy:
57 map();
58 explicit map(const key_compare& comp);
59 map(const key_compare& comp, const allocator_type& a);
60 template <class InputIterator>
61 map(InputIterator first, InputIterator last,
62 const key_compare& comp = key_compare());
63 template <class InputIterator>
64 map(InputIterator first, InputIterator last,
65 const key_compare& comp, const allocator_type& a);
66 map(const map& m);
67 map(map&& m);
68 explicit map(const allocator_type& a);
69 map(const map& m, const allocator_type& a);
70 map(map&& m, const allocator_type& a);
71 map(initializer_list<value_type> il, const key_compare& comp = key_compare());
72 map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
73 ~map();
74
75 map& operator=(const map& m);
76 map& operator=(map&& m);
77 map& operator=(initializer_list<value_type> il);
78
79 // iterators:
80 iterator begin();
81 const_iterator begin() const;
82 iterator end();
83 const_iterator end() const;
84
85 reverse_iterator rbegin();
86 const_reverse_iterator rbegin() const;
87 reverse_iterator rend();
88 const_reverse_iterator rend() const;
89
90 const_iterator cbegin() const;
91 const_iterator cend() const;
92 const_reverse_iterator crbegin() const;
93 const_reverse_iterator crend() const;
94
95 // capacity:
96 bool empty() const;
97 size_type size() const;
98 size_type max_size() const;
99
100 // element access:
101 mapped_type& operator[](const key_type& k);
102 mapped_type& operator[](key_type&& k);
103
104 mapped_type& at(const key_type& k);
105 const mapped_type& at(const key_type& k) const;
106
107 // modifiers:
108 template <class... Args>
109 pair<iterator, bool> emplace(Args&&... args);
110 template <class... Args>
111 iterator emplace_hint(const_iterator position, Args&&... args);
112 pair<iterator, bool> insert(const value_type& v);
113 template <class P>
114 pair<iterator, bool> insert(P&& p);
115 iterator insert(const_iterator position, const value_type& v);
116 template <class P>
117 iterator insert(const_iterator position, P&& p);
118 template <class InputIterator>
119 void insert(InputIterator first, InputIterator last);
120 void insert(initializer_list<value_type> il);
121
122 iterator erase(const_iterator position);
123 size_type erase(const key_type& k);
124 iterator erase(const_iterator first, const_iterator last);
125 void clear();
126
127 void swap(map& m);
128
129 // observers:
130 allocator_type get_allocator() const;
131 key_compare key_comp() const;
132 value_compare value_comp() const;
133
134 // map operations:
135 iterator find(const key_type& k);
136 const_iterator find(const key_type& k) const;
137 size_type count(const key_type& k) const;
138 iterator lower_bound(const key_type& k);
139 const_iterator lower_bound(const key_type& k) const;
140 iterator upper_bound(const key_type& k);
141 const_iterator upper_bound(const key_type& k) const;
142 pair<iterator,iterator> equal_range(const key_type& k);
143 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
144};
145
146template <class Key, class T, class Compare, class Allocator>
147bool
148operator==(const map<Key, T, Compare, Allocator>& x,
149 const map<Key, T, Compare, Allocator>& y);
150
151template <class Key, class T, class Compare, class Allocator>
152bool
153operator< (const map<Key, T, Compare, Allocator>& x,
154 const map<Key, T, Compare, Allocator>& y);
155
156template <class Key, class T, class Compare, class Allocator>
157bool
158operator!=(const map<Key, T, Compare, Allocator>& x,
159 const map<Key, T, Compare, Allocator>& y);
160
161template <class Key, class T, class Compare, class Allocator>
162bool
163operator> (const map<Key, T, Compare, Allocator>& x,
164 const map<Key, T, Compare, Allocator>& y);
165
166template <class Key, class T, class Compare, class Allocator>
167bool
168operator>=(const map<Key, T, Compare, Allocator>& x,
169 const map<Key, T, Compare, Allocator>& y);
170
171template <class Key, class T, class Compare, class Allocator>
172bool
173operator<=(const map<Key, T, Compare, Allocator>& x,
174 const map<Key, T, Compare, Allocator>& y);
175
176// specialized algorithms:
177template <class Key, class T, class Compare, class Allocator>
178void
179swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y);
180
181template <class Key, class T, class Compare = less<Key>,
182 class Allocator = allocator<pair<const Key, T>>>
183class multimap
184{
185public:
186 // types:
187 typedef Key key_type;
188 typedef T mapped_type;
189 typedef pair<const key_type,mapped_type> value_type;
190 typedef Compare key_compare;
191 typedef Allocator allocator_type;
192 typedef typename allocator_type::reference reference;
193 typedef typename allocator_type::const_reference const_reference;
194 typedef typename allocator_type::size_type size_type;
195 typedef typename allocator_type::difference_type difference_type;
196 typedef typename allocator_type::pointer pointer;
197 typedef typename allocator_type::const_pointer const_pointer;
198
199 typedef implementation-defined iterator;
200 typedef implementation-defined const_iterator;
201 typedef std::reverse_iterator<iterator> reverse_iterator;
202 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
203
204 class value_compare
205 : public binary_function<value_type,value_type,bool>
206 {
207 friend class multimap;
208 protected:
209 key_compare comp;
210 value_compare(key_compare c);
211 public:
212 bool operator()(const value_type& x, const value_type& y) const;
213 };
214
215 // construct/copy/destroy:
216 explicit multimap(const key_compare& comp = key_compare());
217 multimap(const key_compare& comp, const allocator_type& a);
218 template <class InputIterator>
219 multimap(InputIterator first, InputIterator last, const key_compare& comp);
220 template <class InputIterator>
221 multimap(InputIterator first, InputIterator last, const key_compare& comp,
222 const allocator_type& a);
223 multimap(const multimap& m);
224 multimap(multimap&& m);
225 explicit multimap(const allocator_type& a);
226 multimap(const multimap& m, const allocator_type& a);
227 multimap(multimap&& m, const allocator_type& a);
228 multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());
229 multimap(initializer_list<value_type> il, const key_compare& comp,
230 const allocator_type& a);
231 ~multimap();
232
233 multimap& operator=(const multimap& m);
234 multimap& operator=(multimap&& m);
235 multimap& operator=(initializer_list<value_type> il);
236
237 // iterators:
238 iterator begin();
239 const_iterator begin() const;
240 iterator end();
241 const_iterator end() const;
242
243 reverse_iterator rbegin();
244 const_reverse_iterator rbegin() const;
245 reverse_iterator rend();
246 const_reverse_iterator rend() const;
247
248 const_iterator cbegin() const;
249 const_iterator cend() const;
250 const_reverse_iterator crbegin() const;
251 const_reverse_iterator crend() const;
252
253 // capacity:
254 bool empty() const;
255 size_type size() const;
256 size_type max_size() const;
257
258 // modifiers:
259 template <class... Args>
260 iterator emplace(Args&&... args);
261 template <class... Args>
262 iterator emplace_hint(const_iterator position, Args&&... args);
263 iterator insert(const value_type& v);
264 template <class P>
265 iterator insert(P&& p);
266 iterator insert(const_iterator position, const value_type& v);
267 template <class P>
268 iterator insert(const_iterator position, P&& p);
269 template <class InputIterator>
270 void insert(InputIterator first, InputIterator last);
271 void insert(initializer_list<value_type> il);
272
273 iterator erase(const_iterator position);
274 size_type erase(const key_type& k);
275 iterator erase(const_iterator first, const_iterator last);
276 void clear();
277
278 void swap(multimap& m);
279
280 // observers:
281 allocator_type get_allocator() const;
282 key_compare key_comp() const;
283 value_compare value_comp() const;
284
285 // map operations:
286 iterator find(const key_type& k);
287 const_iterator find(const key_type& k) const;
288 size_type count(const key_type& k) const;
289 iterator lower_bound(const key_type& k);
290 const_iterator lower_bound(const key_type& k) const;
291 iterator upper_bound(const key_type& k);
292 const_iterator upper_bound(const key_type& k) const;
293 pair<iterator,iterator> equal_range(const key_type& k);
294 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
295};
296
297template <class Key, class T, class Compare, class Allocator>
298bool
299operator==(const multimap<Key, T, Compare, Allocator>& x,
300 const multimap<Key, T, Compare, Allocator>& y);
301
302template <class Key, class T, class Compare, class Allocator>
303bool
304operator< (const multimap<Key, T, Compare, Allocator>& x,
305 const multimap<Key, T, Compare, Allocator>& y);
306
307template <class Key, class T, class Compare, class Allocator>
308bool
309operator!=(const multimap<Key, T, Compare, Allocator>& x,
310 const multimap<Key, T, Compare, Allocator>& y);
311
312template <class Key, class T, class Compare, class Allocator>
313bool
314operator> (const multimap<Key, T, Compare, Allocator>& x,
315 const multimap<Key, T, Compare, Allocator>& y);
316
317template <class Key, class T, class Compare, class Allocator>
318bool
319operator>=(const multimap<Key, T, Compare, Allocator>& x,
320 const multimap<Key, T, Compare, Allocator>& y);
321
322template <class Key, class T, class Compare, class Allocator>
323bool
324operator<=(const multimap<Key, T, Compare, Allocator>& x,
325 const multimap<Key, T, Compare, Allocator>& y);
326
327// specialized algorithms:
328template <class Key, class T, class Compare, class Allocator>
329void
330swap(multimap<Key, T, Compare, Allocator>& x,
331 multimap<Key, T, Compare, Allocator>& y);
332
333} // std
334
335*/
336
337#include <__config>
338#include <__tree>
339#include <iterator>
340#include <memory>
341#include <utility>
342#include <functional>
343#include <initializer_list>
344
345#pragma GCC system_header
346
347_LIBCPP_BEGIN_NAMESPACE_STD
348
349template <class _Key, class _Tp, class _Compare, bool = is_empty<_Compare>::value>
350class __map_value_compare
351 : private _Compare
352{
Howard Hinnant93c382b2011-01-04 19:21:05 +0000353 typedef pair<typename std::remove_const<_Key>::type, _Tp> _P;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000354 typedef pair<const _Key, _Tp> _CP;
355public:
Howard Hinnant82894812010-09-22 16:48:34 +0000356 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000357 __map_value_compare() : _Compare() {}
Howard Hinnant82894812010-09-22 16:48:34 +0000358 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000359 __map_value_compare(_Compare c) : _Compare(c) {}
Howard Hinnant82894812010-09-22 16:48:34 +0000360 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000361 const _Compare& key_comp() const {return *this;}
Howard Hinnant82894812010-09-22 16:48:34 +0000362 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000363 bool operator()(const _CP& __x, const _CP& __y) const
364 {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000366 bool operator()(const _CP& __x, const _P& __y) const
367 {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000368 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000369 bool operator()(const _CP& __x, const _Key& __y) const
370 {return static_cast<const _Compare&>(*this)(__x.first, __y);}
Howard Hinnant82894812010-09-22 16:48:34 +0000371 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000372 bool operator()(const _P& __x, const _CP& __y) const
373 {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000375 bool operator()(const _P& __x, const _P& __y) const
376 {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000377 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000378 bool operator()(const _P& __x, const _Key& __y) const
379 {return static_cast<const _Compare&>(*this)(__x.first, __y);}
Howard Hinnant82894812010-09-22 16:48:34 +0000380 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000381 bool operator()(const _Key& __x, const _CP& __y) const
382 {return static_cast<const _Compare&>(*this)(__x, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000384 bool operator()(const _Key& __x, const _P& __y) const
385 {return static_cast<const _Compare&>(*this)(__x, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000386 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000387 bool operator()(const _Key& __x, const _Key& __y) const
388 {return static_cast<const _Compare&>(*this)(__x, __y);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000389};
390
391template <class _Key, class _Tp, class _Compare>
392class __map_value_compare<_Key, _Tp, _Compare, false>
393{
394 _Compare comp;
395
Howard Hinnant93c382b2011-01-04 19:21:05 +0000396 typedef pair<typename std::remove_const<_Key>::type, _Tp> _P;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000397 typedef pair<const _Key, _Tp> _CP;
398
399public:
Howard Hinnant82894812010-09-22 16:48:34 +0000400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000401 __map_value_compare() : comp() {}
Howard Hinnant82894812010-09-22 16:48:34 +0000402 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000403 __map_value_compare(_Compare c) : comp(c) {}
Howard Hinnant82894812010-09-22 16:48:34 +0000404 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000405 const _Compare& key_comp() const {return comp;}
406
Howard Hinnant82894812010-09-22 16:48:34 +0000407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000408 bool operator()(const _CP& __x, const _CP& __y) const
409 {return comp(__x.first, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000411 bool operator()(const _CP& __x, const _P& __y) const
412 {return comp(__x.first, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000414 bool operator()(const _CP& __x, const _Key& __y) const
415 {return comp(__x.first, __y);}
Howard Hinnant82894812010-09-22 16:48:34 +0000416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000417 bool operator()(const _P& __x, const _CP& __y) const
418 {return comp(__x.first, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000419 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000420 bool operator()(const _P& __x, const _P& __y) const
421 {return comp(__x.first, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000422 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000423 bool operator()(const _P& __x, const _Key& __y) const
424 {return comp(__x.first, __y);}
Howard Hinnant82894812010-09-22 16:48:34 +0000425 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000426 bool operator()(const _Key& __x, const _CP& __y) const
427 {return comp(__x, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000428 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000429 bool operator()(const _Key& __x, const _P& __y) const
430 {return comp(__x, __y.first);}
Howard Hinnant82894812010-09-22 16:48:34 +0000431 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000432 bool operator()(const _Key& __x, const _Key& __y) const
433 {return comp(__x, __y);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000434};
435
436template <class _Allocator>
437class __map_node_destructor
438{
439 typedef _Allocator allocator_type;
440 typedef allocator_traits<allocator_type> __alloc_traits;
441 typedef typename __alloc_traits::value_type::value_type value_type;
442public:
443 typedef typename __alloc_traits::pointer pointer;
444private:
445 typedef typename value_type::first_type first_type;
446 typedef typename value_type::second_type second_type;
447
448 allocator_type& __na_;
449
450 __map_node_destructor& operator=(const __map_node_destructor&);
451
452public:
453 bool __first_constructed;
454 bool __second_constructed;
455
Howard Hinnant82894812010-09-22 16:48:34 +0000456 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000457 explicit __map_node_destructor(allocator_type& __na)
458 : __na_(__na),
459 __first_constructed(false),
460 __second_constructed(false)
461 {}
462
Howard Hinnant73d21a42010-09-04 23:28:19 +0000463#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant82894812010-09-22 16:48:34 +0000464 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000465 __map_node_destructor(__tree_node_destructor<allocator_type>&& __x)
466 : __na_(__x.__na_),
467 __first_constructed(__x.__value_constructed),
468 __second_constructed(__x.__value_constructed)
469 {
470 __x.__value_constructed = false;
471 }
Howard Hinnantbfd55302010-09-04 23:46:48 +0000472#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000473
Howard Hinnant82894812010-09-22 16:48:34 +0000474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000475 void operator()(pointer __p)
476 {
477 if (__second_constructed)
Howard Hinnant2529d022011-02-02 17:36:20 +0000478 __alloc_traits::destroy(__na_, _STD::addressof(__p->__value_.second));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000479 if (__first_constructed)
Howard Hinnant2529d022011-02-02 17:36:20 +0000480 __alloc_traits::destroy(__na_, _STD::addressof(__p->__value_.first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000481 if (__p)
482 __alloc_traits::deallocate(__na_, __p, 1);
483 }
484};
485
486template <class, class, class, class> class map;
487template <class, class, class, class> class multimap;
488template <class> class __map_const_iterator;
489
490template <class _TreeIterator>
Howard Hinnant82894812010-09-22 16:48:34 +0000491class _LIBCPP_VISIBLE __map_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000492{
493 _TreeIterator __i_;
494
495 typedef typename _TreeIterator::__pointer_traits __pointer_traits;
Howard Hinnantdf85e572011-02-27 18:02:02 +0000496 typedef const typename _TreeIterator::value_type::first_type __key_type;
497 typedef typename _TreeIterator::value_type::second_type __mapped_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000498public:
499 typedef bidirectional_iterator_tag iterator_category;
Howard Hinnantdf85e572011-02-27 18:02:02 +0000500 typedef pair<__key_type, __mapped_type> value_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000501 typedef typename _TreeIterator::difference_type difference_type;
502 typedef value_type& reference;
503 typedef typename __pointer_traits::template
504#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
505 rebind<value_type>
506#else
507 rebind<value_type>::other
508#endif
509 pointer;
510
Howard Hinnant82894812010-09-22 16:48:34 +0000511 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000512 __map_iterator() {}
513
Howard Hinnant82894812010-09-22 16:48:34 +0000514 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000515 __map_iterator(_TreeIterator __i) : __i_(__i) {}
516
Howard Hinnant82894812010-09-22 16:48:34 +0000517 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000518 reference operator*() const {return *operator->();}
Howard Hinnant82894812010-09-22 16:48:34 +0000519 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000520 pointer operator->() const {return (pointer)__i_.operator->();}
521
Howard Hinnant82894812010-09-22 16:48:34 +0000522 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000523 __map_iterator& operator++() {++__i_; return *this;}
Howard Hinnant82894812010-09-22 16:48:34 +0000524 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000525 __map_iterator operator++(int)
526 {
527 __map_iterator __t(*this);
528 ++(*this);
529 return __t;
530 }
531
Howard Hinnant82894812010-09-22 16:48:34 +0000532 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000533 __map_iterator& operator--() {--__i_; return *this;}
Howard Hinnant82894812010-09-22 16:48:34 +0000534 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000535 __map_iterator operator--(int)
536 {
537 __map_iterator __t(*this);
538 --(*this);
539 return __t;
540 }
541
Howard Hinnant82894812010-09-22 16:48:34 +0000542 friend _LIBCPP_INLINE_VISIBILITY
543 bool operator==(const __map_iterator& __x, const __map_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000544 {return __x.__i_ == __y.__i_;}
Howard Hinnant82894812010-09-22 16:48:34 +0000545 friend
546 _LIBCPP_INLINE_VISIBILITY
547 bool operator!=(const __map_iterator& __x, const __map_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000548 {return __x.__i_ != __y.__i_;}
549
Howard Hinnant82894812010-09-22 16:48:34 +0000550 template <class, class, class, class> friend class _LIBCPP_VISIBLE map;
551 template <class, class, class, class> friend class _LIBCPP_VISIBLE multimap;
552 template <class> friend class _LIBCPP_VISIBLE __map_const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000553};
554
555template <class _TreeIterator>
Howard Hinnant82894812010-09-22 16:48:34 +0000556class _LIBCPP_VISIBLE __map_const_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000557{
558 _TreeIterator __i_;
559
560 typedef typename _TreeIterator::__pointer_traits __pointer_traits;
Howard Hinnantdf85e572011-02-27 18:02:02 +0000561 typedef const typename _TreeIterator::value_type::first_type __key_type;
562 typedef typename _TreeIterator::value_type::second_type __mapped_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000563public:
564 typedef bidirectional_iterator_tag iterator_category;
Howard Hinnantdf85e572011-02-27 18:02:02 +0000565 typedef pair<__key_type, __mapped_type> value_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000566 typedef typename _TreeIterator::difference_type difference_type;
567 typedef const value_type& reference;
568 typedef typename __pointer_traits::template
569#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
Howard Hinnant9dbeff92011-04-11 02:18:41 +0000570 rebind<const value_type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000571#else
Howard Hinnant9dbeff92011-04-11 02:18:41 +0000572 rebind<const value_type>::other
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000573#endif
574 pointer;
575
Howard Hinnant82894812010-09-22 16:48:34 +0000576 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000577 __map_const_iterator() {}
578
Howard Hinnant82894812010-09-22 16:48:34 +0000579 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000580 __map_const_iterator(_TreeIterator __i) : __i_(__i) {}
Howard Hinnant82894812010-09-22 16:48:34 +0000581 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000582 __map_const_iterator(
583 __map_iterator<typename _TreeIterator::__non_const_iterator> __i)
584 : __i_(__i.__i_) {}
585
Howard Hinnant82894812010-09-22 16:48:34 +0000586 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000587 reference operator*() const {return *operator->();}
Howard Hinnant82894812010-09-22 16:48:34 +0000588 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000589 pointer operator->() const {return (pointer)__i_.operator->();}
590
Howard Hinnant82894812010-09-22 16:48:34 +0000591 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000592 __map_const_iterator& operator++() {++__i_; return *this;}
Howard Hinnant82894812010-09-22 16:48:34 +0000593 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000594 __map_const_iterator operator++(int)
595 {
596 __map_const_iterator __t(*this);
597 ++(*this);
598 return __t;
599 }
600
Howard Hinnant82894812010-09-22 16:48:34 +0000601 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000602 __map_const_iterator& operator--() {--__i_; return *this;}
Howard Hinnant82894812010-09-22 16:48:34 +0000603 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000604 __map_const_iterator operator--(int)
605 {
606 __map_const_iterator __t(*this);
607 --(*this);
608 return __t;
609 }
610
Howard Hinnant82894812010-09-22 16:48:34 +0000611 friend _LIBCPP_INLINE_VISIBILITY
612 bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000613 {return __x.__i_ == __y.__i_;}
Howard Hinnant82894812010-09-22 16:48:34 +0000614 friend _LIBCPP_INLINE_VISIBILITY
615 bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000616 {return __x.__i_ != __y.__i_;}
617
Howard Hinnant82894812010-09-22 16:48:34 +0000618 template <class, class, class, class> friend class _LIBCPP_VISIBLE map;
619 template <class, class, class, class> friend class _LIBCPP_VISIBLE multimap;
620 template <class, class, class> friend class _LIBCPP_VISIBLE __tree_const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000621};
622
623template <class _Key, class _Tp, class _Compare = less<_Key>,
624 class _Allocator = allocator<pair<const _Key, _Tp> > >
Howard Hinnant82894812010-09-22 16:48:34 +0000625class _LIBCPP_VISIBLE map
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000626{
627public:
628 // types:
629 typedef _Key key_type;
630 typedef _Tp mapped_type;
631 typedef pair<const key_type, mapped_type> value_type;
632 typedef _Compare key_compare;
633 typedef _Allocator allocator_type;
634 typedef value_type& reference;
635 typedef const value_type& const_reference;
636
Howard Hinnant82894812010-09-22 16:48:34 +0000637 class _LIBCPP_VISIBLE value_compare
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000638 : public binary_function<value_type, value_type, bool>
639 {
640 friend class map;
641 protected:
642 key_compare comp;
643
Howard Hinnant82894812010-09-22 16:48:34 +0000644 _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000645 public:
Howard Hinnant82894812010-09-22 16:48:34 +0000646 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000647 bool operator()(const value_type& __x, const value_type& __y) const
648 {return comp(__x.first, __y.first);}
649 };
650
651private:
652 typedef pair<key_type, mapped_type> __value_type;
653 typedef __map_value_compare<key_type, mapped_type, key_compare> __vc;
654 typedef typename allocator_traits<allocator_type>::template
655#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
656 rebind_alloc<__value_type>
657#else
658 rebind_alloc<__value_type>::other
659#endif
660 __allocator_type;
661 typedef __tree<__value_type, __vc, __allocator_type> __base;
662 typedef typename __base::__node_traits __node_traits;
663 typedef allocator_traits<allocator_type> __alloc_traits;
664
665 __base __tree_;
666
667public:
668 typedef typename __alloc_traits::pointer pointer;
669 typedef typename __alloc_traits::const_pointer const_pointer;
670 typedef typename __alloc_traits::size_type size_type;
671 typedef typename __alloc_traits::difference_type difference_type;
672 typedef __map_iterator<typename __base::iterator> iterator;
673 typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
674 typedef _STD::reverse_iterator<iterator> reverse_iterator;
675 typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
676
Howard Hinnant82894812010-09-22 16:48:34 +0000677 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000678 explicit map(const key_compare& __comp = key_compare())
679 : __tree_(__vc(__comp)) {}
680
Howard Hinnant82894812010-09-22 16:48:34 +0000681 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000682 explicit map(const key_compare& __comp, const allocator_type& __a)
683 : __tree_(__vc(__comp), __a) {}
684
685 template <class _InputIterator>
Howard Hinnant82894812010-09-22 16:48:34 +0000686 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000687 map(_InputIterator __f, _InputIterator __l,
688 const key_compare& __comp = key_compare())
689 : __tree_(__vc(__comp))
690 {
691 insert(__f, __l);
692 }
693
694 template <class _InputIterator>
Howard Hinnant82894812010-09-22 16:48:34 +0000695 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000696 map(_InputIterator __f, _InputIterator __l,
697 const key_compare& __comp, const allocator_type& __a)
698 : __tree_(__vc(__comp), __a)
699 {
700 insert(__f, __l);
701 }
702
Howard Hinnant82894812010-09-22 16:48:34 +0000703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000704 map(const map& __m)
705 : __tree_(__m.__tree_)
706 {
707 insert(__m.begin(), __m.end());
708 }
709
Howard Hinnant73d21a42010-09-04 23:28:19 +0000710#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000711
Howard Hinnant82894812010-09-22 16:48:34 +0000712 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000713 map(map&& __m)
714 : __tree_(_STD::move(__m.__tree_))
715 {
716 }
717
718 map(map&& __m, const allocator_type& __a);
719
Howard Hinnant82894812010-09-22 16:48:34 +0000720 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000721 map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
722 : __tree_(__vc(__comp))
723 {
724 insert(__il.begin(), __il.end());
725 }
726
Howard Hinnant82894812010-09-22 16:48:34 +0000727 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000728 map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
729 : __tree_(__vc(__comp), __a)
730 {
731 insert(__il.begin(), __il.end());
732 }
733
Howard Hinnant82894812010-09-22 16:48:34 +0000734 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000735 map& operator=(map&& __m)
736 {
737 __tree_ = _STD::move(__m.__tree_);
738 return *this;
739 }
740
Howard Hinnant82894812010-09-22 16:48:34 +0000741 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000742 map& operator=(initializer_list<value_type> __il)
743 {
744 __tree_.__assign_unique(__il.begin(), __il.end());
745 return *this;
746 }
747
Howard Hinnantbfd55302010-09-04 23:46:48 +0000748#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000749
Howard Hinnant82894812010-09-22 16:48:34 +0000750 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000751 explicit map(const allocator_type& __a)
752 : __tree_(__a)
753 {
754 }
755
Howard Hinnant82894812010-09-22 16:48:34 +0000756 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000757 map(const map& __m, const allocator_type& __a)
758 : __tree_(__m.__tree_.value_comp(), __a)
759 {
760 insert(__m.begin(), __m.end());
761 }
762
Howard Hinnant82894812010-09-22 16:48:34 +0000763 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000764 iterator begin() {return __tree_.begin();}
Howard Hinnant82894812010-09-22 16:48:34 +0000765 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000766 const_iterator begin() const {return __tree_.begin();}
Howard Hinnant82894812010-09-22 16:48:34 +0000767 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000768 iterator end() {return __tree_.end();}
Howard Hinnant82894812010-09-22 16:48:34 +0000769 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000770 const_iterator end() const {return __tree_.end();}
771
Howard Hinnant82894812010-09-22 16:48:34 +0000772 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000773 reverse_iterator rbegin() {return reverse_iterator(end());}
Howard Hinnant82894812010-09-22 16:48:34 +0000774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000775 const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
Howard Hinnant82894812010-09-22 16:48:34 +0000776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000777 reverse_iterator rend() {return reverse_iterator(begin());}
Howard Hinnant82894812010-09-22 16:48:34 +0000778 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000779 const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
780
Howard Hinnant82894812010-09-22 16:48:34 +0000781 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000782 const_iterator cbegin() const {return begin();}
Howard Hinnant82894812010-09-22 16:48:34 +0000783 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000784 const_iterator cend() const {return end();}
Howard Hinnant82894812010-09-22 16:48:34 +0000785 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000786 const_reverse_iterator crbegin() const {return rbegin();}
Howard Hinnant82894812010-09-22 16:48:34 +0000787 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000788 const_reverse_iterator crend() const {return rend();}
789
Howard Hinnant82894812010-09-22 16:48:34 +0000790 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000791 bool empty() const {return __tree_.size() == 0;}
Howard Hinnant82894812010-09-22 16:48:34 +0000792 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000793 size_type size() const {return __tree_.size();}
Howard Hinnant82894812010-09-22 16:48:34 +0000794 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000795 size_type max_size() const {return __tree_.max_size();}
796
797 mapped_type& operator[](const key_type& __k);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000798#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000799 mapped_type& operator[](key_type&& __k);
800#endif
801
802 mapped_type& at(const key_type& __k);
803 const mapped_type& at(const key_type& __k) const;
804
Howard Hinnant82894812010-09-22 16:48:34 +0000805 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000806 allocator_type get_allocator() const {return __tree_.__alloc();}
Howard Hinnant82894812010-09-22 16:48:34 +0000807 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000808 key_compare key_comp() const {return __tree_.value_comp().key_comp();}
Howard Hinnant82894812010-09-22 16:48:34 +0000809 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000810 value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());}
811
Howard Hinnant73d21a42010-09-04 23:28:19 +0000812#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000813
Howard Hinnant82894812010-09-22 16:48:34 +0000814 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000815 pair<iterator, bool>
816 emplace() {return __tree_.__emplace_unique();}
817
818 template <class _A0,
819 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
Howard Hinnant82894812010-09-22 16:48:34 +0000820 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000821 pair<iterator, bool>
822 emplace(_A0&& __a0)
823 {return __tree_.__emplace_unique(_STD::forward<_A0>(__a0));}
824
Howard Hinnant73d21a42010-09-04 23:28:19 +0000825#ifndef _LIBCPP_HAS_NO_VARIADICS
826
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000827 template <class _A0, class ..._Args,
828 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
829 pair<iterator, bool>
830 emplace(_A0&& __a0, _Args&& ...__args);
831
Howard Hinnant73d21a42010-09-04 23:28:19 +0000832#endif // _LIBCPP_HAS_NO_VARIADICS
833
Howard Hinnant82894812010-09-22 16:48:34 +0000834 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000835 iterator
836 emplace_hint(const_iterator __p)
837 {return __tree_.__emplace_hint_unique(__p.__i_);}
838
839 template <class _A0,
840 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
Howard Hinnant82894812010-09-22 16:48:34 +0000841 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000842 iterator
843 emplace_hint(const_iterator __p, _A0&& __a0)
844 {return __tree_.__emplace_hint_unique(__p.__i_, _STD::forward<_A0>(__a0));}
845
Howard Hinnant73d21a42010-09-04 23:28:19 +0000846#ifndef _LIBCPP_HAS_NO_VARIADICS
847
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000848 template <class _A0, class ..._Args,
849 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
850 iterator
851 emplace_hint(const_iterator __p, _A0&& __a0, _Args&& ...__args);
852
Howard Hinnant73d21a42010-09-04 23:28:19 +0000853#endif // _LIBCPP_HAS_NO_VARIADICS
854
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000855 template <class _P,
856 class = typename enable_if<is_convertible<_P, value_type>::value>::type>
Howard Hinnant82894812010-09-22 16:48:34 +0000857 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000858 pair<iterator, bool> insert(_P&& __p)
859 {return __tree_.__insert_unique(_STD::forward<_P>(__p));}
860
861 template <class _P,
862 class = typename enable_if<is_convertible<_P, value_type>::value>::type>
Howard Hinnant82894812010-09-22 16:48:34 +0000863 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000864 iterator insert(const_iterator __pos, _P&& __p)
865 {return __tree_.__insert_unique(__pos.__i_, _STD::forward<_P>(__p));}
866
Howard Hinnant73d21a42010-09-04 23:28:19 +0000867#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000868
Howard Hinnant82894812010-09-22 16:48:34 +0000869 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000870 pair<iterator, bool>
871 insert(const value_type& __v) {return __tree_.__insert_unique(__v);}
872
Howard Hinnant82894812010-09-22 16:48:34 +0000873 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000874 iterator
875 insert(const_iterator __p, const value_type& __v)
876 {return __tree_.__insert_unique(__p.__i_, __v);}
877
878 template <class _InputIterator>
Howard Hinnant82894812010-09-22 16:48:34 +0000879 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000880 void insert(_InputIterator __f, _InputIterator __l)
881 {
882 for (const_iterator __e = cend(); __f != __l; ++__f)
883 insert(__e.__i_, *__f);
884 }
885
Howard Hinnant82894812010-09-22 16:48:34 +0000886 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000887 void insert(initializer_list<value_type> __il)
888 {insert(__il.begin(), __il.end());}
889
Howard Hinnant82894812010-09-22 16:48:34 +0000890 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000891 iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
Howard Hinnant82894812010-09-22 16:48:34 +0000892 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000893 size_type erase(const key_type& __k)
894 {return __tree_.__erase_unique(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +0000895 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000896 iterator erase(const_iterator __f, const_iterator __l)
897 {return __tree_.erase(__f.__i_, __l.__i_);}
Howard Hinnant82894812010-09-22 16:48:34 +0000898 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000899 void clear() {__tree_.clear();}
900
Howard Hinnant82894812010-09-22 16:48:34 +0000901 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000902 void swap(map& __m) {__tree_.swap(__m.__tree_);}
903
Howard Hinnant82894812010-09-22 16:48:34 +0000904 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000905 iterator find(const key_type& __k) {return __tree_.find(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +0000906 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000907 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +0000908 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000909 size_type count(const key_type& __k) const
910 {return __tree_.__count_unique(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +0000911 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000912 iterator lower_bound(const key_type& __k)
913 {return __tree_.lower_bound(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +0000914 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000915 const_iterator lower_bound(const key_type& __k) const
916 {return __tree_.lower_bound(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +0000917 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000918 iterator upper_bound(const key_type& __k)
919 {return __tree_.upper_bound(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +0000920 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000921 const_iterator upper_bound(const key_type& __k) const
922 {return __tree_.upper_bound(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +0000923 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000924 pair<iterator,iterator> equal_range(const key_type& __k)
925 {return __tree_.__equal_range_unique(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +0000926 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000927 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
928 {return __tree_.__equal_range_unique(__k);}
929
930private:
931 typedef typename __base::__node __node;
932 typedef typename __base::__node_allocator __node_allocator;
933 typedef typename __base::__node_pointer __node_pointer;
934 typedef typename __base::__node_const_pointer __node_const_pointer;
935 typedef typename __base::__node_base_pointer __node_base_pointer;
936 typedef typename __base::__node_base_const_pointer __node_base_const_pointer;
937 typedef __map_node_destructor<__node_allocator> _D;
938 typedef unique_ptr<__node, _D> __node_holder;
939
Howard Hinnant73d21a42010-09-04 23:28:19 +0000940#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000941 __node_holder __construct_node();
942 template <class _A0,
943 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
944 __node_holder __construct_node(_A0&& __a0);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000945#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000946 template <class _A0, class ..._Args,
947 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
948 __node_holder __construct_node(_A0&& __a0, _Args&& ...__args);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000949#endif // _LIBCPP_HAS_NO_VARIADICS
950#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000951 __node_holder __construct_node(const key_type& __k);
952#endif
953
954 __node_base_pointer&
955 __find_equal_key(__node_base_pointer& __parent, const key_type& __k);
956 __node_base_pointer&
957 __find_equal_key(const_iterator __hint,
958 __node_base_pointer& __parent, const key_type& __k);
959 __node_base_const_pointer
960 __find_equal_key(__node_base_const_pointer& __parent, const key_type& __k) const;
961};
962
963// Find place to insert if __k doesn't exist
964// Set __parent to parent of null leaf
965// Return reference to null leaf
966// If __k exists, set parent to node of __k and return reference to node of __k
967template <class _Key, class _Tp, class _Compare, class _Allocator>
968typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer&
969map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __parent,
970 const key_type& __k)
971{
972 __node_pointer __nd = __tree_.__root();
973 if (__nd != nullptr)
974 {
975 while (true)
976 {
977 if (__tree_.value_comp().key_comp()(__k, __nd->__value_.first))
978 {
979 if (__nd->__left_ != nullptr)
980 __nd = static_cast<__node_pointer>(__nd->__left_);
981 else
982 {
983 __parent = __nd;
984 return __parent->__left_;
985 }
986 }
987 else if (__tree_.value_comp().key_comp()(__nd->__value_.first, __k))
988 {
989 if (__nd->__right_ != nullptr)
990 __nd = static_cast<__node_pointer>(__nd->__right_);
991 else
992 {
993 __parent = __nd;
994 return __parent->__right_;
995 }
996 }
997 else
998 {
999 __parent = __nd;
1000 return __parent;
1001 }
1002 }
1003 }
1004 __parent = __tree_.__end_node();
1005 return __parent->__left_;
1006}
1007
1008// Find place to insert if __k doesn't exist
1009// First check prior to __hint.
1010// Next check after __hint.
1011// Next do O(log N) search.
1012// Set __parent to parent of null leaf
1013// Return reference to null leaf
1014// If __k exists, set parent to node of __k and return reference to node of __k
1015template <class _Key, class _Tp, class _Compare, class _Allocator>
1016typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer&
1017map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(const_iterator __hint,
1018 __node_base_pointer& __parent,
1019 const key_type& __k)
1020{
1021 if (__hint == end() || __tree_.value_comp().key_comp()(__k, __hint->first)) // check before
1022 {
1023 // __k < *__hint
1024 const_iterator __prior = __hint;
1025 if (__prior == begin() || __tree_.value_comp().key_comp()((--__prior)->first, __k))
1026 {
1027 // *prev(__hint) < __k < *__hint
1028 if (__hint.__ptr_->__left_ == nullptr)
1029 {
1030 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1031 return __parent->__left_;
1032 }
1033 else
1034 {
1035 __parent = const_cast<__node_pointer&>(__prior.__ptr_);
1036 return __parent->__right_;
1037 }
1038 }
1039 // __k <= *prev(__hint)
1040 return __find_equal_key(__parent, __k);
1041 }
1042 else if (__tree_.value_comp().key_comp()(__hint->first, __k)) // check after
1043 {
1044 // *__hint < __k
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001045 const_iterator __next = _STD::next(__hint);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001046 if (__next == end() || __tree_.value_comp().key_comp()(__k, __next->first))
1047 {
1048 // *__hint < __k < *next(__hint)
1049 if (__hint.__ptr_->__right_ == nullptr)
1050 {
1051 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1052 return __parent->__right_;
1053 }
1054 else
1055 {
1056 __parent = const_cast<__node_pointer&>(__next.__ptr_);
1057 return __parent->__left_;
1058 }
1059 }
1060 // *next(__hint) <= __k
1061 return __find_equal_key(__parent, __k);
1062 }
1063 // else __k == *__hint
1064 __parent = const_cast<__node_pointer&>(__hint.__ptr_);
1065 return __parent;
1066}
1067
1068// Find __k
1069// Set __parent to parent of null leaf and
1070// return reference to null leaf iv __k does not exist.
1071// If __k exists, set parent to node of __k and return reference to node of __k
1072template <class _Key, class _Tp, class _Compare, class _Allocator>
1073typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_const_pointer
1074map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer& __parent,
1075 const key_type& __k) const
1076{
1077 __node_const_pointer __nd = __tree_.__root();
1078 if (__nd != nullptr)
1079 {
1080 while (true)
1081 {
1082 if (__tree_.value_comp().key_comp()(__k, __nd->__value_.first))
1083 {
1084 if (__nd->__left_ != nullptr)
1085 __nd = static_cast<__node_pointer>(__nd->__left_);
1086 else
1087 {
1088 __parent = __nd;
1089 return const_cast<const __node_base_const_pointer&>(__parent->__left_);
1090 }
1091 }
1092 else if (__tree_.value_comp().key_comp()(__nd->__value_.first, __k))
1093 {
1094 if (__nd->__right_ != nullptr)
1095 __nd = static_cast<__node_pointer>(__nd->__right_);
1096 else
1097 {
1098 __parent = __nd;
1099 return const_cast<const __node_base_const_pointer&>(__parent->__right_);
1100 }
1101 }
1102 else
1103 {
1104 __parent = __nd;
1105 return __parent;
1106 }
1107 }
1108 }
1109 __parent = __tree_.__end_node();
1110 return const_cast<const __node_base_const_pointer&>(__parent->__left_);
1111}
1112
Howard Hinnant73d21a42010-09-04 23:28:19 +00001113#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001114
1115template <class _Key, class _Tp, class _Compare, class _Allocator>
1116map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
1117 : __tree_(_STD::move(__m.__tree_), __a)
1118{
1119 if (__a != __m.get_allocator())
1120 {
1121 const_iterator __e = cend();
1122 while (!__m.empty())
1123 __tree_.__insert_unique(__e.__i_,
1124 _STD::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
1125 }
1126}
1127
1128template <class _Key, class _Tp, class _Compare, class _Allocator>
1129typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1130map<_Key, _Tp, _Compare, _Allocator>::__construct_node()
1131{
1132 __node_allocator& __na = __tree_.__node_alloc();
1133 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
Howard Hinnant2529d022011-02-02 17:36:20 +00001134 __node_traits::construct(__na, _STD::addressof(__h->__value_.first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001135 __h.get_deleter().__first_constructed = true;
Howard Hinnant2529d022011-02-02 17:36:20 +00001136 __node_traits::construct(__na, _STD::addressof(__h->__value_.second));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001137 __h.get_deleter().__second_constructed = true;
1138 return __h;
1139}
1140
1141template <class _Key, class _Tp, class _Compare, class _Allocator>
1142template <class _A0,
1143 class>
1144typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1145map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
1146{
1147 __node_allocator& __na = __tree_.__node_alloc();
1148 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
Howard Hinnant2529d022011-02-02 17:36:20 +00001149 __node_traits::construct(__na, _STD::addressof(__h->__value_), _STD::forward<_A0>(__a0));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001150 __h.get_deleter().__first_constructed = true;
1151 __h.get_deleter().__second_constructed = true;
1152 return __h;
1153}
1154
Howard Hinnant73d21a42010-09-04 23:28:19 +00001155#ifndef _LIBCPP_HAS_NO_VARIADICS
1156
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001157template <class _Key, class _Tp, class _Compare, class _Allocator>
1158template <class _A0, class ..._Args,
1159 class>
1160typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1161map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _Args&& ...__args)
1162{
1163 __node_allocator& __na = __tree_.__node_alloc();
1164 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
Howard Hinnant2529d022011-02-02 17:36:20 +00001165 __node_traits::construct(__na, _STD::addressof(__h->__value_.first), _STD::forward<_A0>(__a0));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001166 __h.get_deleter().__first_constructed = true;
Howard Hinnant2529d022011-02-02 17:36:20 +00001167 __node_traits::construct(__na, _STD::addressof(__h->__value_.second), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001168 __h.get_deleter().__second_constructed = true;
1169 return __h;
1170}
1171
Howard Hinnant73d21a42010-09-04 23:28:19 +00001172#endif // _LIBCPP_HAS_NO_VARIADICS
1173
1174#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001175
1176template <class _Key, class _Tp, class _Compare, class _Allocator>
1177typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1178map<_Key, _Tp, _Compare, _Allocator>::__construct_node(const key_type& __k)
1179{
1180 __node_allocator& __na = __tree_.__node_alloc();
1181 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
Howard Hinnant2529d022011-02-02 17:36:20 +00001182 __node_traits::construct(__na, _STD::addressof(__h->__value_.first), __k);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001183 __h.get_deleter().__first_constructed = true;
Howard Hinnant2529d022011-02-02 17:36:20 +00001184 __node_traits::construct(__na, _STD::addressof(__h->__value_.second));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001185 __h.get_deleter().__second_constructed = true;
1186 return _STD::move(__h);
1187}
1188
Howard Hinnant73d21a42010-09-04 23:28:19 +00001189#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001190
1191template <class _Key, class _Tp, class _Compare, class _Allocator>
1192_Tp&
1193map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
1194{
1195 __node_base_pointer __parent;
1196 __node_base_pointer& __child = __find_equal_key(__parent, __k);
1197 __node_pointer __r = static_cast<__node_pointer>(__child);
1198 if (__child == nullptr)
1199 {
1200 __node_holder __h = __construct_node(__k);
1201 __tree_.__insert_node_at(__parent, __child, __h.get());
1202 __r = __h.release();
1203 }
1204 return __r->__value_.second;
1205}
1206
Howard Hinnant73d21a42010-09-04 23:28:19 +00001207#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001208
1209template <class _Key, class _Tp, class _Compare, class _Allocator>
1210_Tp&
1211map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k)
1212{
1213 __node_base_pointer __parent;
1214 __node_base_pointer& __child = __find_equal_key(__parent, __k);
1215 __node_pointer __r = static_cast<__node_pointer>(__child);
1216 if (__child == nullptr)
1217 {
1218 __node_holder __h = __construct_node(_STD::move(__k));
1219 __tree_.__insert_node_at(__parent, __child, __h.get());
1220 __r = __h.release();
1221 }
1222 return __r->__value_.second;
1223}
1224
Howard Hinnant73d21a42010-09-04 23:28:19 +00001225#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001226
1227template <class _Key, class _Tp, class _Compare, class _Allocator>
1228_Tp&
1229map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k)
1230{
1231 __node_base_pointer __parent;
1232 __node_base_pointer& __child = __find_equal_key(__parent, __k);
Howard Hinnantd4444702010-08-11 17:04:31 +00001233#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001234 if (__child == nullptr)
1235 throw out_of_range("map::at: key not found");
Howard Hinnant324bb032010-08-22 00:02:43 +00001236#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001237 return static_cast<__node_pointer>(__child)->__value_.second;
1238}
1239
1240template <class _Key, class _Tp, class _Compare, class _Allocator>
1241const _Tp&
1242map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const
1243{
1244 __node_base_const_pointer __parent;
1245 __node_base_const_pointer __child = __find_equal_key(__parent, __k);
Howard Hinnantd4444702010-08-11 17:04:31 +00001246#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001247 if (__child == nullptr)
1248 throw out_of_range("map::at: key not found");
Howard Hinnant324bb032010-08-22 00:02:43 +00001249#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001250 return static_cast<__node_const_pointer>(__child)->__value_.second;
1251}
1252
Howard Hinnant73d21a42010-09-04 23:28:19 +00001253#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001254
1255template <class _Key, class _Tp, class _Compare, class _Allocator>
1256template <class _A0, class ..._Args,
1257 class //= typename enable_if<is_convertible<_A0, _Key>::value>::type
1258 >
1259pair<typename map<_Key, _Tp, _Compare, _Allocator>::iterator, bool>
1260map<_Key, _Tp, _Compare, _Allocator>::emplace(_A0&& __a0, _Args&& ...__args)
1261{
1262 __node_holder __h = __construct_node(_STD::forward<_A0>(__a0),
1263 _STD::forward<_Args>(__args)...);
1264 pair<iterator, bool> __r = __tree_.__node_insert_unique(__h.get());
1265 if (__r.second)
1266 __h.release();
1267 return __r;
1268}
1269
1270template <class _Key, class _Tp, class _Compare, class _Allocator>
1271template <class _A0, class ..._Args,
1272 class //= typename enable_if<is_convertible<_A0, _Key>::value>::type
1273 >
1274typename map<_Key, _Tp, _Compare, _Allocator>::iterator
1275map<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p,
1276 _A0&& __a0, _Args&& ...__args)
1277{
1278 __node_holder __h = __construct_node(_STD::forward<_A0>(__a0),
1279 _STD::forward<_Args>(__args)...);
1280 iterator __r = __tree_.__node_insert_unique(__p.__i_, __h.get());
1281 if (__r.__i_.__ptr_ == __h.get())
1282 __h.release();
1283 return __r;
1284}
1285
Howard Hinnant73d21a42010-09-04 23:28:19 +00001286#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001287
1288template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001289inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001290bool
1291operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1292 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1293{
1294 return __x.size() == __y.size() && _STD::equal(__x.begin(), __x.end(), __y.begin());
1295}
1296
1297template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001298inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001299bool
1300operator< (const map<_Key, _Tp, _Compare, _Allocator>& __x,
1301 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1302{
1303 return _STD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1304}
1305
1306template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001307inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001308bool
1309operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1310 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1311{
1312 return !(__x == __y);
1313}
1314
1315template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001316inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001317bool
1318operator> (const map<_Key, _Tp, _Compare, _Allocator>& __x,
1319 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1320{
1321 return __y < __x;
1322}
1323
1324template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001325inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001326bool
1327operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1328 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1329{
1330 return !(__x < __y);
1331}
1332
1333template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001334inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001335bool
1336operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1337 const map<_Key, _Tp, _Compare, _Allocator>& __y)
1338{
1339 return !(__y < __x);
1340}
1341
1342template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001343inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001344void
1345swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
1346 map<_Key, _Tp, _Compare, _Allocator>& __y)
1347{
1348 __x.swap(__y);
1349}
1350
1351template <class _Key, class _Tp, class _Compare = less<_Key>,
1352 class _Allocator = allocator<pair<const _Key, _Tp> > >
Howard Hinnant82894812010-09-22 16:48:34 +00001353class _LIBCPP_VISIBLE multimap
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001354{
1355public:
1356 // types:
1357 typedef _Key key_type;
1358 typedef _Tp mapped_type;
1359 typedef pair<const key_type, mapped_type> value_type;
1360 typedef _Compare key_compare;
1361 typedef _Allocator allocator_type;
1362 typedef value_type& reference;
1363 typedef const value_type& const_reference;
1364
Howard Hinnant82894812010-09-22 16:48:34 +00001365 class _LIBCPP_VISIBLE value_compare
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001366 : public binary_function<value_type, value_type, bool>
1367 {
1368 friend class multimap;
1369 protected:
1370 key_compare comp;
1371
Howard Hinnant82894812010-09-22 16:48:34 +00001372 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001373 value_compare(key_compare c) : comp(c) {}
1374 public:
Howard Hinnant82894812010-09-22 16:48:34 +00001375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001376 bool operator()(const value_type& __x, const value_type& __y) const
1377 {return comp(__x.first, __y.first);}
1378 };
1379
1380private:
1381 typedef pair<key_type, mapped_type> __value_type;
1382 typedef __map_value_compare<key_type, mapped_type, key_compare> __vc;
1383 typedef typename allocator_traits<allocator_type>::template
1384#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1385 rebind_alloc<__value_type>
1386#else
1387 rebind_alloc<__value_type>::other
1388#endif
1389 __allocator_type;
1390 typedef __tree<__value_type, __vc, __allocator_type> __base;
1391 typedef typename __base::__node_traits __node_traits;
1392 typedef allocator_traits<allocator_type> __alloc_traits;
1393
1394 __base __tree_;
1395
1396public:
1397 typedef typename __alloc_traits::pointer pointer;
1398 typedef typename __alloc_traits::const_pointer const_pointer;
1399 typedef typename __alloc_traits::size_type size_type;
1400 typedef typename __alloc_traits::difference_type difference_type;
1401 typedef __map_iterator<typename __base::iterator> iterator;
1402 typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
1403 typedef _STD::reverse_iterator<iterator> reverse_iterator;
1404 typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
1405
Howard Hinnant82894812010-09-22 16:48:34 +00001406 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001407 explicit multimap(const key_compare& __comp = key_compare())
1408 : __tree_(__vc(__comp)) {}
1409
Howard Hinnant82894812010-09-22 16:48:34 +00001410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001411 explicit multimap(const key_compare& __comp, const allocator_type& __a)
1412 : __tree_(__vc(__comp), __a) {}
1413
1414 template <class _InputIterator>
Howard Hinnant82894812010-09-22 16:48:34 +00001415 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001416 multimap(_InputIterator __f, _InputIterator __l,
1417 const key_compare& __comp = key_compare())
1418 : __tree_(__vc(__comp))
1419 {
1420 insert(__f, __l);
1421 }
1422
1423 template <class _InputIterator>
Howard Hinnant82894812010-09-22 16:48:34 +00001424 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001425 multimap(_InputIterator __f, _InputIterator __l,
1426 const key_compare& __comp, const allocator_type& __a)
1427 : __tree_(__vc(__comp), __a)
1428 {
1429 insert(__f, __l);
1430 }
1431
Howard Hinnant82894812010-09-22 16:48:34 +00001432 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001433 multimap(const multimap& __m)
1434 : __tree_(__m.__tree_.value_comp(),
1435 __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc()))
1436 {
1437 insert(__m.begin(), __m.end());
1438 }
1439
Howard Hinnant73d21a42010-09-04 23:28:19 +00001440#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001441
Howard Hinnant82894812010-09-22 16:48:34 +00001442 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001443 multimap(multimap&& __m)
1444 : __tree_(_STD::move(__m.__tree_))
1445 {
1446 }
1447
1448 multimap(multimap&& __m, const allocator_type& __a);
1449
Howard Hinnant82894812010-09-22 16:48:34 +00001450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001451 multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
1452 : __tree_(__vc(__comp))
1453 {
1454 insert(__il.begin(), __il.end());
1455 }
1456
Howard Hinnant82894812010-09-22 16:48:34 +00001457 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001458 multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
1459 : __tree_(__vc(__comp), __a)
1460 {
1461 insert(__il.begin(), __il.end());
1462 }
1463
Howard Hinnant82894812010-09-22 16:48:34 +00001464 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001465 multimap& operator=(multimap&& __m)
1466 {
1467 __tree_ = _STD::move(__m.__tree_);
1468 return *this;
1469 }
1470
Howard Hinnant82894812010-09-22 16:48:34 +00001471 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001472 multimap& operator=(initializer_list<value_type> __il)
1473 {
1474 __tree_.__assign_multi(__il.begin(), __il.end());
1475 return *this;
1476 }
Howard Hinnantbfd55302010-09-04 23:46:48 +00001477#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001478
Howard Hinnant82894812010-09-22 16:48:34 +00001479 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001480 explicit multimap(const allocator_type& __a)
1481 : __tree_(__a)
1482 {
1483 }
1484
Howard Hinnant82894812010-09-22 16:48:34 +00001485 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001486 multimap(const multimap& __m, const allocator_type& __a)
1487 : __tree_(__m.__tree_.value_comp(), __a)
1488 {
1489 insert(__m.begin(), __m.end());
1490 }
1491
Howard Hinnant82894812010-09-22 16:48:34 +00001492 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001493 iterator begin() {return __tree_.begin();}
Howard Hinnant82894812010-09-22 16:48:34 +00001494 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001495 const_iterator begin() const {return __tree_.begin();}
Howard Hinnant82894812010-09-22 16:48:34 +00001496 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001497 iterator end() {return __tree_.end();}
Howard Hinnant82894812010-09-22 16:48:34 +00001498 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001499 const_iterator end() const {return __tree_.end();}
1500
Howard Hinnant82894812010-09-22 16:48:34 +00001501 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001502 reverse_iterator rbegin() {return reverse_iterator(end());}
Howard Hinnant82894812010-09-22 16:48:34 +00001503 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001504 const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
Howard Hinnant82894812010-09-22 16:48:34 +00001505 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001506 reverse_iterator rend() {return reverse_iterator(begin());}
Howard Hinnant82894812010-09-22 16:48:34 +00001507 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001508 const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
1509
Howard Hinnant82894812010-09-22 16:48:34 +00001510 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001511 const_iterator cbegin() const {return begin();}
Howard Hinnant82894812010-09-22 16:48:34 +00001512 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001513 const_iterator cend() const {return end();}
Howard Hinnant82894812010-09-22 16:48:34 +00001514 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001515 const_reverse_iterator crbegin() const {return rbegin();}
Howard Hinnant82894812010-09-22 16:48:34 +00001516 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001517 const_reverse_iterator crend() const {return rend();}
1518
Howard Hinnant82894812010-09-22 16:48:34 +00001519 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001520 bool empty() const {return __tree_.size() == 0;}
Howard Hinnant82894812010-09-22 16:48:34 +00001521 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001522 size_type size() const {return __tree_.size();}
Howard Hinnant82894812010-09-22 16:48:34 +00001523 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001524 size_type max_size() const {return __tree_.max_size();}
1525
Howard Hinnant82894812010-09-22 16:48:34 +00001526 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001527 allocator_type get_allocator() const {return __tree_.__alloc();}
Howard Hinnant82894812010-09-22 16:48:34 +00001528 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001529 key_compare key_comp() const {return __tree_.value_comp().key_comp();}
Howard Hinnant82894812010-09-22 16:48:34 +00001530 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001531 value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());}
1532
Howard Hinnant73d21a42010-09-04 23:28:19 +00001533#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001534
Howard Hinnant82894812010-09-22 16:48:34 +00001535 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001536 iterator emplace() {return __tree_.__emplace_multi();}
1537
1538 template <class _A0,
1539 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
Howard Hinnant82894812010-09-22 16:48:34 +00001540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001541 iterator
1542 emplace(_A0&& __a0)
1543 {return __tree_.__emplace_multi(_STD::forward<_A0>(__a0));}
1544
Howard Hinnant73d21a42010-09-04 23:28:19 +00001545#ifndef _LIBCPP_HAS_NO_VARIADICS
1546
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001547 template <class _A0, class ..._Args,
1548 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
1549 iterator
1550 emplace(_A0&& __a0, _Args&& ...__args);
1551
Howard Hinnant73d21a42010-09-04 23:28:19 +00001552#endif // _LIBCPP_HAS_NO_VARIADICS
1553
Howard Hinnant82894812010-09-22 16:48:34 +00001554 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001555 iterator emplace_hint(const_iterator __p)
1556 {return __tree_.__emplace_hint_multi(__p.__i_);}
1557
1558 template <class _A0,
1559 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
Howard Hinnant82894812010-09-22 16:48:34 +00001560 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001561 iterator
1562 emplace_hint(const_iterator __p, _A0&& __a0)
1563 {return __tree_.__emplace_hint_multi(__p.__i_, _STD::forward<_A0>(__a0));}
1564
Howard Hinnant73d21a42010-09-04 23:28:19 +00001565#ifndef _LIBCPP_HAS_NO_VARIADICS
1566
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001567 template <class _A0, class ..._Args,
1568 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
1569 iterator
1570 emplace_hint(const_iterator __p, _A0&& __a0, _Args&& ...__args);
1571
Howard Hinnant73d21a42010-09-04 23:28:19 +00001572#endif // _LIBCPP_HAS_NO_VARIADICS
1573
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001574 template <class _P,
1575 class = typename enable_if<is_convertible<_P, value_type>::value>::type>
Howard Hinnant82894812010-09-22 16:48:34 +00001576 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001577 iterator insert(_P&& __p)
1578 {return __tree_.__insert_multi(_STD::forward<_P>(__p));}
1579
1580 template <class _P,
1581 class = typename enable_if<is_convertible<_P, value_type>::value>::type>
Howard Hinnant82894812010-09-22 16:48:34 +00001582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001583 iterator insert(const_iterator __pos, _P&& __p)
1584 {return __tree_.__insert_multi(__pos.__i_, _STD::forward<_P>(__p));}
1585
Howard Hinnant73d21a42010-09-04 23:28:19 +00001586#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001587
Howard Hinnant82894812010-09-22 16:48:34 +00001588 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001589 iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);}
1590
Howard Hinnant82894812010-09-22 16:48:34 +00001591 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001592 iterator insert(const_iterator __p, const value_type& __v)
1593 {return __tree_.__insert_multi(__p.__i_, __v);}
1594
1595 template <class _InputIterator>
Howard Hinnant82894812010-09-22 16:48:34 +00001596 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001597 void insert(_InputIterator __f, _InputIterator __l)
1598 {
1599 for (const_iterator __e = cend(); __f != __l; ++__f)
1600 __tree_.__insert_multi(__e.__i_, *__f);
1601 }
1602
Howard Hinnant82894812010-09-22 16:48:34 +00001603 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001604 void insert(initializer_list<value_type> __il)
1605 {insert(__il.begin(), __il.end());}
1606
Howard Hinnant82894812010-09-22 16:48:34 +00001607 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001608 iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
Howard Hinnant82894812010-09-22 16:48:34 +00001609 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001610 size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +00001611 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001612 iterator erase(const_iterator __f, const_iterator __l)
1613 {return __tree_.erase(__f.__i_, __l.__i_);}
Howard Hinnant82894812010-09-22 16:48:34 +00001614 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001615 void clear() {__tree_.clear();}
1616
Howard Hinnant82894812010-09-22 16:48:34 +00001617 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001618 void swap(multimap& __m) {__tree_.swap(__m.__tree_);}
1619
Howard Hinnant82894812010-09-22 16:48:34 +00001620 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001621 iterator find(const key_type& __k) {return __tree_.find(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +00001622 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001623 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +00001624 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001625 size_type count(const key_type& __k) const
1626 {return __tree_.__count_multi(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +00001627 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001628 iterator lower_bound(const key_type& __k)
1629 {return __tree_.lower_bound(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +00001630 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001631 const_iterator lower_bound(const key_type& __k) const
1632 {return __tree_.lower_bound(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +00001633 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001634 iterator upper_bound(const key_type& __k)
1635 {return __tree_.upper_bound(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +00001636 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001637 const_iterator upper_bound(const key_type& __k) const
1638 {return __tree_.upper_bound(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +00001639 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001640 pair<iterator,iterator> equal_range(const key_type& __k)
1641 {return __tree_.__equal_range_multi(__k);}
Howard Hinnant82894812010-09-22 16:48:34 +00001642 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001643 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
1644 {return __tree_.__equal_range_multi(__k);}
1645
1646private:
1647 typedef typename __base::__node __node;
1648 typedef typename __base::__node_allocator __node_allocator;
1649 typedef typename __base::__node_pointer __node_pointer;
1650 typedef typename __base::__node_const_pointer __node_const_pointer;
1651 typedef __map_node_destructor<__node_allocator> _D;
1652 typedef unique_ptr<__node, _D> __node_holder;
1653
Howard Hinnant73d21a42010-09-04 23:28:19 +00001654#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001655 __node_holder __construct_node();
1656 template <class _A0,
1657 class = typename enable_if<is_convertible<_A0, value_type>::value>::type>
1658 __node_holder __construct_node(_A0&& __a0);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001659#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001660 template <class _A0, class ..._Args,
1661 class = typename enable_if<is_convertible<_A0, key_type>::value>::type>
1662 __node_holder __construct_node(_A0&& __a0, _Args&& ...__args);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001663#endif // _LIBCPP_HAS_NO_VARIADICS
1664#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001665};
1666
Howard Hinnant73d21a42010-09-04 23:28:19 +00001667#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001668
1669template <class _Key, class _Tp, class _Compare, class _Allocator>
1670multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a)
1671 : __tree_(_STD::move(__m.__tree_), __a)
1672{
1673 if (__a != __m.get_allocator())
1674 {
1675 const_iterator __e = cend();
1676 while (!__m.empty())
1677 __tree_.__insert_multi(__e.__i_,
1678 _STD::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
1679 }
1680}
1681
1682template <class _Key, class _Tp, class _Compare, class _Allocator>
1683typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
1684multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node()
1685{
1686 __node_allocator& __na = __tree_.__node_alloc();
1687 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
Howard Hinnant2529d022011-02-02 17:36:20 +00001688 __node_traits::construct(__na, _STD::addressof(__h->__value_.first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001689 __h.get_deleter().__first_constructed = true;
Howard Hinnant2529d022011-02-02 17:36:20 +00001690 __node_traits::construct(__na, _STD::addressof(__h->__value_.second));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001691 __h.get_deleter().__second_constructed = true;
1692 return __h;
1693}
1694
1695template <class _Key, class _Tp, class _Compare, class _Allocator>
1696template <class _A0,
1697 class // = typename enable_if<is_convertible<_A0, value_type>::value>::type
1698 >
1699typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
1700multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
1701{
1702 __node_allocator& __na = __tree_.__node_alloc();
1703 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
Howard Hinnant2529d022011-02-02 17:36:20 +00001704 __node_traits::construct(__na, _STD::addressof(__h->__value_), _STD::forward<_A0>(__a0));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001705 __h.get_deleter().__first_constructed = true;
1706 __h.get_deleter().__second_constructed = true;
1707 return __h;
1708}
1709
Howard Hinnant73d21a42010-09-04 23:28:19 +00001710#ifndef _LIBCPP_HAS_NO_VARIADICS
1711
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001712template <class _Key, class _Tp, class _Compare, class _Allocator>
1713template <class _A0, class ..._Args,
1714 class // = typename enable_if<is_convertible<_A0, key_type>::value>::type
1715 >
1716typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
1717multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _Args&& ...__args)
1718{
1719 __node_allocator& __na = __tree_.__node_alloc();
1720 __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
Howard Hinnant2529d022011-02-02 17:36:20 +00001721 __node_traits::construct(__na, _STD::addressof(__h->__value_.first), _STD::forward<_A0>(__a0));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001722 __h.get_deleter().__first_constructed = true;
Howard Hinnant2529d022011-02-02 17:36:20 +00001723 __node_traits::construct(__na, _STD::addressof(__h->__value_.second), _STD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001724 __h.get_deleter().__second_constructed = true;
1725 return __h;
1726}
1727
Howard Hinnant73d21a42010-09-04 23:28:19 +00001728#endif // _LIBCPP_HAS_NO_VARIADICS
1729#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001730
Howard Hinnant73d21a42010-09-04 23:28:19 +00001731#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001732
1733template <class _Key, class _Tp, class _Compare, class _Allocator>
1734template <class _A0, class ..._Args,
1735 class //= typename enable_if<is_convertible<_A0, _Key>::value>::type
1736 >
1737typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator
1738multimap<_Key, _Tp, _Compare, _Allocator>::emplace(_A0&& __a0, _Args&& ...__args)
1739{
1740 __node_holder __h = __construct_node(_STD::forward<_A0>(__a0),
1741 _STD::forward<_Args>(__args)...);
1742 iterator __r = __tree_.__node_insert_multi(__h.get());
1743 __h.release();
1744 return __r;
1745}
1746
1747template <class _Key, class _Tp, class _Compare, class _Allocator>
1748template <class _A0, class ..._Args,
1749 class //= typename enable_if<is_convertible<_A0, _Key>::value>::type
1750 >
1751typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator
1752multimap<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p,
1753 _A0&& __a0,
1754 _Args&& ...__args)
1755{
1756 __node_holder __h = __construct_node(_STD::forward<_A0>(__a0),
1757 _STD::forward<_Args>(__args)...);
1758 iterator __r = __tree_.__node_insert_multi(__p.__i_, __h.get());
1759 __h.release();
1760 return __r;
1761}
1762
Howard Hinnant73d21a42010-09-04 23:28:19 +00001763#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001764
1765template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001766inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001767bool
1768operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1769 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1770{
1771 return __x.size() == __y.size() && _STD::equal(__x.begin(), __x.end(), __y.begin());
1772}
1773
1774template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001775inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001776bool
1777operator< (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1778 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1779{
1780 return _STD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1781}
1782
1783template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001784inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001785bool
1786operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1787 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1788{
1789 return !(__x == __y);
1790}
1791
1792template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001793inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001794bool
1795operator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1796 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1797{
1798 return __y < __x;
1799}
1800
1801template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001802inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001803bool
1804operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1805 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1806{
1807 return !(__x < __y);
1808}
1809
1810template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001811inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001812bool
1813operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1814 const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1815{
1816 return !(__y < __x);
1817}
1818
1819template <class _Key, class _Tp, class _Compare, class _Allocator>
Howard Hinnant82894812010-09-22 16:48:34 +00001820inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001821void
1822swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1823 multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1824{
1825 __x.swap(__y);
1826}
1827
1828_LIBCPP_END_NAMESPACE_STD
1829
1830#endif // _LIBCPP_MAP