• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
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        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
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
176template <class Key, class T, class Compare, class Allocator>
177bool
178operator> (const map<Key, T, Compare, Allocator>& x,
179           const map<Key, T, Compare, Allocator>& y);
180
181template <class Key, class T, class Compare, class Allocator>
182bool
183operator>=(const map<Key, T, Compare, Allocator>& x,
184           const map<Key, T, Compare, Allocator>& y);
185
186template <class Key, class T, class Compare, class Allocator>
187bool
188operator<=(const map<Key, T, Compare, Allocator>& x,
189           const map<Key, T, Compare, Allocator>& y);
190
191// specialized algorithms:
192template <class Key, class T, class Compare, class Allocator>
193void
194swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
195    noexcept(noexcept(x.swap(y)));
196
197template <class Key, class T, class Compare = less<Key>,
198          class Allocator = allocator<pair<const Key, T>>>
199class multimap
200{
201public:
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
329template <class Key, class T, class Compare, class Allocator>
330bool
331operator==(const multimap<Key, T, Compare, Allocator>& x,
332           const multimap<Key, T, Compare, Allocator>& y);
333
334template <class Key, class T, class Compare, class Allocator>
335bool
336operator< (const multimap<Key, T, Compare, Allocator>& x,
337           const multimap<Key, T, Compare, Allocator>& y);
338
339template <class Key, class T, class Compare, class Allocator>
340bool
341operator!=(const multimap<Key, T, Compare, Allocator>& x,
342           const multimap<Key, T, Compare, Allocator>& y);
343
344template <class Key, class T, class Compare, class Allocator>
345bool
346operator> (const multimap<Key, T, Compare, Allocator>& x,
347           const multimap<Key, T, Compare, Allocator>& y);
348
349template <class Key, class T, class Compare, class Allocator>
350bool
351operator>=(const multimap<Key, T, Compare, Allocator>& x,
352           const multimap<Key, T, Compare, Allocator>& y);
353
354template <class Key, class T, class Compare, class Allocator>
355bool
356operator<=(const multimap<Key, T, Compare, Allocator>& x,
357           const multimap<Key, T, Compare, Allocator>& y);
358
359// specialized algorithms:
360template <class Key, class T, class Compare, class Allocator>
361void
362swap(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
384template <class _Key, class _CP, class _Compare, bool = is_empty<_Compare>::value
385#if __has_feature(is_final)
386                                                        && !__is_final(_Compare)
387#endif
388         >
389class __map_value_compare
390    : private _Compare
391{
392public:
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
414template <class _Key, class _CP, class _Compare>
415class __map_value_compare<_Key, _CP, _Compare, false>
416{
417    _Compare comp;
418
419public:
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
442template <class _Allocator>
443class __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;
448public:
449    typedef typename __alloc_traits::pointer    pointer;
450private:
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
458public:
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
492template <class _Key, class _Tp, class _Compare, class _Allocator>
493    class map;
494template <class _Key, class _Tp, class _Compare, class _Allocator>
495    class multimap;
496template <class _TreeIterator> class __map_const_iterator;
497
498template <class _TreeIterator>
499class _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;
506public:
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
563template <class _TreeIterator>
564class _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;
571public:
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
632template <class _Key, class _Tp, class _Compare = less<_Key>,
633          class _Allocator = allocator<pair<const _Key, _Tp> > >
634class _LIBCPP_TYPE_VIS map
635{
636public:
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
661private:
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
720public:
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
986private:
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
1018template <class _Key, class _Tp, class _Compare, class _Allocator>
1019typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer&
1020map<_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
1063template <class _Key, class _Tp, class _Compare, class _Allocator>
1064typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_const_pointer
1065map<_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
1106template <class _Key, class _Tp, class _Compare, class _Allocator>
1107map<_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
1119template <class _Key, class _Tp, class _Compare, class _Allocator>
1120typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1121map<_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
1132template <class _Key, class _Tp, class _Compare, class _Allocator>
1133template <class _A0>
1134typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1135map<_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
1145template <class _Key, class _Tp, class _Compare, class _Allocator>
1146typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1147map<_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
1160template <class _Key, class _Tp, class _Compare, class _Allocator>
1161template <class _A0, class _A1, class ..._Args>
1162typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1163map<_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
1179template <class _Key, class _Tp, class _Compare, class _Allocator>
1180typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
1181map<_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
1192template <class _Key, class _Tp, class _Compare, class _Allocator>
1193_Tp&
1194map<_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
1210template <class _Key, class _Tp, class _Compare, class _Allocator>
1211_Tp&
1212map<_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
1228template <class _Key, class _Tp, class _Compare, class _Allocator>
1229_Tp&
1230map<_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
1241template <class _Key, class _Tp, class _Compare, class _Allocator>
1242const _Tp&
1243map<_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
1256template <class _Key, class _Tp, class _Compare, class _Allocator>
1257template <class ..._Args>
1258pair<typename map<_Key, _Tp, _Compare, _Allocator>::iterator, bool>
1259map<_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
1268template <class _Key, class _Tp, class _Compare, class _Allocator>
1269template <class ..._Args>
1270typename map<_Key, _Tp, _Compare, _Allocator>::iterator
1271map<_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
1283template <class _Key, class _Tp, class _Compare, class _Allocator>
1284inline _LIBCPP_INLINE_VISIBILITY
1285bool
1286operator==(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
1292template <class _Key, class _Tp, class _Compare, class _Allocator>
1293inline _LIBCPP_INLINE_VISIBILITY
1294bool
1295operator< (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
1301template <class _Key, class _Tp, class _Compare, class _Allocator>
1302inline _LIBCPP_INLINE_VISIBILITY
1303bool
1304operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1305           const map<_Key, _Tp, _Compare, _Allocator>& __y)
1306{
1307    return !(__x == __y);
1308}
1309
1310template <class _Key, class _Tp, class _Compare, class _Allocator>
1311inline _LIBCPP_INLINE_VISIBILITY
1312bool
1313operator> (const map<_Key, _Tp, _Compare, _Allocator>& __x,
1314           const map<_Key, _Tp, _Compare, _Allocator>& __y)
1315{
1316    return __y < __x;
1317}
1318
1319template <class _Key, class _Tp, class _Compare, class _Allocator>
1320inline _LIBCPP_INLINE_VISIBILITY
1321bool
1322operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1323           const map<_Key, _Tp, _Compare, _Allocator>& __y)
1324{
1325    return !(__x < __y);
1326}
1327
1328template <class _Key, class _Tp, class _Compare, class _Allocator>
1329inline _LIBCPP_INLINE_VISIBILITY
1330bool
1331operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
1332           const map<_Key, _Tp, _Compare, _Allocator>& __y)
1333{
1334    return !(__y < __x);
1335}
1336
1337template <class _Key, class _Tp, class _Compare, class _Allocator>
1338inline _LIBCPP_INLINE_VISIBILITY
1339void
1340swap(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
1347template <class _Key, class _Tp, class _Compare = less<_Key>,
1348          class _Allocator = allocator<pair<const _Key, _Tp> > >
1349class _LIBCPP_TYPE_VIS multimap
1350{
1351public:
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
1377private:
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
1435public:
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
1691private:
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
1713template <class _Key, class _Tp, class _Compare, class _Allocator>
1714multimap<_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
1726template <class _Key, class _Tp, class _Compare, class _Allocator>
1727typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
1728multimap<_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
1739template <class _Key, class _Tp, class _Compare, class _Allocator>
1740template <class _A0>
1741typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
1742multimap<_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
1754template <class _Key, class _Tp, class _Compare, class _Allocator>
1755template <class _A0, class _A1, class ..._Args>
1756typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
1757multimap<_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
1774template <class _Key, class _Tp, class _Compare, class _Allocator>
1775template <class ..._Args>
1776typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator
1777multimap<_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
1785template <class _Key, class _Tp, class _Compare, class _Allocator>
1786template <class ..._Args>
1787typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator
1788multimap<_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
1799template <class _Key, class _Tp, class _Compare, class _Allocator>
1800inline _LIBCPP_INLINE_VISIBILITY
1801bool
1802operator==(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
1808template <class _Key, class _Tp, class _Compare, class _Allocator>
1809inline _LIBCPP_INLINE_VISIBILITY
1810bool
1811operator< (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
1817template <class _Key, class _Tp, class _Compare, class _Allocator>
1818inline _LIBCPP_INLINE_VISIBILITY
1819bool
1820operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1821           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1822{
1823    return !(__x == __y);
1824}
1825
1826template <class _Key, class _Tp, class _Compare, class _Allocator>
1827inline _LIBCPP_INLINE_VISIBILITY
1828bool
1829operator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1830           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1831{
1832    return __y < __x;
1833}
1834
1835template <class _Key, class _Tp, class _Compare, class _Allocator>
1836inline _LIBCPP_INLINE_VISIBILITY
1837bool
1838operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1839           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1840{
1841    return !(__x < __y);
1842}
1843
1844template <class _Key, class _Tp, class _Compare, class _Allocator>
1845inline _LIBCPP_INLINE_VISIBILITY
1846bool
1847operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
1848           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
1849{
1850    return !(__y < __x);
1851}
1852
1853template <class _Key, class _Tp, class _Compare, class _Allocator>
1854inline _LIBCPP_INLINE_VISIBILITY
1855void
1856swap(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
1866