xref: /freebsd/contrib/llvm-project/libcxx/include/ext/hash_map (revision f10421e96d0b7f2de657cabedc1e2884a429c76d)
1// -*- C++ -*-
2//===-------------------------- hash_map ----------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_HASH_MAP
11#define _LIBCPP_HASH_MAP
12
13/*
14
15    hash_map synopsis
16
17namespace __gnu_cxx
18{
19
20template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
21          class Alloc = allocator<pair<const Key, T>>>
22class hash_map
23{
24public:
25    // types
26    typedef Key                                                        key_type;
27    typedef T                                                          mapped_type;
28    typedef Hash                                                       hasher;
29    typedef Pred                                                       key_equal;
30    typedef Alloc                                                      allocator_type;
31    typedef pair<const key_type, mapped_type>                          value_type;
32    typedef value_type&                                                reference;
33    typedef const value_type&                                          const_reference;
34    typedef typename allocator_traits<allocator_type>::pointer         pointer;
35    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
36    typedef typename allocator_traits<allocator_type>::size_type       size_type;
37    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
38
39    typedef /unspecified/ iterator;
40    typedef /unspecified/ const_iterator;
41
42    explicit hash_map(size_type n = 193, const hasher& hf = hasher(),
43                           const key_equal& eql = key_equal(),
44                           const allocator_type& a = allocator_type());
45    template <class InputIterator>
46        hash_map(InputIterator f, InputIterator l,
47                      size_type n = 193, const hasher& hf = hasher(),
48                      const key_equal& eql = key_equal(),
49                      const allocator_type& a = allocator_type());
50    hash_map(const hash_map&);
51    ~hash_map();
52    hash_map& operator=(const hash_map&);
53
54    allocator_type get_allocator() const;
55
56    bool      empty() const;
57    size_type size() const;
58    size_type max_size() const;
59
60    iterator       begin();
61    iterator       end();
62    const_iterator begin()  const;
63    const_iterator end()    const;
64
65    pair<iterator, bool> insert(const value_type& obj);
66    template <class InputIterator>
67        void insert(InputIterator first, InputIterator last);
68
69    void erase(const_iterator position);
70    size_type erase(const key_type& k);
71    void erase(const_iterator first, const_iterator last);
72    void clear();
73
74    void swap(hash_map&);
75
76    hasher hash_funct() const;
77    key_equal key_eq() const;
78
79    iterator       find(const key_type& k);
80    const_iterator find(const key_type& k) const;
81    size_type count(const key_type& k) const;
82    pair<iterator, iterator>             equal_range(const key_type& k);
83    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
84
85    mapped_type& operator[](const key_type& k);
86
87    size_type bucket_count() const;
88    size_type max_bucket_count() const;
89
90    size_type elems_in_bucket(size_type n) const;
91
92    void resize(size_type n);
93};
94
95template <class Key, class T, class Hash, class Pred, class Alloc>
96    void swap(hash_map<Key, T, Hash, Pred, Alloc>& x,
97              hash_map<Key, T, Hash, Pred, Alloc>& y);
98
99template <class Key, class T, class Hash, class Pred, class Alloc>
100    bool
101    operator==(const hash_map<Key, T, Hash, Pred, Alloc>& x,
102               const hash_map<Key, T, Hash, Pred, Alloc>& y);
103
104template <class Key, class T, class Hash, class Pred, class Alloc>
105    bool
106    operator!=(const hash_map<Key, T, Hash, Pred, Alloc>& x,
107               const hash_map<Key, T, Hash, Pred, Alloc>& y);
108
109template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
110          class Alloc = allocator<pair<const Key, T>>>
111class hash_multimap
112{
113public:
114    // types
115    typedef Key                                                        key_type;
116    typedef T                                                          mapped_type;
117    typedef Hash                                                       hasher;
118    typedef Pred                                                       key_equal;
119    typedef Alloc                                                      allocator_type;
120    typedef pair<const key_type, mapped_type>                          value_type;
121    typedef value_type&                                                reference;
122    typedef const value_type&                                          const_reference;
123    typedef typename allocator_traits<allocator_type>::pointer         pointer;
124    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
125    typedef typename allocator_traits<allocator_type>::size_type       size_type;
126    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
127
128    typedef /unspecified/ iterator;
129    typedef /unspecified/ const_iterator;
130
131    explicit hash_multimap(size_type n = 193, const hasher& hf = hasher(),
132                           const key_equal& eql = key_equal(),
133                           const allocator_type& a = allocator_type());
134    template <class InputIterator>
135        hash_multimap(InputIterator f, InputIterator l,
136                      size_type n = 193, const hasher& hf = hasher(),
137                      const key_equal& eql = key_equal(),
138                      const allocator_type& a = allocator_type());
139    explicit hash_multimap(const allocator_type&);
140    hash_multimap(const hash_multimap&);
141    ~hash_multimap();
142    hash_multimap& operator=(const hash_multimap&);
143
144    allocator_type get_allocator() const;
145
146    bool      empty() const;
147    size_type size() const;
148    size_type max_size() const;
149
150    iterator       begin();
151    iterator       end();
152    const_iterator begin()  const;
153    const_iterator end()    const;
154
155    iterator insert(const value_type& obj);
156    template <class InputIterator>
157        void insert(InputIterator first, InputIterator last);
158
159    void erase(const_iterator position);
160    size_type erase(const key_type& k);
161    void erase(const_iterator first, const_iterator last);
162    void clear();
163
164    void swap(hash_multimap&);
165
166    hasher hash_funct() const;
167    key_equal key_eq() const;
168
169    iterator       find(const key_type& k);
170    const_iterator find(const key_type& k) const;
171    size_type count(const key_type& k) const;
172    pair<iterator, iterator>             equal_range(const key_type& k);
173    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
174
175    size_type bucket_count() const;
176    size_type max_bucket_count() const;
177
178    size_type elems_in_bucket(size_type n) const;
179
180    void resize(size_type n);
181};
182
183template <class Key, class T, class Hash, class Pred, class Alloc>
184    void swap(hash_multimap<Key, T, Hash, Pred, Alloc>& x,
185              hash_multimap<Key, T, Hash, Pred, Alloc>& y);
186
187template <class Key, class T, class Hash, class Pred, class Alloc>
188    bool
189    operator==(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
190               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);
191
192template <class Key, class T, class Hash, class Pred, class Alloc>
193    bool
194    operator!=(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
195               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);
196
197}  // __gnu_cxx
198
199*/
200
201#include <__config>
202#include <__hash_table>
203#include <functional>
204#include <stdexcept>
205#include <type_traits>
206#include <ext/__hash>
207
208#if __DEPRECATED
209#if defined(_LIBCPP_WARNING)
210    _LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>")
211#else
212#   warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
213#endif
214#endif
215
216#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
217#pragma GCC system_header
218#endif
219
220namespace __gnu_cxx {
221
222template <class _Tp, class _Hash,
223          bool = std::is_empty<_Hash>::value && !std::__libcpp_is_final<_Hash>::value
224        >
225class __hash_map_hasher
226    : private _Hash
227{
228public:
229    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : _Hash() {}
230    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : _Hash(__h) {}
231    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return *this;}
232    _LIBCPP_INLINE_VISIBILITY
233    size_t operator()(const _Tp& __x) const
234        {return static_cast<const _Hash&>(*this)(__x.first);}
235    _LIBCPP_INLINE_VISIBILITY
236    size_t operator()(const typename _Tp::first_type& __x) const
237        {return static_cast<const _Hash&>(*this)(__x);}
238};
239
240template <class _Tp, class _Hash>
241class __hash_map_hasher<_Tp, _Hash, false>
242{
243    _Hash __hash_;
244public:
245    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : __hash_() {}
246    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : __hash_(__h) {}
247    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return __hash_;}
248    _LIBCPP_INLINE_VISIBILITY
249    size_t operator()(const _Tp& __x) const
250        {return __hash_(__x.first);}
251    _LIBCPP_INLINE_VISIBILITY
252    size_t operator()(const typename _Tp::first_type& __x) const
253        {return __hash_(__x);}
254};
255
256template <class _Tp, class _Pred,
257          bool = std::is_empty<_Pred>::value && !std::__libcpp_is_final<_Pred>::value
258         >
259class __hash_map_equal
260    : private _Pred
261{
262public:
263    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : _Pred() {}
264    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : _Pred(__p) {}
265    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return *this;}
266    _LIBCPP_INLINE_VISIBILITY
267    bool operator()(const _Tp& __x, const _Tp& __y) const
268        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
269    _LIBCPP_INLINE_VISIBILITY
270    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
271        {return static_cast<const _Pred&>(*this)(__x, __y.first);}
272    _LIBCPP_INLINE_VISIBILITY
273    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
274        {return static_cast<const _Pred&>(*this)(__x.first, __y);}
275    _LIBCPP_INLINE_VISIBILITY
276    bool operator()(const typename _Tp::first_type& __x,
277                    const typename _Tp::first_type& __y) const
278        {return static_cast<const _Pred&>(*this)(__x, __y);}
279};
280
281template <class _Tp, class _Pred>
282class __hash_map_equal<_Tp, _Pred, false>
283{
284    _Pred __pred_;
285public:
286    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : __pred_() {}
287    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : __pred_(__p) {}
288    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return __pred_;}
289    _LIBCPP_INLINE_VISIBILITY
290    bool operator()(const _Tp& __x, const _Tp& __y) const
291        {return __pred_(__x.first, __y.first);}
292    _LIBCPP_INLINE_VISIBILITY
293    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
294        {return __pred_(__x, __y.first);}
295    _LIBCPP_INLINE_VISIBILITY
296    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
297        {return __pred_(__x.first, __y);}
298    _LIBCPP_INLINE_VISIBILITY
299    bool operator()(const typename _Tp::first_type& __x,
300                    const typename _Tp::first_type& __y) const
301        {return __pred_(__x, __y);}
302};
303
304template <class _Alloc>
305class __hash_map_node_destructor
306{
307    typedef _Alloc                              allocator_type;
308    typedef std::allocator_traits<allocator_type>    __alloc_traits;
309    typedef typename __alloc_traits::value_type::__node_value_type value_type;
310public:
311    typedef typename __alloc_traits::pointer    pointer;
312private:
313    typedef typename value_type::first_type     first_type;
314    typedef typename value_type::second_type    second_type;
315
316    allocator_type& __na_;
317
318public:
319    bool __first_constructed;
320    bool __second_constructed;
321
322    __hash_map_node_destructor(__hash_map_node_destructor const&) = default;
323    __hash_map_node_destructor& operator=(const __hash_map_node_destructor&) = delete;
324
325    _LIBCPP_INLINE_VISIBILITY
326    explicit __hash_map_node_destructor(allocator_type& __na)
327        : __na_(__na),
328          __first_constructed(false),
329          __second_constructed(false)
330        {}
331
332#ifndef _LIBCPP_CXX03_LANG
333    _LIBCPP_INLINE_VISIBILITY
334    __hash_map_node_destructor(std::__hash_node_destructor<allocator_type>&& __x)
335        : __na_(__x.__na_),
336          __first_constructed(__x.__value_constructed),
337          __second_constructed(__x.__value_constructed)
338        {
339            __x.__value_constructed = false;
340        }
341#else  // _LIBCPP_CXX03_LANG
342    _LIBCPP_INLINE_VISIBILITY
343    __hash_map_node_destructor(const std::__hash_node_destructor<allocator_type>& __x)
344        : __na_(__x.__na_),
345          __first_constructed(__x.__value_constructed),
346          __second_constructed(__x.__value_constructed)
347        {
348            const_cast<bool&>(__x.__value_constructed) = false;
349        }
350#endif  // _LIBCPP_CXX03_LANG
351
352    _LIBCPP_INLINE_VISIBILITY
353    void operator()(pointer __p)
354    {
355        if (__second_constructed)
356            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second));
357        if (__first_constructed)
358            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first));
359        if (__p)
360            __alloc_traits::deallocate(__na_, __p, 1);
361    }
362};
363
364template <class _HashIterator>
365class _LIBCPP_TEMPLATE_VIS __hash_map_iterator
366{
367    _HashIterator __i_;
368
369    typedef const typename _HashIterator::value_type::first_type key_type;
370    typedef typename _HashIterator::value_type::second_type      mapped_type;
371public:
372    typedef std::forward_iterator_tag                            iterator_category;
373    typedef std::pair<key_type, mapped_type>                     value_type;
374    typedef typename _HashIterator::difference_type              difference_type;
375    typedef value_type&                                          reference;
376    typedef typename std::__rebind_pointer<typename _HashIterator::pointer, value_type>::type
377        pointer;
378
379    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() {}
380
381    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator(_HashIterator __i) : __i_(__i) {}
382
383    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *operator->();}
384    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return (pointer)__i_.operator->();}
385
386    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;}
387    _LIBCPP_INLINE_VISIBILITY
388    __hash_map_iterator operator++(int)
389    {
390        __hash_map_iterator __t(*this);
391        ++(*this);
392        return __t;
393    }
394
395    friend _LIBCPP_INLINE_VISIBILITY
396    bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
397        {return __x.__i_ == __y.__i_;}
398    friend _LIBCPP_INLINE_VISIBILITY
399    bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
400        {return __x.__i_ != __y.__i_;}
401
402    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map;
403    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
404    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
405    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
406    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
407};
408
409template <class _HashIterator>
410class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator
411{
412    _HashIterator __i_;
413
414    typedef const typename _HashIterator::value_type::first_type key_type;
415    typedef typename _HashIterator::value_type::second_type      mapped_type;
416public:
417    typedef std::forward_iterator_tag                            iterator_category;
418    typedef std::pair<key_type, mapped_type>                     value_type;
419    typedef typename _HashIterator::difference_type              difference_type;
420    typedef const value_type&                                    reference;
421    typedef typename std::__rebind_pointer<typename _HashIterator::pointer, const value_type>::type
422        pointer;
423
424    _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() {}
425
426    _LIBCPP_INLINE_VISIBILITY
427    __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {}
428    _LIBCPP_INLINE_VISIBILITY
429    __hash_map_const_iterator(
430            __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
431                : __i_(__i.__i_) {}
432
433    _LIBCPP_INLINE_VISIBILITY
434    reference operator*() const {return *operator->();}
435    _LIBCPP_INLINE_VISIBILITY
436    pointer operator->() const {return (pointer)__i_.operator->();}
437
438    _LIBCPP_INLINE_VISIBILITY
439    __hash_map_const_iterator& operator++() {++__i_; return *this;}
440    _LIBCPP_INLINE_VISIBILITY
441    __hash_map_const_iterator operator++(int)
442    {
443        __hash_map_const_iterator __t(*this);
444        ++(*this);
445        return __t;
446    }
447
448    friend _LIBCPP_INLINE_VISIBILITY
449    bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
450        {return __x.__i_ == __y.__i_;}
451    friend _LIBCPP_INLINE_VISIBILITY
452    bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
453        {return __x.__i_ != __y.__i_;}
454
455    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map;
456    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
457    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
458    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
459};
460
461template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>,
462          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
463class _LIBCPP_TEMPLATE_VIS hash_map
464{
465public:
466    // types
467    typedef _Key                                           key_type;
468    typedef _Tp                                            mapped_type;
469    typedef _Tp                                            data_type;
470    typedef _Hash                                          hasher;
471    typedef _Pred                                          key_equal;
472    typedef _Alloc                                         allocator_type;
473    typedef std::pair<const key_type, mapped_type>         value_type;
474    typedef value_type&                                    reference;
475    typedef const value_type&                              const_reference;
476
477private:
478    typedef std::pair<key_type, mapped_type>                    __value_type;
479    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
480    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
481    typedef typename std::__rebind_alloc_helper<
482        std::allocator_traits<allocator_type>, __value_type>::type __allocator_type;
483
484    typedef std::__hash_table<__value_type, __hasher,
485                         __key_equal,  __allocator_type>   __table;
486
487    __table __table_;
488
489    typedef typename __table::__node_pointer               __node_pointer;
490    typedef typename __table::__node_const_pointer         __node_const_pointer;
491    typedef typename __table::__node_traits                __node_traits;
492    typedef typename __table::__node_allocator             __node_allocator;
493    typedef typename __table::__node                       __node;
494    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
495    typedef std::unique_ptr<__node, _Dp>                   __node_holder;
496    typedef std::allocator_traits<allocator_type>          __alloc_traits;
497public:
498    typedef typename __alloc_traits::pointer         pointer;
499    typedef typename __alloc_traits::const_pointer   const_pointer;
500    typedef typename __alloc_traits::size_type       size_type;
501    typedef typename __alloc_traits::difference_type difference_type;
502
503    typedef __hash_map_iterator<typename __table::iterator>       iterator;
504    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
505
506    _LIBCPP_INLINE_VISIBILITY hash_map() {__table_.rehash(193);}
507    explicit hash_map(size_type __n, const hasher& __hf = hasher(),
508                           const key_equal& __eql = key_equal());
509    hash_map(size_type __n, const hasher& __hf,
510                  const key_equal& __eql,
511                  const allocator_type& __a);
512    template <class _InputIterator>
513        hash_map(_InputIterator __first, _InputIterator __last);
514    template <class _InputIterator>
515        hash_map(_InputIterator __first, _InputIterator __last,
516                      size_type __n, const hasher& __hf = hasher(),
517                      const key_equal& __eql = key_equal());
518    template <class _InputIterator>
519        hash_map(_InputIterator __first, _InputIterator __last,
520                      size_type __n, const hasher& __hf,
521                      const key_equal& __eql,
522                      const allocator_type& __a);
523    hash_map(const hash_map& __u);
524
525    _LIBCPP_INLINE_VISIBILITY
526    allocator_type get_allocator() const
527        {return allocator_type(__table_.__node_alloc());}
528
529    _LIBCPP_INLINE_VISIBILITY
530    bool      empty() const {return __table_.size() == 0;}
531    _LIBCPP_INLINE_VISIBILITY
532    size_type size() const  {return __table_.size();}
533    _LIBCPP_INLINE_VISIBILITY
534    size_type max_size() const {return __table_.max_size();}
535
536    _LIBCPP_INLINE_VISIBILITY
537    iterator       begin()        {return __table_.begin();}
538    _LIBCPP_INLINE_VISIBILITY
539    iterator       end()          {return __table_.end();}
540    _LIBCPP_INLINE_VISIBILITY
541    const_iterator begin()  const {return __table_.begin();}
542    _LIBCPP_INLINE_VISIBILITY
543    const_iterator end()    const {return __table_.end();}
544
545    _LIBCPP_INLINE_VISIBILITY
546    std::pair<iterator, bool> insert(const value_type& __x)
547        {return __table_.__insert_unique(__x);}
548    _LIBCPP_INLINE_VISIBILITY
549    iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}
550    template <class _InputIterator>
551        _LIBCPP_INLINE_VISIBILITY
552        void insert(_InputIterator __first, _InputIterator __last);
553
554    _LIBCPP_INLINE_VISIBILITY
555    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
556    _LIBCPP_INLINE_VISIBILITY
557    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
558    _LIBCPP_INLINE_VISIBILITY
559    void erase(const_iterator __first, const_iterator __last)
560        {__table_.erase(__first.__i_, __last.__i_);}
561    _LIBCPP_INLINE_VISIBILITY
562    void clear() {__table_.clear();}
563
564    _LIBCPP_INLINE_VISIBILITY
565    void swap(hash_map& __u) {__table_.swap(__u.__table_);}
566
567    _LIBCPP_INLINE_VISIBILITY
568    hasher hash_funct() const
569        {return __table_.hash_function().hash_function();}
570    _LIBCPP_INLINE_VISIBILITY
571    key_equal key_eq() const
572        {return __table_.key_eq().key_eq();}
573
574    _LIBCPP_INLINE_VISIBILITY
575    iterator       find(const key_type& __k)       {return __table_.find(__k);}
576    _LIBCPP_INLINE_VISIBILITY
577    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
578    _LIBCPP_INLINE_VISIBILITY
579    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
580    _LIBCPP_INLINE_VISIBILITY
581    std::pair<iterator, iterator>             equal_range(const key_type& __k)
582        {return __table_.__equal_range_unique(__k);}
583    _LIBCPP_INLINE_VISIBILITY
584    std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
585        {return __table_.__equal_range_unique(__k);}
586
587    mapped_type& operator[](const key_type& __k);
588
589    _LIBCPP_INLINE_VISIBILITY
590    size_type bucket_count() const {return __table_.bucket_count();}
591    _LIBCPP_INLINE_VISIBILITY
592    size_type max_bucket_count() const {return __table_.max_bucket_count();}
593
594    _LIBCPP_INLINE_VISIBILITY
595    size_type elems_in_bucket(size_type __n) const
596        {return __table_.bucket_size(__n);}
597
598    _LIBCPP_INLINE_VISIBILITY
599    void resize(size_type __n) {__table_.rehash(__n);}
600
601private:
602    __node_holder __construct_node(const key_type& __k);
603};
604
605template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
606hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
607        size_type __n, const hasher& __hf, const key_equal& __eql)
608    : __table_(__hf, __eql)
609{
610    __table_.rehash(__n);
611}
612
613template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
614hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
615        size_type __n, const hasher& __hf, const key_equal& __eql,
616        const allocator_type& __a)
617    : __table_(__hf, __eql, __a)
618{
619    __table_.rehash(__n);
620}
621
622template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
623template <class _InputIterator>
624hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
625        _InputIterator __first, _InputIterator __last)
626{
627    __table_.rehash(193);
628    insert(__first, __last);
629}
630
631template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
632template <class _InputIterator>
633hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
634        _InputIterator __first, _InputIterator __last, size_type __n,
635        const hasher& __hf, const key_equal& __eql)
636    : __table_(__hf, __eql)
637{
638    __table_.rehash(__n);
639    insert(__first, __last);
640}
641
642template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
643template <class _InputIterator>
644hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
645        _InputIterator __first, _InputIterator __last, size_type __n,
646        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
647    : __table_(__hf, __eql, __a)
648{
649    __table_.rehash(__n);
650    insert(__first, __last);
651}
652
653template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
654hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
655        const hash_map& __u)
656    : __table_(__u.__table_)
657{
658    __table_.rehash(__u.bucket_count());
659    insert(__u.begin(), __u.end());
660}
661
662template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
663typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
664hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k)
665{
666    __node_allocator& __na = __table_.__node_alloc();
667    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
668    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k);
669    __h.get_deleter().__first_constructed = true;
670    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
671    __h.get_deleter().__second_constructed = true;
672    return _LIBCPP_EXPLICIT_MOVE(__h);  // explicitly moved for C++03
673}
674
675template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
676template <class _InputIterator>
677inline
678void
679hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
680                                                       _InputIterator __last)
681{
682    for (; __first != __last; ++__first)
683        __table_.__insert_unique(*__first);
684}
685
686template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
687_Tp&
688hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
689{
690    iterator __i = find(__k);
691    if (__i != end())
692        return __i->second;
693    __node_holder __h = __construct_node(__k);
694    std::pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
695    __h.release();
696    return __r.first->second;
697}
698
699template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
700inline _LIBCPP_INLINE_VISIBILITY
701void
702swap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
703     hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
704{
705    __x.swap(__y);
706}
707
708template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
709bool
710operator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
711           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
712{
713    if (__x.size() != __y.size())
714        return false;
715    typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
716                                                                 const_iterator;
717    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
718            __i != __ex; ++__i)
719    {
720        const_iterator __j = __y.find(__i->first);
721        if (__j == __ey || !(*__i == *__j))
722            return false;
723    }
724    return true;
725}
726
727template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
728inline _LIBCPP_INLINE_VISIBILITY
729bool
730operator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
731           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
732{
733    return !(__x == __y);
734}
735
736template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>,
737          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
738class _LIBCPP_TEMPLATE_VIS hash_multimap
739{
740public:
741    // types
742    typedef _Key                                           key_type;
743    typedef _Tp                                            mapped_type;
744    typedef _Tp                                            data_type;
745    typedef _Hash                                          hasher;
746    typedef _Pred                                          key_equal;
747    typedef _Alloc                                         allocator_type;
748    typedef std::pair<const key_type, mapped_type>         value_type;
749    typedef value_type&                                    reference;
750    typedef const value_type&                              const_reference;
751
752private:
753    typedef std::pair<key_type, mapped_type>               __value_type;
754    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
755    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
756    typedef typename std::__rebind_alloc_helper<std::allocator_traits<allocator_type>, __value_type>::type __allocator_type;
757
758    typedef std::__hash_table<__value_type, __hasher,
759                         __key_equal,  __allocator_type>   __table;
760
761    __table __table_;
762
763    typedef typename __table::__node_traits                __node_traits;
764    typedef typename __table::__node_allocator             __node_allocator;
765    typedef typename __table::__node                       __node;
766    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
767    typedef std::unique_ptr<__node, _Dp>                         __node_holder;
768    typedef std::allocator_traits<allocator_type>               __alloc_traits;
769public:
770    typedef typename __alloc_traits::pointer         pointer;
771    typedef typename __alloc_traits::const_pointer   const_pointer;
772    typedef typename __alloc_traits::size_type       size_type;
773    typedef typename __alloc_traits::difference_type difference_type;
774
775    typedef __hash_map_iterator<typename __table::iterator>       iterator;
776    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
777
778    _LIBCPP_INLINE_VISIBILITY
779    hash_multimap() {__table_.rehash(193);}
780    explicit hash_multimap(size_type __n, const hasher& __hf = hasher(),
781                                const key_equal& __eql = key_equal());
782    hash_multimap(size_type __n, const hasher& __hf,
783                                const key_equal& __eql,
784                                const allocator_type& __a);
785    template <class _InputIterator>
786        hash_multimap(_InputIterator __first, _InputIterator __last);
787    template <class _InputIterator>
788        hash_multimap(_InputIterator __first, _InputIterator __last,
789                      size_type __n, const hasher& __hf = hasher(),
790                      const key_equal& __eql = key_equal());
791    template <class _InputIterator>
792        hash_multimap(_InputIterator __first, _InputIterator __last,
793                      size_type __n, const hasher& __hf,
794                      const key_equal& __eql,
795                      const allocator_type& __a);
796    hash_multimap(const hash_multimap& __u);
797
798    _LIBCPP_INLINE_VISIBILITY
799    allocator_type get_allocator() const
800        {return allocator_type(__table_.__node_alloc());}
801
802    _LIBCPP_INLINE_VISIBILITY
803    bool      empty() const {return __table_.size() == 0;}
804    _LIBCPP_INLINE_VISIBILITY
805    size_type size() const  {return __table_.size();}
806    _LIBCPP_INLINE_VISIBILITY
807    size_type max_size() const {return __table_.max_size();}
808
809    _LIBCPP_INLINE_VISIBILITY
810    iterator       begin()        {return __table_.begin();}
811    _LIBCPP_INLINE_VISIBILITY
812    iterator       end()          {return __table_.end();}
813    _LIBCPP_INLINE_VISIBILITY
814    const_iterator begin()  const {return __table_.begin();}
815    _LIBCPP_INLINE_VISIBILITY
816    const_iterator end()    const {return __table_.end();}
817
818    _LIBCPP_INLINE_VISIBILITY
819    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
820    _LIBCPP_INLINE_VISIBILITY
821    iterator insert(const_iterator, const value_type& __x) {return insert(__x);}
822    template <class _InputIterator>
823        _LIBCPP_INLINE_VISIBILITY
824        void insert(_InputIterator __first, _InputIterator __last);
825
826    _LIBCPP_INLINE_VISIBILITY
827    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
828    _LIBCPP_INLINE_VISIBILITY
829    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
830    _LIBCPP_INLINE_VISIBILITY
831    void erase(const_iterator __first, const_iterator __last)
832        {__table_.erase(__first.__i_, __last.__i_);}
833    _LIBCPP_INLINE_VISIBILITY
834    void clear() {__table_.clear();}
835
836    _LIBCPP_INLINE_VISIBILITY
837    void swap(hash_multimap& __u) {__table_.swap(__u.__table_);}
838
839    _LIBCPP_INLINE_VISIBILITY
840    hasher hash_funct() const
841        {return __table_.hash_function().hash_function();}
842    _LIBCPP_INLINE_VISIBILITY
843    key_equal key_eq() const
844        {return __table_.key_eq().key_eq();}
845
846    _LIBCPP_INLINE_VISIBILITY
847    iterator       find(const key_type& __k)       {return __table_.find(__k);}
848    _LIBCPP_INLINE_VISIBILITY
849    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
850    _LIBCPP_INLINE_VISIBILITY
851    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
852    _LIBCPP_INLINE_VISIBILITY
853    std::pair<iterator, iterator>             equal_range(const key_type& __k)
854        {return __table_.__equal_range_multi(__k);}
855    _LIBCPP_INLINE_VISIBILITY
856    std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
857        {return __table_.__equal_range_multi(__k);}
858
859    _LIBCPP_INLINE_VISIBILITY
860    size_type bucket_count() const {return __table_.bucket_count();}
861    _LIBCPP_INLINE_VISIBILITY
862    size_type max_bucket_count() const {return __table_.max_bucket_count();}
863
864    _LIBCPP_INLINE_VISIBILITY
865    size_type elems_in_bucket(size_type __n) const
866        {return __table_.bucket_size(__n);}
867
868    _LIBCPP_INLINE_VISIBILITY
869    void resize(size_type __n) {__table_.rehash(__n);}
870};
871
872template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
873hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
874        size_type __n, const hasher& __hf, const key_equal& __eql)
875    : __table_(__hf, __eql)
876{
877    __table_.rehash(__n);
878}
879
880template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
881hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
882        size_type __n, const hasher& __hf, const key_equal& __eql,
883        const allocator_type& __a)
884    : __table_(__hf, __eql, __a)
885{
886    __table_.rehash(__n);
887}
888
889template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
890template <class _InputIterator>
891hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
892        _InputIterator __first, _InputIterator __last)
893{
894    __table_.rehash(193);
895    insert(__first, __last);
896}
897
898template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
899template <class _InputIterator>
900hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
901        _InputIterator __first, _InputIterator __last, size_type __n,
902        const hasher& __hf, const key_equal& __eql)
903    : __table_(__hf, __eql)
904{
905    __table_.rehash(__n);
906    insert(__first, __last);
907}
908
909template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
910template <class _InputIterator>
911hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
912        _InputIterator __first, _InputIterator __last, size_type __n,
913        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
914    : __table_(__hf, __eql, __a)
915{
916    __table_.rehash(__n);
917    insert(__first, __last);
918}
919
920template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
921hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
922        const hash_multimap& __u)
923    : __table_(__u.__table_)
924{
925    __table_.rehash(__u.bucket_count());
926    insert(__u.begin(), __u.end());
927}
928
929template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
930template <class _InputIterator>
931inline
932void
933hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
934                                                            _InputIterator __last)
935{
936    for (; __first != __last; ++__first)
937        __table_.__insert_multi(*__first);
938}
939
940template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
941inline _LIBCPP_INLINE_VISIBILITY
942void
943swap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
944     hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
945{
946    __x.swap(__y);
947}
948
949template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
950bool
951operator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
952           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
953{
954    if (__x.size() != __y.size())
955        return false;
956    typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
957                                                                 const_iterator;
958    typedef std::pair<const_iterator, const_iterator> _EqRng;
959    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
960    {
961        _EqRng __xeq = __x.equal_range(__i->first);
962        _EqRng __yeq = __y.equal_range(__i->first);
963        if (_VSTD::distance(__xeq.first, __xeq.second) !=
964            _VSTD::distance(__yeq.first, __yeq.second) ||
965                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
966            return false;
967        __i = __xeq.second;
968    }
969    return true;
970}
971
972template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
973inline _LIBCPP_INLINE_VISIBILITY
974bool
975operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
976           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
977{
978    return !(__x == __y);
979}
980
981} // __gnu_cxx
982
983#endif  // _LIBCPP_HASH_MAP
984