]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/libc++/include/map
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / libc++ / include / map
1 // -*- C++ -*-
2 //===----------------------------- map ------------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #ifndef _LIBCPP_MAP
12 #define _LIBCPP_MAP
13
14 /*
15
16     map synopsis
17
18 namespace std
19 {
20
21 template <class Key, class T, class Compare = less<Key>,
22           class Allocator = allocator<pair<const Key, T>>>
23 class map
24 {
25 public:
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         noexcept(
59             is_nothrow_default_constructible<allocator_type>::value &&
60             is_nothrow_default_constructible<key_compare>::value &&
61             is_nothrow_copy_constructible<key_compare>::value);
62     explicit map(const key_compare& comp);
63     map(const key_compare& comp, const allocator_type& a);
64     template <class InputIterator>
65         map(InputIterator first, InputIterator last,
66             const key_compare& comp = key_compare());
67     template <class InputIterator>
68         map(InputIterator first, InputIterator last,
69             const key_compare& comp, const allocator_type& a);
70     map(const map& m);
71     map(map&& m)
72         noexcept(
73             is_nothrow_move_constructible<allocator_type>::value &&
74             is_nothrow_move_constructible<key_compare>::value);
75     explicit map(const allocator_type& a);
76     map(const map& m, const allocator_type& a);
77     map(map&& m, const allocator_type& a);
78     map(initializer_list<value_type> il, const key_compare& comp = key_compare());
79     map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
80     ~map();
81
82     map& operator=(const map& m);
83     map& operator=(map&& m)
84         noexcept(
85             allocator_type::propagate_on_container_move_assignment::value &&
86             is_nothrow_move_assignable<allocator_type>::value &&
87             is_nothrow_move_assignable<key_compare>::value);
88     map& operator=(initializer_list<value_type> il);
89
90     // iterators:
91           iterator begin() noexcept;
92     const_iterator begin() const noexcept;
93           iterator end() noexcept;
94     const_iterator end()   const noexcept;
95
96           reverse_iterator rbegin() noexcept;
97     const_reverse_iterator rbegin() const noexcept;
98           reverse_iterator rend() noexcept;
99     const_reverse_iterator rend()   const noexcept;
100
101     const_iterator         cbegin()  const noexcept;
102     const_iterator         cend()    const noexcept;
103     const_reverse_iterator crbegin() const noexcept;
104     const_reverse_iterator crend()   const noexcept;
105
106     // capacity:
107     bool      empty()    const noexcept;
108     size_type size()     const noexcept;
109     size_type max_size() const noexcept;
110
111     // element access:
112     mapped_type& operator[](const key_type& k);
113     mapped_type& operator[](key_type&& k);
114
115           mapped_type& at(const key_type& k);
116     const mapped_type& at(const key_type& k) const;
117
118     // modifiers:
119     template <class... Args>
120         pair<iterator, bool> emplace(Args&&... args);
121     template <class... Args>
122         iterator emplace_hint(const_iterator position, Args&&... args);
123     pair<iterator, bool> insert(const value_type& v);
124     template <class P>
125         pair<iterator, bool> insert(P&& p);
126     iterator insert(const_iterator position, const value_type& v);
127     template <class P>
128         iterator insert(const_iterator position, P&& p);
129     template <class InputIterator>
130         void insert(InputIterator first, InputIterator last);
131     void insert(initializer_list<value_type> il);
132
133     iterator  erase(const_iterator position);
134     size_type erase(const key_type& k);
135     iterator  erase(const_iterator first, const_iterator last);
136     void clear() noexcept;
137
138     void swap(map& m)
139         noexcept(
140             __is_nothrow_swappable<key_compare>::value &&
141             (!allocator_type::propagate_on_container_swap::value ||
142              __is_nothrow_swappable<allocator_type>::value));
143
144     // observers:
145     allocator_type get_allocator() const noexcept;
146     key_compare    key_comp()      const;
147     value_compare  value_comp()    const;
148
149     // map operations:
150           iterator find(const key_type& k);
151     const_iterator find(const key_type& k) const;
152     size_type      count(const key_type& k) const;
153           iterator lower_bound(const key_type& k);
154     const_iterator lower_bound(const key_type& k) const;
155           iterator upper_bound(const key_type& k);
156     const_iterator upper_bound(const key_type& k) const;
157     pair<iterator,iterator>             equal_range(const key_type& k);
158     pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
159 };
160
161 template <class Key, class T, class Compare, class Allocator>
162 bool
163 operator==(const map<Key, T, Compare, Allocator>& x,
164            const map<Key, T, Compare, Allocator>& y);
165
166 template <class Key, class T, class Compare, class Allocator>
167 bool
168 operator< (const map<Key, T, Compare, Allocator>& x,
169            const map<Key, T, Compare, Allocator>& y);
170
171 template <class Key, class T, class Compare, class Allocator>
172 bool
173 operator!=(const map<Key, T, Compare, Allocator>& x,
174            const map<Key, T, Compare, Allocator>& y);
175
176 template <class Key, class T, class Compare, class Allocator>
177 bool
178 operator> (const map<Key, T, Compare, Allocator>& x,
179            const map<Key, T, Compare, Allocator>& y);
180
181 template <class Key, class T, class Compare, class Allocator>
182 bool
183 operator>=(const map<Key, T, Compare, Allocator>& x,
184            const map<Key, T, Compare, Allocator>& y);
185
186 template <class Key, class T, class Compare, class Allocator>
187 bool
188 operator<=(const map<Key, T, Compare, Allocator>& x,
189            const map<Key, T, Compare, Allocator>& y);
190
191 // specialized algorithms:
192 template <class Key, class T, class Compare, class Allocator>
193 void
194 swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
195     noexcept(noexcept(x.swap(y)));
196
197 template <class Key, class T, class Compare = less<Key>,
198           class Allocator = allocator<pair<const Key, T>>>
199 class multimap
200 {
201 public:
202     // types:
203     typedef Key                                      key_type;
204     typedef T                                        mapped_type;
205     typedef pair<const key_type,mapped_type>         value_type;
206     typedef Compare                                  key_compare;
207     typedef Allocator                                allocator_type;
208     typedef typename allocator_type::reference       reference;
209     typedef typename allocator_type::const_reference const_reference;
210     typedef typename allocator_type::size_type       size_type;
211     typedef typename allocator_type::difference_type difference_type;
212     typedef typename allocator_type::pointer         pointer;
213     typedef typename allocator_type::const_pointer   const_pointer;
214
215     typedef implementation-defined                   iterator;
216     typedef implementation-defined                   const_iterator;
217     typedef std::reverse_iterator<iterator>          reverse_iterator;
218     typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
219
220     class value_compare
221         : public binary_function<value_type,value_type,bool>
222     {
223         friend class multimap;
224     protected:
225         key_compare comp;
226         value_compare(key_compare c);
227     public:
228         bool operator()(const value_type& x, const value_type& y) const;
229     };
230
231     // construct/copy/destroy:
232     multimap()
233         noexcept(
234             is_nothrow_default_constructible<allocator_type>::value &&
235             is_nothrow_default_constructible<key_compare>::value &&
236             is_nothrow_copy_constructible<key_compare>::value);
237     explicit multimap(const key_compare& comp);
238     multimap(const key_compare& comp, const allocator_type& a);
239     template <class InputIterator>
240         multimap(InputIterator first, InputIterator last, const key_compare& comp);
241     template <class InputIterator>
242         multimap(InputIterator first, InputIterator last, const key_compare& comp,
243                  const allocator_type& a);
244     multimap(const multimap& m);
245     multimap(multimap&& m)
246         noexcept(
247             is_nothrow_move_constructible<allocator_type>::value &&
248             is_nothrow_move_constructible<key_compare>::value);
249     explicit multimap(const allocator_type& a);
250     multimap(const multimap& m, const allocator_type& a);
251     multimap(multimap&& m, const allocator_type& a);
252     multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());
253     multimap(initializer_list<value_type> il, const key_compare& comp,
254              const allocator_type& a);
255     ~multimap();
256
257     multimap& operator=(const multimap& m);
258     multimap& operator=(multimap&& m)
259         noexcept(
260             allocator_type::propagate_on_container_move_assignment::value &&
261             is_nothrow_move_assignable<allocator_type>::value &&
262             is_nothrow_move_assignable<key_compare>::value);
263     multimap& operator=(initializer_list<value_type> il);
264
265     // iterators:
266           iterator begin() noexcept;
267     const_iterator begin() const noexcept;
268           iterator end() noexcept;
269     const_iterator end()   const noexcept;
270
271           reverse_iterator rbegin() noexcept;
272     const_reverse_iterator rbegin() const noexcept;
273           reverse_iterator rend() noexcept;
274     const_reverse_iterator rend()   const noexcept;
275
276     const_iterator         cbegin()  const noexcept;
277     const_iterator         cend()    const noexcept;
278     const_reverse_iterator crbegin() const noexcept;
279     const_reverse_iterator crend()   const noexcept;
280
281     // capacity:
282     bool      empty()    const noexcept;
283     size_type size()     const noexcept;
284     size_type max_size() const noexcept;
285
286     // modifiers:
287     template <class... Args>
288         iterator emplace(Args&&... args);
289     template <class... Args>
290         iterator emplace_hint(const_iterator position, Args&&... args);
291     iterator insert(const value_type& v);
292     template <class P>
293         iterator insert(P&& p);
294     iterator insert(const_iterator position, const value_type& v);
295     template <class P>
296         iterator insert(const_iterator position, P&& p);
297     template <class InputIterator>
298         void insert(InputIterator first, InputIterator last);
299     void insert(initializer_list<value_type> il);
300
301     iterator  erase(const_iterator position);
302     size_type erase(const key_type& k);
303     iterator  erase(const_iterator first, const_iterator last);
304     void clear() noexcept;
305
306     void swap(multimap& m)
307         noexcept(
308             __is_nothrow_swappable<key_compare>::value &&
309             (!allocator_type::propagate_on_container_swap::value ||
310              __is_nothrow_swappable<allocator_type>::value));
311
312     // observers:
313     allocator_type get_allocator() const noexcept;
314     key_compare    key_comp()      const;
315     value_compare  value_comp()    const;
316
317     // map operations:
318           iterator find(const key_type& k);
319     const_iterator find(const key_type& k) const;
320     size_type      count(const key_type& k) const;
321           iterator lower_bound(const key_type& k);
322     const_iterator lower_bound(const key_type& k) const;
323           iterator upper_bound(const key_type& k);
324     const_iterator upper_bound(const key_type& k) const;
325     pair<iterator,iterator>             equal_range(const key_type& k);
326     pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
327 };
328
329 template <class Key, class T, class Compare, class Allocator>
330 bool
331 operator==(const multimap<Key, T, Compare, Allocator>& x,
332            const multimap<Key, T, Compare, Allocator>& y);
333
334 template <class Key, class T, class Compare, class Allocator>
335 bool
336 operator< (const multimap<Key, T, Compare, Allocator>& x,
337            const multimap<Key, T, Compare, Allocator>& y);
338
339 template <class Key, class T, class Compare, class Allocator>
340 bool
341 operator!=(const multimap<Key, T, Compare, Allocator>& x,
342            const multimap<Key, T, Compare, Allocator>& y);
343
344 template <class Key, class T, class Compare, class Allocator>
345 bool
346 operator> (const multimap<Key, T, Compare, Allocator>& x,
347            const multimap<Key, T, Compare, Allocator>& y);
348
349 template <class Key, class T, class Compare, class Allocator>
350 bool
351 operator>=(const multimap<Key, T, Compare, Allocator>& x,
352            const multimap<Key, T, Compare, Allocator>& y);
353
354 template <class Key, class T, class Compare, class Allocator>
355 bool
356 operator<=(const multimap<Key, T, Compare, Allocator>& x,
357            const multimap<Key, T, Compare, Allocator>& y);
358
359 // specialized algorithms:
360 template <class Key, class T, class Compare, class Allocator>
361 void
362 swap(multimap<Key, T, Compare, Allocator>& x,
363      multimap<Key, T, Compare, Allocator>& y)
364     noexcept(noexcept(x.swap(y)));
365
366 }  // std
367
368 */
369
370 #include <__config>
371 #include <__tree>
372 #include <iterator>
373 #include <memory>
374 #include <utility>
375 #include <functional>
376 #include <initializer_list>
377
378 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
379 #pragma GCC system_header
380 #endif
381
382 _LIBCPP_BEGIN_NAMESPACE_STD
383
384 template <class _Key, class _CP, class _Compare, bool = is_empty<_Compare>::value
385 #if __has_feature(is_final)
386                                                         && !__is_final(_Compare)
387 #endif
388          >
389 class __map_value_compare
390     : private _Compare
391 {
392 public:
393     _LIBCPP_INLINE_VISIBILITY
394     __map_value_compare()
395         _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
396         : _Compare() {}
397     _LIBCPP_INLINE_VISIBILITY
398     __map_value_compare(_Compare c)
399         _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
400         : _Compare(c) {}
401     _LIBCPP_INLINE_VISIBILITY
402     const _Compare& key_comp() const _NOEXCEPT {return *this;}
403     _LIBCPP_INLINE_VISIBILITY
404     bool operator()(const _CP& __x, const _CP& __y) const
405         {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y.__cc.first);}
406     _LIBCPP_INLINE_VISIBILITY
407     bool operator()(const _CP& __x, const _Key& __y) const
408         {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y);}
409     _LIBCPP_INLINE_VISIBILITY
410     bool operator()(const _Key& __x, const _CP& __y) const
411         {return static_cast<const _Compare&>(*this)(__x, __y.__cc.first);}
412 };
413
414 template <class _Key, class _CP, class _Compare>
415 class __map_value_compare<_Key, _CP, _Compare, false>
416 {
417     _Compare comp;
418
419 public:
420     _LIBCPP_INLINE_VISIBILITY
421     __map_value_compare()
422         _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
423         : comp() {}
424     _LIBCPP_INLINE_VISIBILITY
425     __map_value_compare(_Compare c)
426         _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
427         : comp(c) {}
428     _LIBCPP_INLINE_VISIBILITY
429     const _Compare& key_comp() const _NOEXCEPT {return comp;}
430
431     _LIBCPP_INLINE_VISIBILITY
432     bool operator()(const _CP& __x, const _CP& __y) const
433         {return comp(__x.__cc.first, __y.__cc.first);}
434     _LIBCPP_INLINE_VISIBILITY
435     bool operator()(const _CP& __x, const _Key& __y) const
436         {return comp(__x.__cc.first, __y);}
437     _LIBCPP_INLINE_VISIBILITY
438     bool operator()(const _Key& __x, const _CP& __y) const
439         {return comp(__x, __y.__cc.first);}
440 };
441
442 template <class _Allocator>
443 class __map_node_destructor
444 {
445     typedef _Allocator                          allocator_type;
446     typedef allocator_traits<allocator_type>    __alloc_traits;
447     typedef typename __alloc_traits::value_type::value_type value_type;
448 public:
449     typedef typename __alloc_traits::pointer    pointer;
450 private:
451     typedef typename value_type::value_type::first_type     first_type;
452     typedef typename value_type::value_type::second_type    second_type;
453
454     allocator_type& __na_;
455
456     __map_node_destructor& operator=(const __map_node_destructor&);
457
458 public:
459     bool __first_constructed;
460     bool __second_constructed;
461
462     _LIBCPP_INLINE_VISIBILITY
463     explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT
464         : __na_(__na),
465           __first_constructed(false),
466           __second_constructed(false)
467         {}
468
469 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
470     _LIBCPP_INLINE_VISIBILITY
471     __map_node_destructor(__tree_node_destructor<allocator_type>&& __x) _NOEXCEPT
472         : __na_(__x.__na_),
473           __first_constructed(__x.__value_constructed),
474           __second_constructed(__x.__value_constructed)
475         {
476             __x.__value_constructed = false;
477         }
478 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
479
480     _LIBCPP_INLINE_VISIBILITY
481     void operator()(pointer __p) _NOEXCEPT
482     {
483         if (__second_constructed)
484             __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second));
485         if (__first_constructed)
486             __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first));
487         if (__p)
488             __alloc_traits::deallocate(__na_, __p, 1);
489     }
490 };
491
492 template <class _Key, class _Tp, class _Compare, class _Allocator>
493     class map;
494 template <class _Key, class _Tp, class _Compare, class _Allocator>
495     class multimap;
496 template <class _TreeIterator> class __map_const_iterator;
497
498 template <class _TreeIterator>
499 class _LIBCPP_TYPE_VIS __map_iterator
500 {
501     _TreeIterator __i_;
502
503     typedef typename _TreeIterator::__pointer_traits             __pointer_traits;
504     typedef const typename _TreeIterator::value_type::value_type::first_type __key_type;
505     typedef typename _TreeIterator::value_type::value_type::second_type      __mapped_type;
506 public:
507     typedef bidirectional_iterator_tag                           iterator_category;
508     typedef pair<__key_type, __mapped_type>                      value_type;
509     typedef typename _TreeIterator::difference_type              difference_type;
510     typedef value_type&                                          reference;
511     typedef typename __pointer_traits::template
512 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
513             rebind<value_type>
514 #else
515             rebind<value_type>::other
516 #endif
517                                                                  pointer;
518
519     _LIBCPP_INLINE_VISIBILITY
520     __map_iterator() _NOEXCEPT {}
521
522     _LIBCPP_INLINE_VISIBILITY
523     __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
524
525     _LIBCPP_INLINE_VISIBILITY
526     reference operator*() const {return __i_->__cc;}
527     _LIBCPP_INLINE_VISIBILITY
528     pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
529
530     _LIBCPP_INLINE_VISIBILITY
531     __map_iterator& operator++() {++__i_; return *this;}
532     _LIBCPP_INLINE_VISIBILITY
533     __map_iterator operator++(int)
534     {
535         __map_iterator __t(*this);
536         ++(*this);
537         return __t;
538     }
539
540     _LIBCPP_INLINE_VISIBILITY
541     __map_iterator& operator--() {--__i_; return *this;}
542     _LIBCPP_INLINE_VISIBILITY
543     __map_iterator operator--(int)
544     {
545         __map_iterator __t(*this);
546         --(*this);
547         return __t;
548     }
549
550     friend _LIBCPP_INLINE_VISIBILITY
551     bool operator==(const __map_iterator& __x, const __map_iterator& __y)
552         {return __x.__i_ == __y.__i_;}
553     friend 
554     _LIBCPP_INLINE_VISIBILITY
555     bool operator!=(const __map_iterator& __x, const __map_iterator& __y)
556         {return __x.__i_ != __y.__i_;}
557
558     template <class, class, class, class> friend class _LIBCPP_TYPE_VIS map;
559     template <class, class, class, class> friend class _LIBCPP_TYPE_VIS multimap;
560     template <class> friend class _LIBCPP_TYPE_VIS __map_const_iterator;
561 };
562
563 template <class _TreeIterator>
564 class _LIBCPP_TYPE_VIS __map_const_iterator
565 {
566     _TreeIterator __i_;
567
568     typedef typename _TreeIterator::__pointer_traits             __pointer_traits;
569     typedef const typename _TreeIterator::value_type::value_type::first_type __key_type;
570     typedef typename _TreeIterator::value_type::value_type::second_type      __mapped_type;
571 public:
572     typedef bidirectional_iterator_tag                           iterator_category;
573     typedef pair<__key_type, __mapped_type>                      value_type;
574     typedef typename _TreeIterator::difference_type              difference_type;
575     typedef const value_type&                                    reference;
576     typedef typename __pointer_traits::template
577 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
578             rebind<const value_type>
579 #else
580             rebind<const value_type>::other
581 #endif
582                                                                  pointer;
583
584     _LIBCPP_INLINE_VISIBILITY
585     __map_const_iterator() _NOEXCEPT {}
586
587     _LIBCPP_INLINE_VISIBILITY
588     __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
589     _LIBCPP_INLINE_VISIBILITY
590     __map_const_iterator(
591             __map_iterator<typename _TreeIterator::__non_const_iterator> __i)
592                 _NOEXCEPT
593                 : __i_(__i.__i_) {}
594
595     _LIBCPP_INLINE_VISIBILITY
596     reference operator*() const {return __i_->__cc;}
597     _LIBCPP_INLINE_VISIBILITY
598     pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
599
600     _LIBCPP_INLINE_VISIBILITY
601     __map_const_iterator& operator++() {++__i_; return *this;}
602     _LIBCPP_INLINE_VISIBILITY
603     __map_const_iterator operator++(int)
604     {
605         __map_const_iterator __t(*this);
606         ++(*this);
607         return __t;
608     }
609
610     _LIBCPP_INLINE_VISIBILITY
611     __map_const_iterator& operator--() {--__i_; return *this;}
612     _LIBCPP_INLINE_VISIBILITY
613     __map_const_iterator operator--(int)
614     {
615         __map_const_iterator __t(*this);
616         --(*this);
617         return __t;
618     }
619
620     friend _LIBCPP_INLINE_VISIBILITY
621     bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y)
622         {return __x.__i_ == __y.__i_;}
623     friend _LIBCPP_INLINE_VISIBILITY
624     bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y)
625         {return __x.__i_ != __y.__i_;}
626
627     template <class, class, class, class> friend class _LIBCPP_TYPE_VIS map;
628     template <class, class, class, class> friend class _LIBCPP_TYPE_VIS multimap;
629     template <class, class, class> friend class _LIBCPP_TYPE_VIS __tree_const_iterator;
630 };
631
632 template <class _Key, class _Tp, class _Compare = less<_Key>,
633           class _Allocator = allocator<pair<const _Key, _Tp> > >
634 class _LIBCPP_TYPE_VIS map
635 {
636 public:
637     // types:
638     typedef _Key                                     key_type;
639     typedef _Tp                                      mapped_type;
640     typedef pair<const key_type, mapped_type>        value_type;
641     typedef pair<key_type, mapped_type>              __nc_value_type;
642     typedef _Compare                                 key_compare;
643     typedef _Allocator                               allocator_type;
644     typedef value_type&                              reference;
645     typedef const value_type&                        const_reference;
646
647     class _LIBCPP_TYPE_VIS value_compare
648         : public binary_function<value_type, value_type, bool>
649     {
650         friend class map;
651     protected:
652         key_compare comp;
653
654         _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {}
655     public:
656         _LIBCPP_INLINE_VISIBILITY
657         bool operator()(const value_type& __x, const value_type& __y) const
658             {return comp(__x.first, __y.first);}
659     };
660
661 private:
662
663 #if __cplusplus >= 201103L
664     union __value_type
665     {
666         typedef typename map::value_type value_type;
667         typedef typename map::__nc_value_type __nc_value_type;
668         value_type __cc;
669         __nc_value_type __nc;
670
671         template <class ..._Args>
672         __value_type(_Args&& ...__args)
673             : __cc(std::forward<_Args>(__args)...) {}
674
675         __value_type(const __value_type& __v)
676             : __cc(std::move(__v.__cc)) {}
677
678         __value_type(__value_type&& __v)
679             : __nc(std::move(__v.__nc)) {}
680
681         __value_type& operator=(const __value_type& __v)
682             {__nc = __v.__cc; return *this;}
683
684         __value_type& operator=(__value_type&& __v)
685             {__nc = std::move(__v.__nc); return *this;}
686
687         ~__value_type() {__cc.~value_type();}
688     };
689 #else
690     struct __value_type
691     {
692         typedef typename map::value_type value_type;
693         value_type __cc;
694
695         __value_type() {}
696
697         template <class _A0>
698         __value_type(const _A0& __a0)
699             : __cc(__a0) {}
700
701         template <class _A0, class _A1>
702         __value_type(const _A0& __a0, const _A1& __a1)
703             : __cc(__a0, __a1) {}
704     };
705 #endif
706     typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
707     typedef typename allocator_traits<allocator_type>::template
708 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
709             rebind_alloc<__value_type>
710 #else
711             rebind_alloc<__value_type>::other
712 #endif
713                                                            __allocator_type;
714     typedef __tree<__value_type, __vc, __allocator_type>   __base;
715     typedef typename __base::__node_traits                 __node_traits;
716     typedef allocator_traits<allocator_type>               __alloc_traits;
717
718     __base __tree_;
719
720 public:
721     typedef typename __alloc_traits::pointer               pointer;
722     typedef typename __alloc_traits::const_pointer         const_pointer;
723     typedef typename __alloc_traits::size_type             size_type;
724     typedef typename __alloc_traits::difference_type       difference_type;
725     typedef __map_iterator<typename __base::iterator>      iterator;
726     typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
727     typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
728     typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;
729
730     _LIBCPP_INLINE_VISIBILITY
731     explicit map(const key_compare& __comp = key_compare())
732         _NOEXCEPT_(
733             is_nothrow_default_constructible<allocator_type>::value &&
734             is_nothrow_default_constructible<key_compare>::value &&
735             is_nothrow_copy_constructible<key_compare>::value)
736         : __tree_(__vc(__comp)) {}
737
738     _LIBCPP_INLINE_VISIBILITY
739     explicit map(const key_compare& __comp, const allocator_type& __a)
740         : __tree_(__vc(__comp), __a) {}
741
742     template <class _InputIterator>
743     _LIBCPP_INLINE_VISIBILITY
744         map(_InputIterator __f, _InputIterator __l,
745             const key_compare& __comp = key_compare())
746         : __tree_(__vc(__comp))
747         {
748             insert(__f, __l);
749         }
750
751     template <class _InputIterator>
752     _LIBCPP_INLINE_VISIBILITY
753         map(_InputIterator __f, _InputIterator __l,
754             const key_compare& __comp, const allocator_type& __a)
755         : __tree_(__vc(__comp), __a)
756         {
757             insert(__f, __l);
758         }
759
760     _LIBCPP_INLINE_VISIBILITY
761     map(const map& __m)
762         : __tree_(__m.__tree_)
763         {
764             insert(__m.begin(), __m.end());
765         }
766
767     _LIBCPP_INLINE_VISIBILITY
768     map& operator=(const map& __m)
769         {
770 #if __cplusplus >= 201103L
771             __tree_ = __m.__tree_;
772 #else
773             __tree_.clear();
774             __tree_.value_comp() = __m.__tree_.value_comp();
775             __tree_.__copy_assign_alloc(__m.__tree_);
776             insert(__m.begin(), __m.end());
777 #endif
778             return *this;
779         }
780
781 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
782
783     _LIBCPP_INLINE_VISIBILITY
784     map(map&& __m)
785         _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
786         : __tree_(_VSTD::move(__m.__tree_))
787         {
788         }
789
790     map(map&& __m, const allocator_type& __a);
791
792     _LIBCPP_INLINE_VISIBILITY
793     map& operator=(map&& __m)
794         _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
795         {
796             __tree_ = _VSTD::move(__m.__tree_);
797             return *this;
798         }
799
800 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
801
802 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
803
804     _LIBCPP_INLINE_VISIBILITY
805     map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
806         : __tree_(__vc(__comp))
807         {
808             insert(__il.begin(), __il.end());
809         }
810
811     _LIBCPP_INLINE_VISIBILITY
812     map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
813         : __tree_(__vc(__comp), __a)
814         {
815             insert(__il.begin(), __il.end());
816         }
817
818     _LIBCPP_INLINE_VISIBILITY
819     map& operator=(initializer_list<value_type> __il)
820         {
821             __tree_.__assign_unique(__il.begin(), __il.end());
822             return *this;
823         }
824
825 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
826
827     _LIBCPP_INLINE_VISIBILITY
828     explicit map(const allocator_type& __a)
829         : __tree_(__a)
830         {
831         }
832
833     _LIBCPP_INLINE_VISIBILITY
834     map(const map& __m, const allocator_type& __a)
835         : __tree_(__m.__tree_.value_comp(), __a)
836         {
837             insert(__m.begin(), __m.end());
838         }
839
840     _LIBCPP_INLINE_VISIBILITY
841           iterator begin() _NOEXCEPT {return __tree_.begin();}
842     _LIBCPP_INLINE_VISIBILITY
843     const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
844     _LIBCPP_INLINE_VISIBILITY
845           iterator end() _NOEXCEPT {return __tree_.end();}
846     _LIBCPP_INLINE_VISIBILITY
847     const_iterator end() const _NOEXCEPT {return __tree_.end();}
848
849     _LIBCPP_INLINE_VISIBILITY
850           reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
851     _LIBCPP_INLINE_VISIBILITY
852     const_reverse_iterator rbegin() const _NOEXCEPT
853         {return const_reverse_iterator(end());}
854     _LIBCPP_INLINE_VISIBILITY
855           reverse_iterator rend() _NOEXCEPT
856             {return       reverse_iterator(begin());}
857     _LIBCPP_INLINE_VISIBILITY
858     const_reverse_iterator rend() const _NOEXCEPT
859         {return const_reverse_iterator(begin());}
860
861     _LIBCPP_INLINE_VISIBILITY
862     const_iterator cbegin() const _NOEXCEPT {return begin();}
863     _LIBCPP_INLINE_VISIBILITY
864     const_iterator cend() const _NOEXCEPT {return end();}
865     _LIBCPP_INLINE_VISIBILITY
866     const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
867     _LIBCPP_INLINE_VISIBILITY
868     const_reverse_iterator crend() const _NOEXCEPT {return rend();}
869
870     _LIBCPP_INLINE_VISIBILITY
871     bool      empty() const _NOEXCEPT {return __tree_.size() == 0;}
872     _LIBCPP_INLINE_VISIBILITY
873     size_type size() const _NOEXCEPT {return __tree_.size();}
874     _LIBCPP_INLINE_VISIBILITY
875     size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
876
877     mapped_type& operator[](const key_type& __k);
878 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
879     mapped_type& operator[](key_type&& __k);
880 #endif
881
882           mapped_type& at(const key_type& __k);
883     const mapped_type& at(const key_type& __k) const;
884
885     _LIBCPP_INLINE_VISIBILITY
886     allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}
887     _LIBCPP_INLINE_VISIBILITY
888     key_compare    key_comp()      const {return __tree_.value_comp().key_comp();}
889     _LIBCPP_INLINE_VISIBILITY
890     value_compare  value_comp()    const {return value_compare(__tree_.value_comp().key_comp());}
891
892 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
893 #ifndef _LIBCPP_HAS_NO_VARIADICS
894
895     template <class ..._Args>
896         pair<iterator, bool>
897         emplace(_Args&& ...__args);
898
899     template <class ..._Args>
900         iterator
901         emplace_hint(const_iterator __p, _Args&& ...__args);
902
903 #endif  // _LIBCPP_HAS_NO_VARIADICS
904
905     template <class _Pp,
906               class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
907         _LIBCPP_INLINE_VISIBILITY
908         pair<iterator, bool> insert(_Pp&& __p)
909             {return __tree_.__insert_unique(_VSTD::forward<_Pp>(__p));}
910
911     template <class _Pp,
912               class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
913         _LIBCPP_INLINE_VISIBILITY
914         iterator insert(const_iterator __pos, _Pp&& __p)
915             {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));}
916
917 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
918
919     _LIBCPP_INLINE_VISIBILITY
920     pair<iterator, bool>
921         insert(const value_type& __v) {return __tree_.__insert_unique(__v);}
922
923     _LIBCPP_INLINE_VISIBILITY
924     iterator
925         insert(const_iterator __p, const value_type& __v)
926             {return __tree_.__insert_unique(__p.__i_, __v);}
927
928     template <class _InputIterator>
929         _LIBCPP_INLINE_VISIBILITY
930         void insert(_InputIterator __f, _InputIterator __l)
931         {
932             for (const_iterator __e = cend(); __f != __l; ++__f)
933                 insert(__e.__i_, *__f);
934         }
935
936 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
937
938     _LIBCPP_INLINE_VISIBILITY
939     void insert(initializer_list<value_type> __il)
940         {insert(__il.begin(), __il.end());}
941
942 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
943
944     _LIBCPP_INLINE_VISIBILITY
945     iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
946     _LIBCPP_INLINE_VISIBILITY
947     size_type erase(const key_type& __k)
948         {return __tree_.__erase_unique(__k);}
949     _LIBCPP_INLINE_VISIBILITY
950     iterator  erase(const_iterator __f, const_iterator __l)
951         {return __tree_.erase(__f.__i_, __l.__i_);}
952     _LIBCPP_INLINE_VISIBILITY
953     void clear() _NOEXCEPT {__tree_.clear();}
954
955     _LIBCPP_INLINE_VISIBILITY
956     void swap(map& __m)
957         _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
958         {__tree_.swap(__m.__tree_);}
959
960     _LIBCPP_INLINE_VISIBILITY
961     iterator find(const key_type& __k)             {return __tree_.find(__k);}
962     _LIBCPP_INLINE_VISIBILITY
963     const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
964     _LIBCPP_INLINE_VISIBILITY
965     size_type      count(const key_type& __k) const
966         {return __tree_.__count_unique(__k);}
967     _LIBCPP_INLINE_VISIBILITY
968     iterator lower_bound(const key_type& __k)
969         {return __tree_.lower_bound(__k);}
970     _LIBCPP_INLINE_VISIBILITY
971     const_iterator lower_bound(const key_type& __k) const
972         {return __tree_.lower_bound(__k);}
973     _LIBCPP_INLINE_VISIBILITY
974     iterator upper_bound(const key_type& __k)
975         {return __tree_.upper_bound(__k);}
976     _LIBCPP_INLINE_VISIBILITY
977     const_iterator upper_bound(const key_type& __k) const
978         {return __tree_.upper_bound(__k);}
979     _LIBCPP_INLINE_VISIBILITY
980     pair<iterator,iterator> equal_range(const key_type& __k)
981         {return __tree_.__equal_range_unique(__k);}
982     _LIBCPP_INLINE_VISIBILITY
983     pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
984         {return __tree_.__equal_range_unique(__k);}
985
986 private:
987     typedef typename __base::__node                    __node;
988     typedef typename __base::__node_allocator          __node_allocator;
989     typedef typename __base::__node_pointer            __node_pointer;
990     typedef typename __base::__node_const_pointer      __node_const_pointer;
991     typedef typename __base::__node_base_pointer       __node_base_pointer;
992     typedef typename __base::__node_base_const_pointer __node_base_const_pointer;
993     typedef __map_node_destructor<__node_allocator> _Dp;
994     typedef unique_ptr<__node, _Dp> __node_holder;
995
996 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
997     __node_holder __construct_node();
998     template <class _A0>
999         __node_holder __construct_node(_A0&& __a0);
1000     __node_holder __construct_node_with_key(key_type&& __k);
1001 #ifndef _LIBCPP_HAS_NO_VARIADICS
1002     template <class _A0, class _A1, class ..._Args>
1003         __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
1004 #endif  // _LIBCPP_HAS_NO_VARIADICS
1005 #endif
1006     __node_holder __construct_node_with_key(const key_type& __k);
1007
1008     __node_base_pointer&
1009         __find_equal_key(__node_base_pointer& __parent, const key_type& __k);
1010     __node_base_const_pointer
1011         __find_equal_key(__node_base_const_pointer& __parent, const key_type& __k) const;
1012 };
1013
1014 // Find place to insert if __k doesn't exist
1015 // Set __parent to parent of null leaf
1016 // Return reference to null leaf
1017 // If __k exists, set parent to node of __k and return reference to node of __k
1018 template <class _Key, class _Tp, class _Compare, class _Allocator>
1019 typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer&
1020 map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __parent,
1021                                                        const key_type& __k)
1022 {
1023     __node_pointer __nd = __tree_.__root();
1024     if (__nd != nullptr)
1025     {
1026         while (true)
1027         {
1028             if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))
1029             {
1030                 if (__nd->__left_ != nullptr)
1031                     __nd = static_cast<__node_pointer>(__nd->__left_);
1032                 else
1033                 {
1034                     __parent = static_cast<__node_base_pointer>(__nd);
1035                     return __parent->__left_;
1036                 }
1037             }
1038             else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k))
1039             {
1040                 if (__nd->__right_ != nullptr)
1041                     __nd = static_cast<__node_pointer>(__nd->__right_);
1042                 else
1043                 {
1044                     __parent = static_cast<__node_base_pointer>(__nd);
1045                     return __parent->__right_;
1046                 }
1047             }
1048             else
1049             {
1050                 __parent = static_cast<__node_base_pointer>(__nd);
1051                 return __parent;
1052             }
1053         }
1054     }
1055     __parent = static_cast<__node_base_pointer>(__tree_.__end_node());
1056     return __parent->__left_;
1057 }
1058
1059 // Find __k
1060 // Set __parent to parent of null leaf and
1061 //    return reference to null leaf iv __k does not exist.
1062 // If __k exists, set parent to node of __k and return reference to node of __k
1063 template <class _Key, class _Tp, class _Compare, class _Allocator>
1064 typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_const_pointer
1065 map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer& __parent,
1066                                                        const key_type& __k) const
1067 {
1068     __node_const_pointer __nd = __tree_.__root();
1069     if (__nd != nullptr)
1070     {
1071         while (true)
1072         {
1073             if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))
1074             {
1075                 if (__nd->__left_ != nullptr)
1076                     __nd = static_cast<__node_pointer>(__nd->__left_);
1077                 else
1078                 {
1079                     __parent = static_cast<__node_base_pointer>(__nd);
1080                     return const_cast<const __node_base_const_pointer&>(__parent->__left_);
1081                 }
1082             }
1083             else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k))
1084             {
1085                 if (__nd->__right_ != nullptr)
1086                     __nd = static_cast<__node_pointer>(__nd->__right_);
1087                 else
1088                 {
1089                     __parent = static_cast<__node_base_pointer>(__nd);
1090                     return const_cast<const __node_base_const_pointer&>(__parent->__right_);
1091                 }
1092             }
1093             else
1094             {
1095                 __parent = static_cast<__node_base_pointer>(__nd);
1096                 return __parent;
1097             }
1098         }
1099     }
1100     __parent = static_cast<__node_base_pointer>(__tree_.__end_node());
1101     return const_cast<const __node_base_const_pointer&>(__parent->__left_);
1102 }
1103
1104 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1105
1106 template <class _Key, class _Tp, class _Compare, class _Allocator>
1107 map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
1108     : __tree_(_VSTD::move(__m.__tree_), __a)
1109 {
1110     if (__a != __m.get_allocator())
1111     {
1112         const_iterator __e = cend();
1113         while (!__m.empty())
1114             __tree_.__insert_unique(__e.__i_,
1115                     _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
1116     }
1117 }
1118
1119 template <class _Key, class _Tp, class _Compare, class _Allocator>
1120 typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1121 map<_Key, _Tp, _Compare, _Allocator>::__construct_node()
1122 {
1123     __node_allocator& __na = __tree_.__node_alloc();
1124     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1125     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first));
1126     __h.get_deleter().__first_constructed = true;
1127     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
1128     __h.get_deleter().__second_constructed = true;
1129     return __h;
1130 }
1131
1132 template <class _Key, class _Tp, class _Compare, class _Allocator>
1133 template <class _A0>
1134 typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1135 map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
1136 {
1137     __node_allocator& __na = __tree_.__node_alloc();
1138     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1139     __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0));
1140     __h.get_deleter().__first_constructed = true;
1141     __h.get_deleter().__second_constructed = true;
1142     return __h;
1143 }
1144
1145 template <class _Key, class _Tp, class _Compare, class _Allocator>
1146 typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1147 map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(key_type&& __k)
1148 {
1149     __node_allocator& __na = __tree_.__node_alloc();
1150     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1151     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k));
1152     __h.get_deleter().__first_constructed = true;
1153     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
1154     __h.get_deleter().__second_constructed = true;
1155     return _VSTD::move(__h);
1156 }
1157
1158 #ifndef _LIBCPP_HAS_NO_VARIADICS
1159
1160 template <class _Key, class _Tp, class _Compare, class _Allocator>
1161 template <class _A0, class _A1, class ..._Args>
1162 typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1163 map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args)
1164 {
1165     __node_allocator& __na = __tree_.__node_alloc();
1166     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1167     __node_traits::construct(__na, _VSTD::addressof(__h->__value_),
1168                              _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),
1169                              _VSTD::forward<_Args>(__args)...);
1170     __h.get_deleter().__first_constructed = true;
1171     __h.get_deleter().__second_constructed = true;
1172     return __h;
1173 }
1174
1175 #endif  // _LIBCPP_HAS_NO_VARIADICS
1176
1177 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1178
1179 template <class _Key, class _Tp, class _Compare, class _Allocator>
1180 typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1181 map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k)
1182 {
1183     __node_allocator& __na = __tree_.__node_alloc();
1184     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1185     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k);
1186     __h.get_deleter().__first_constructed = true;
1187     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
1188     __h.get_deleter().__second_constructed = true;
1189     return _VSTD::move(__h);
1190 }
1191
1192 template <class _Key, class _Tp, class _Compare, class _Allocator>
1193 _Tp&
1194 map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
1195 {
1196     __node_base_pointer __parent;
1197     __node_base_pointer& __child = __find_equal_key(__parent, __k);
1198     __node_pointer __r = static_cast<__node_pointer>(__child);
1199     if (__child == nullptr)
1200     {
1201         __node_holder __h = __construct_node_with_key(__k);
1202         __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1203         __r = __h.release();
1204     }
1205     return __r->__value_.__cc.second;
1206 }
1207
1208 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1209
1210 template <class _Key, class _Tp, class _Compare, class _Allocator>
1211 _Tp&
1212 map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k)
1213 {
1214     __node_base_pointer __parent;
1215     __node_base_pointer& __child = __find_equal_key(__parent, __k);
1216     __node_pointer __r = static_cast<__node_pointer>(__child);
1217     if (__child == nullptr)
1218     {
1219         __node_holder __h = __construct_node_with_key(_VSTD::move(__k));
1220         __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
1221         __r = __h.release();
1222     }
1223     return __r->__value_.__cc.second;
1224 }
1225
1226 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1227
1228 template <class _Key, class _Tp, class _Compare, class _Allocator>
1229 _Tp&
1230 map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k)
1231 {
1232     __node_base_pointer __parent;
1233     __node_base_pointer& __child = __find_equal_key(__parent, __k);
1234 #ifndef _LIBCPP_NO_EXCEPTIONS
1235     if (__child == nullptr)
1236         throw out_of_range("map::at:  key not found");
1237 #endif  // _LIBCPP_NO_EXCEPTIONS
1238     return static_cast<__node_pointer>(__child)->__value_.__cc.second;
1239 }
1240
1241 template <class _Key, class _Tp, class _Compare, class _Allocator>
1242 const _Tp&
1243 map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const
1244 {
1245     __node_base_const_pointer __parent;
1246     __node_base_const_pointer __child = __find_equal_key(__parent, __k);
1247 #ifndef _LIBCPP_NO_EXCEPTIONS
1248     if (__child == nullptr)
1249         throw out_of_range("map::at:  key not found");
1250 #endif  // _LIBCPP_NO_EXCEPTIONS
1251     return static_cast<__node_const_pointer>(__child)->__value_.__cc.second;
1252 }
1253
1254 #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
1255
1256 template <class _Key, class _Tp, class _Compare, class _Allocator>
1257 template <class ..._Args>
1258 pair<typename map<_Key, _Tp, _Compare, _Allocator>::iterator, bool>
1259 map<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args)
1260 {
1261     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
1262     pair<iterator, bool> __r = __tree_.__node_insert_unique(__h.get());
1263     if (__r.second)
1264         __h.release();
1265     return __r;
1266 }
1267
1268 template <class _Key, class _Tp, class _Compare, class _Allocator>
1269 template <class ..._Args>
1270 typename map<_Key, _Tp, _Compare, _Allocator>::iterator
1271 map<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p,
1272                                                    _Args&& ...__args)
1273 {
1274     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
1275     iterator __r = __tree_.__node_insert_unique(__p.__i_, __h.get());
1276     if (__r.__i_.__ptr_ == __h.get())
1277         __h.release();
1278     return __r;
1279 }
1280
1281 #endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
1282
1283 template <class _Key, class _Tp, class _Compare, class _Allocator>
1284 inline _LIBCPP_INLINE_VISIBILITY
1285 bool
1286 operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1287            const map<_Key, _Tp, _Compare, _Allocator>& __y)
1288 {
1289     return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
1290 }
1291
1292 template <class _Key, class _Tp, class _Compare, class _Allocator>
1293 inline _LIBCPP_INLINE_VISIBILITY
1294 bool
1295 operator< (const map<_Key, _Tp, _Compare, _Allocator>& __x,
1296            const map<_Key, _Tp, _Compare, _Allocator>& __y)
1297 {
1298     return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1299 }
1300
1301 template <class _Key, class _Tp, class _Compare, class _Allocator>
1302 inline _LIBCPP_INLINE_VISIBILITY
1303 bool
1304 operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1305            const map<_Key, _Tp, _Compare, _Allocator>& __y)
1306 {
1307     return !(__x == __y);
1308 }
1309
1310 template <class _Key, class _Tp, class _Compare, class _Allocator>
1311 inline _LIBCPP_INLINE_VISIBILITY
1312 bool
1313 operator> (const map<_Key, _Tp, _Compare, _Allocator>& __x,
1314            const map<_Key, _Tp, _Compare, _Allocator>& __y)
1315 {
1316     return __y < __x;
1317 }
1318
1319 template <class _Key, class _Tp, class _Compare, class _Allocator>
1320 inline _LIBCPP_INLINE_VISIBILITY
1321 bool
1322 operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1323            const map<_Key, _Tp, _Compare, _Allocator>& __y)
1324 {
1325     return !(__x < __y);
1326 }
1327
1328 template <class _Key, class _Tp, class _Compare, class _Allocator>
1329 inline _LIBCPP_INLINE_VISIBILITY
1330 bool
1331 operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1332            const map<_Key, _Tp, _Compare, _Allocator>& __y)
1333 {
1334     return !(__y < __x);
1335 }
1336
1337 template <class _Key, class _Tp, class _Compare, class _Allocator>
1338 inline _LIBCPP_INLINE_VISIBILITY
1339 void
1340 swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
1341      map<_Key, _Tp, _Compare, _Allocator>& __y)
1342     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1343 {
1344     __x.swap(__y);
1345 }
1346
1347 template <class _Key, class _Tp, class _Compare = less<_Key>,
1348           class _Allocator = allocator<pair<const _Key, _Tp> > >
1349 class _LIBCPP_TYPE_VIS multimap
1350 {
1351 public:
1352     // types:
1353     typedef _Key                                     key_type;
1354     typedef _Tp                                      mapped_type;
1355     typedef pair<const key_type, mapped_type>        value_type;
1356     typedef pair<key_type, mapped_type>              __nc_value_type;
1357     typedef _Compare                                 key_compare;
1358     typedef _Allocator                               allocator_type;
1359     typedef value_type&                              reference;
1360     typedef const value_type&                        const_reference;
1361
1362     class _LIBCPP_TYPE_VIS value_compare
1363         : public binary_function<value_type, value_type, bool>
1364     {
1365         friend class multimap;
1366     protected:
1367         key_compare comp;
1368
1369         _LIBCPP_INLINE_VISIBILITY
1370         value_compare(key_compare c) : comp(c) {}
1371     public:
1372         _LIBCPP_INLINE_VISIBILITY
1373         bool operator()(const value_type& __x, const value_type& __y) const
1374             {return comp(__x.first, __y.first);}
1375     };
1376
1377 private:
1378 #if __cplusplus >= 201103L
1379     union __value_type
1380     {
1381         typedef typename multimap::value_type value_type;
1382         typedef typename multimap::__nc_value_type __nc_value_type;
1383         value_type __cc;
1384         __nc_value_type __nc;
1385
1386         template <class ..._Args>
1387         __value_type(_Args&& ...__args)
1388             : __cc(std::forward<_Args>(__args)...) {}
1389
1390         __value_type(const __value_type& __v)
1391             : __cc(std::move(__v.__cc)) {}
1392
1393         __value_type(__value_type&& __v)
1394             : __nc(std::move(__v.__nc)) {}
1395
1396         __value_type& operator=(const __value_type& __v)
1397             {__nc = __v.__cc; return *this;}
1398
1399         __value_type& operator=(__value_type&& __v)
1400             {__nc = std::move(__v.__nc); return *this;}
1401
1402         ~__value_type() {__cc.~value_type();}
1403     };
1404 #else
1405     struct __value_type
1406     {
1407         typedef typename multimap::value_type value_type;
1408         value_type __cc;
1409
1410         __value_type() {}
1411
1412         template <class _A0>
1413         __value_type(const _A0& __a0)
1414             : __cc(__a0) {}
1415
1416         template <class _A0, class _A1>
1417         __value_type(const _A0& __a0, const _A1& __a1)
1418             : __cc(__a0, __a1) {}
1419     };
1420 #endif
1421     typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
1422     typedef typename allocator_traits<allocator_type>::template
1423 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1424             rebind_alloc<__value_type>
1425 #else
1426             rebind_alloc<__value_type>::other
1427 #endif
1428                                                                     __allocator_type;
1429     typedef __tree<__value_type, __vc, __allocator_type>            __base;
1430     typedef typename __base::__node_traits                          __node_traits;
1431     typedef allocator_traits<allocator_type>                        __alloc_traits;
1432
1433     __base __tree_;
1434
1435 public:
1436     typedef typename __alloc_traits::pointer               pointer;
1437     typedef typename __alloc_traits::const_pointer         const_pointer;
1438     typedef typename __alloc_traits::size_type             size_type;
1439     typedef typename __alloc_traits::difference_type       difference_type;
1440     typedef __map_iterator<typename __base::iterator>      iterator;
1441     typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
1442     typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
1443     typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;
1444
1445     _LIBCPP_INLINE_VISIBILITY
1446     explicit multimap(const key_compare& __comp = key_compare())
1447         _NOEXCEPT_(
1448             is_nothrow_default_constructible<allocator_type>::value &&
1449             is_nothrow_default_constructible<key_compare>::value &&
1450             is_nothrow_copy_constructible<key_compare>::value)
1451         : __tree_(__vc(__comp)) {}
1452
1453     _LIBCPP_INLINE_VISIBILITY
1454     explicit multimap(const key_compare& __comp, const allocator_type& __a)
1455         : __tree_(__vc(__comp), __a) {}
1456
1457     template <class _InputIterator>
1458         _LIBCPP_INLINE_VISIBILITY
1459         multimap(_InputIterator __f, _InputIterator __l,
1460             const key_compare& __comp = key_compare())
1461         : __tree_(__vc(__comp))
1462         {
1463             insert(__f, __l);
1464         }
1465
1466     template <class _InputIterator>
1467         _LIBCPP_INLINE_VISIBILITY
1468         multimap(_InputIterator __f, _InputIterator __l,
1469             const key_compare& __comp, const allocator_type& __a)
1470         : __tree_(__vc(__comp), __a)
1471         {
1472             insert(__f, __l);
1473         }
1474
1475     _LIBCPP_INLINE_VISIBILITY
1476     multimap(const multimap& __m)
1477         : __tree_(__m.__tree_.value_comp(),
1478           __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc()))
1479         {
1480             insert(__m.begin(), __m.end());
1481         }
1482
1483     _LIBCPP_INLINE_VISIBILITY
1484     multimap& operator=(const multimap& __m)
1485         {
1486 #if __cplusplus >= 201103L
1487             __tree_ = __m.__tree_;
1488 #else
1489             __tree_.clear();
1490             __tree_.value_comp() = __m.__tree_.value_comp();
1491             __tree_.__copy_assign_alloc(__m.__tree_);
1492             insert(__m.begin(), __m.end());
1493 #endif
1494             return *this;
1495         }
1496
1497 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1498
1499     _LIBCPP_INLINE_VISIBILITY
1500     multimap(multimap&& __m)
1501         _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
1502         : __tree_(_VSTD::move(__m.__tree_))
1503         {
1504         }
1505
1506     multimap(multimap&& __m, const allocator_type& __a);
1507
1508     _LIBCPP_INLINE_VISIBILITY
1509     multimap& operator=(multimap&& __m)
1510         _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
1511         {
1512             __tree_ = _VSTD::move(__m.__tree_);
1513             return *this;
1514         }
1515
1516 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1517
1518 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1519
1520     _LIBCPP_INLINE_VISIBILITY
1521     multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
1522         : __tree_(__vc(__comp))
1523         {
1524             insert(__il.begin(), __il.end());
1525         }
1526
1527     _LIBCPP_INLINE_VISIBILITY
1528     multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
1529         : __tree_(__vc(__comp), __a)
1530         {
1531             insert(__il.begin(), __il.end());
1532         }
1533
1534     _LIBCPP_INLINE_VISIBILITY
1535     multimap& operator=(initializer_list<value_type> __il)
1536         {
1537             __tree_.__assign_multi(__il.begin(), __il.end());
1538             return *this;
1539         }
1540
1541 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1542
1543     _LIBCPP_INLINE_VISIBILITY
1544     explicit multimap(const allocator_type& __a)
1545         : __tree_(__a)
1546         {
1547         }
1548
1549     _LIBCPP_INLINE_VISIBILITY
1550     multimap(const multimap& __m, const allocator_type& __a)
1551         : __tree_(__m.__tree_.value_comp(), __a)
1552         {
1553             insert(__m.begin(), __m.end());
1554         }
1555
1556     _LIBCPP_INLINE_VISIBILITY
1557           iterator begin() _NOEXCEPT {return __tree_.begin();}
1558     _LIBCPP_INLINE_VISIBILITY
1559     const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
1560     _LIBCPP_INLINE_VISIBILITY
1561           iterator end() _NOEXCEPT {return __tree_.end();}
1562     _LIBCPP_INLINE_VISIBILITY
1563     const_iterator end() const _NOEXCEPT {return __tree_.end();}
1564
1565     _LIBCPP_INLINE_VISIBILITY
1566           reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
1567     _LIBCPP_INLINE_VISIBILITY
1568     const_reverse_iterator rbegin() const _NOEXCEPT
1569         {return const_reverse_iterator(end());}
1570     _LIBCPP_INLINE_VISIBILITY
1571           reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
1572     _LIBCPP_INLINE_VISIBILITY
1573     const_reverse_iterator rend() const _NOEXCEPT
1574         {return const_reverse_iterator(begin());}
1575
1576     _LIBCPP_INLINE_VISIBILITY
1577     const_iterator cbegin()  const _NOEXCEPT {return begin();}
1578     _LIBCPP_INLINE_VISIBILITY
1579     const_iterator cend() const _NOEXCEPT {return end();}
1580     _LIBCPP_INLINE_VISIBILITY
1581     const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
1582     _LIBCPP_INLINE_VISIBILITY
1583     const_reverse_iterator crend() const _NOEXCEPT {return rend();}
1584
1585     _LIBCPP_INLINE_VISIBILITY
1586     bool empty() const _NOEXCEPT {return __tree_.size() == 0;}
1587     _LIBCPP_INLINE_VISIBILITY
1588     size_type size() const _NOEXCEPT {return __tree_.size();}
1589     _LIBCPP_INLINE_VISIBILITY
1590     size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
1591
1592     _LIBCPP_INLINE_VISIBILITY
1593     allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}
1594     _LIBCPP_INLINE_VISIBILITY
1595     key_compare    key_comp() const {return __tree_.value_comp().key_comp();}
1596     _LIBCPP_INLINE_VISIBILITY
1597     value_compare  value_comp() const
1598         {return value_compare(__tree_.value_comp().key_comp());}
1599
1600 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1601 #ifndef _LIBCPP_HAS_NO_VARIADICS
1602
1603     template <class ..._Args>
1604         iterator
1605         emplace(_Args&& ...__args);
1606
1607     template <class ..._Args>
1608         iterator
1609         emplace_hint(const_iterator __p, _Args&& ...__args);
1610
1611 #endif  // _LIBCPP_HAS_NO_VARIADICS
1612
1613     template <class _Pp,
1614               class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
1615         _LIBCPP_INLINE_VISIBILITY
1616         iterator insert(_Pp&& __p)
1617             {return __tree_.__insert_multi(_VSTD::forward<_Pp>(__p));}
1618
1619     template <class _Pp,
1620               class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
1621         _LIBCPP_INLINE_VISIBILITY
1622         iterator insert(const_iterator __pos, _Pp&& __p)
1623             {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));}
1624
1625 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1626
1627     _LIBCPP_INLINE_VISIBILITY
1628     iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);}
1629
1630     _LIBCPP_INLINE_VISIBILITY
1631     iterator insert(const_iterator __p, const value_type& __v)
1632             {return __tree_.__insert_multi(__p.__i_, __v);}
1633
1634     template <class _InputIterator>
1635         _LIBCPP_INLINE_VISIBILITY
1636         void insert(_InputIterator __f, _InputIterator __l)
1637         {
1638             for (const_iterator __e = cend(); __f != __l; ++__f)
1639                 __tree_.__insert_multi(__e.__i_, *__f);
1640         }
1641
1642 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1643
1644     _LIBCPP_INLINE_VISIBILITY
1645     void insert(initializer_list<value_type> __il)
1646         {insert(__il.begin(), __il.end());}
1647
1648 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1649
1650     _LIBCPP_INLINE_VISIBILITY
1651     iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
1652     _LIBCPP_INLINE_VISIBILITY
1653     size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}
1654     _LIBCPP_INLINE_VISIBILITY
1655     iterator  erase(const_iterator __f, const_iterator __l)
1656         {return __tree_.erase(__f.__i_, __l.__i_);}
1657     _LIBCPP_INLINE_VISIBILITY
1658     void clear() {__tree_.clear();}
1659
1660     _LIBCPP_INLINE_VISIBILITY
1661     void swap(multimap& __m)
1662         _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
1663         {__tree_.swap(__m.__tree_);}
1664
1665     _LIBCPP_INLINE_VISIBILITY
1666     iterator find(const key_type& __k)             {return __tree_.find(__k);}
1667     _LIBCPP_INLINE_VISIBILITY
1668     const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
1669     _LIBCPP_INLINE_VISIBILITY
1670     size_type      count(const key_type& __k) const
1671         {return __tree_.__count_multi(__k);}
1672     _LIBCPP_INLINE_VISIBILITY
1673     iterator lower_bound(const key_type& __k)
1674         {return __tree_.lower_bound(__k);}
1675     _LIBCPP_INLINE_VISIBILITY
1676     const_iterator lower_bound(const key_type& __k) const
1677             {return __tree_.lower_bound(__k);}
1678     _LIBCPP_INLINE_VISIBILITY
1679     iterator upper_bound(const key_type& __k)
1680             {return __tree_.upper_bound(__k);}
1681     _LIBCPP_INLINE_VISIBILITY
1682     const_iterator upper_bound(const key_type& __k) const
1683             {return __tree_.upper_bound(__k);}
1684     _LIBCPP_INLINE_VISIBILITY
1685     pair<iterator,iterator>             equal_range(const key_type& __k)
1686             {return __tree_.__equal_range_multi(__k);}
1687     _LIBCPP_INLINE_VISIBILITY
1688     pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
1689             {return __tree_.__equal_range_multi(__k);}
1690
1691 private:
1692     typedef typename __base::__node                    __node;
1693     typedef typename __base::__node_allocator          __node_allocator;
1694     typedef typename __base::__node_pointer            __node_pointer;
1695     typedef typename __base::__node_const_pointer      __node_const_pointer;
1696     typedef __map_node_destructor<__node_allocator> _Dp;
1697     typedef unique_ptr<__node, _Dp> __node_holder;
1698
1699 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1700     __node_holder __construct_node();
1701     template <class _A0>
1702         __node_holder
1703          __construct_node(_A0&& __a0);
1704 #ifndef _LIBCPP_HAS_NO_VARIADICS
1705     template <class _A0, class _A1, class ..._Args>
1706         __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
1707 #endif  // _LIBCPP_HAS_NO_VARIADICS
1708 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1709 };
1710
1711 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1712
1713 template <class _Key, class _Tp, class _Compare, class _Allocator>
1714 multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a)
1715     : __tree_(_VSTD::move(__m.__tree_), __a)
1716 {
1717     if (__a != __m.get_allocator())
1718     {
1719         const_iterator __e = cend();
1720         while (!__m.empty())
1721             __tree_.__insert_multi(__e.__i_,
1722                     _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
1723     }
1724 }
1725
1726 template <class _Key, class _Tp, class _Compare, class _Allocator>
1727 typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
1728 multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node()
1729 {
1730     __node_allocator& __na = __tree_.__node_alloc();
1731     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1732     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first));
1733     __h.get_deleter().__first_constructed = true;
1734     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
1735     __h.get_deleter().__second_constructed = true;
1736     return __h;
1737 }
1738
1739 template <class _Key, class _Tp, class _Compare, class _Allocator>
1740 template <class _A0>
1741 typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
1742 multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
1743 {
1744     __node_allocator& __na = __tree_.__node_alloc();
1745     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1746     __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0));
1747     __h.get_deleter().__first_constructed = true;
1748     __h.get_deleter().__second_constructed = true;
1749     return __h;
1750 }
1751
1752 #ifndef _LIBCPP_HAS_NO_VARIADICS
1753
1754 template <class _Key, class _Tp, class _Compare, class _Allocator>
1755 template <class _A0, class _A1, class ..._Args>
1756 typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
1757 multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args)
1758 {
1759     __node_allocator& __na = __tree_.__node_alloc();
1760     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1761     __node_traits::construct(__na, _VSTD::addressof(__h->__value_),
1762                              _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),
1763                              _VSTD::forward<_Args>(__args)...);
1764     __h.get_deleter().__first_constructed = true;
1765     __h.get_deleter().__second_constructed = true;
1766     return __h;
1767 }
1768
1769 #endif  // _LIBCPP_HAS_NO_VARIADICS
1770 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1771
1772 #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
1773
1774 template <class _Key, class _Tp, class _Compare, class _Allocator>
1775 template <class ..._Args>
1776 typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator
1777 multimap<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args)
1778 {
1779     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
1780     iterator __r = __tree_.__node_insert_multi(__h.get());
1781     __h.release();
1782     return __r;
1783 }
1784
1785 template <class _Key, class _Tp, class _Compare, class _Allocator>
1786 template <class ..._Args>
1787 typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator
1788 multimap<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p,
1789                                                         _Args&& ...__args)
1790 {
1791     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
1792     iterator __r = __tree_.__node_insert_multi(__p.__i_, __h.get());
1793     __h.release();
1794     return __r;
1795 }
1796
1797 #endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
1798
1799 template <class _Key, class _Tp, class _Compare, class _Allocator>
1800 inline _LIBCPP_INLINE_VISIBILITY
1801 bool
1802 operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1803            const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1804 {
1805     return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
1806 }
1807
1808 template <class _Key, class _Tp, class _Compare, class _Allocator>
1809 inline _LIBCPP_INLINE_VISIBILITY
1810 bool
1811 operator< (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1812            const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1813 {
1814     return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1815 }
1816
1817 template <class _Key, class _Tp, class _Compare, class _Allocator>
1818 inline _LIBCPP_INLINE_VISIBILITY
1819 bool
1820 operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1821            const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1822 {
1823     return !(__x == __y);
1824 }
1825
1826 template <class _Key, class _Tp, class _Compare, class _Allocator>
1827 inline _LIBCPP_INLINE_VISIBILITY
1828 bool
1829 operator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1830            const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1831 {
1832     return __y < __x;
1833 }
1834
1835 template <class _Key, class _Tp, class _Compare, class _Allocator>
1836 inline _LIBCPP_INLINE_VISIBILITY
1837 bool
1838 operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1839            const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1840 {
1841     return !(__x < __y);
1842 }
1843
1844 template <class _Key, class _Tp, class _Compare, class _Allocator>
1845 inline _LIBCPP_INLINE_VISIBILITY
1846 bool
1847 operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1848            const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1849 {
1850     return !(__y < __x);
1851 }
1852
1853 template <class _Key, class _Tp, class _Compare, class _Allocator>
1854 inline _LIBCPP_INLINE_VISIBILITY
1855 void
1856 swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1857      multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1858     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1859 {
1860     __x.swap(__y);
1861 }
1862
1863 _LIBCPP_END_NAMESPACE_STD
1864
1865 #endif  // _LIBCPP_MAP