xref: /freebsd/contrib/llvm-project/libcxx/include/ext/hash_map (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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
318    __hash_map_node_destructor& operator=(const __hash_map_node_destructor&);
319
320public:
321    bool __first_constructed;
322    bool __second_constructed;
323
324    _LIBCPP_INLINE_VISIBILITY
325    explicit __hash_map_node_destructor(allocator_type& __na)
326        : __na_(__na),
327          __first_constructed(false),
328          __second_constructed(false)
329        {}
330
331#ifndef _LIBCPP_CXX03_LANG
332    _LIBCPP_INLINE_VISIBILITY
333    __hash_map_node_destructor(std::__hash_node_destructor<allocator_type>&& __x)
334        : __na_(__x.__na_),
335          __first_constructed(__x.__value_constructed),
336          __second_constructed(__x.__value_constructed)
337        {
338            __x.__value_constructed = false;
339        }
340#else  // _LIBCPP_CXX03_LANG
341    _LIBCPP_INLINE_VISIBILITY
342    __hash_map_node_destructor(const std::__hash_node_destructor<allocator_type>& __x)
343        : __na_(__x.__na_),
344          __first_constructed(__x.__value_constructed),
345          __second_constructed(__x.__value_constructed)
346        {
347            const_cast<bool&>(__x.__value_constructed) = false;
348        }
349#endif  // _LIBCPP_CXX03_LANG
350
351    _LIBCPP_INLINE_VISIBILITY
352    void operator()(pointer __p)
353    {
354        if (__second_constructed)
355            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second));
356        if (__first_constructed)
357            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first));
358        if (__p)
359            __alloc_traits::deallocate(__na_, __p, 1);
360    }
361};
362
363template <class _HashIterator>
364class _LIBCPP_TEMPLATE_VIS __hash_map_iterator
365{
366    _HashIterator __i_;
367
368    typedef const typename _HashIterator::value_type::first_type key_type;
369    typedef typename _HashIterator::value_type::second_type      mapped_type;
370public:
371    typedef std::forward_iterator_tag                            iterator_category;
372    typedef std::pair<key_type, mapped_type>                     value_type;
373    typedef typename _HashIterator::difference_type              difference_type;
374    typedef value_type&                                          reference;
375    typedef typename std::__rebind_pointer<typename _HashIterator::pointer, value_type>::type
376        pointer;
377
378    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() {}
379
380    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator(_HashIterator __i) : __i_(__i) {}
381
382    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *operator->();}
383    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return (pointer)__i_.operator->();}
384
385    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;}
386    _LIBCPP_INLINE_VISIBILITY
387    __hash_map_iterator operator++(int)
388    {
389        __hash_map_iterator __t(*this);
390        ++(*this);
391        return __t;
392    }
393
394    friend _LIBCPP_INLINE_VISIBILITY
395    bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
396        {return __x.__i_ == __y.__i_;}
397    friend _LIBCPP_INLINE_VISIBILITY
398    bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
399        {return __x.__i_ != __y.__i_;}
400
401    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map;
402    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
403    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
404    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
405    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
406};
407
408template <class _HashIterator>
409class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator
410{
411    _HashIterator __i_;
412
413    typedef const typename _HashIterator::value_type::first_type key_type;
414    typedef typename _HashIterator::value_type::second_type      mapped_type;
415public:
416    typedef std::forward_iterator_tag                            iterator_category;
417    typedef std::pair<key_type, mapped_type>                     value_type;
418    typedef typename _HashIterator::difference_type              difference_type;
419    typedef const value_type&                                    reference;
420    typedef typename std::__rebind_pointer<typename _HashIterator::pointer, const value_type>::type
421        pointer;
422
423    _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() {}
424
425    _LIBCPP_INLINE_VISIBILITY
426    __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {}
427    _LIBCPP_INLINE_VISIBILITY
428    __hash_map_const_iterator(
429            __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
430                : __i_(__i.__i_) {}
431
432    _LIBCPP_INLINE_VISIBILITY
433    reference operator*() const {return *operator->();}
434    _LIBCPP_INLINE_VISIBILITY
435    pointer operator->() const {return (pointer)__i_.operator->();}
436
437    _LIBCPP_INLINE_VISIBILITY
438    __hash_map_const_iterator& operator++() {++__i_; return *this;}
439    _LIBCPP_INLINE_VISIBILITY
440    __hash_map_const_iterator operator++(int)
441    {
442        __hash_map_const_iterator __t(*this);
443        ++(*this);
444        return __t;
445    }
446
447    friend _LIBCPP_INLINE_VISIBILITY
448    bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
449        {return __x.__i_ == __y.__i_;}
450    friend _LIBCPP_INLINE_VISIBILITY
451    bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
452        {return __x.__i_ != __y.__i_;}
453
454    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map;
455    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
456    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
457    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
458};
459
460template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>,
461          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
462class _LIBCPP_TEMPLATE_VIS hash_map
463{
464public:
465    // types
466    typedef _Key                                           key_type;
467    typedef _Tp                                            mapped_type;
468    typedef _Tp                                            data_type;
469    typedef _Hash                                          hasher;
470    typedef _Pred                                          key_equal;
471    typedef _Alloc                                         allocator_type;
472    typedef std::pair<const key_type, mapped_type>         value_type;
473    typedef value_type&                                    reference;
474    typedef const value_type&                              const_reference;
475
476private:
477    typedef std::pair<key_type, mapped_type>                    __value_type;
478    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
479    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
480    typedef typename std::__rebind_alloc_helper<
481        std::allocator_traits<allocator_type>, __value_type>::type __allocator_type;
482
483    typedef std::__hash_table<__value_type, __hasher,
484                         __key_equal,  __allocator_type>   __table;
485
486    __table __table_;
487
488    typedef typename __table::__node_pointer               __node_pointer;
489    typedef typename __table::__node_const_pointer         __node_const_pointer;
490    typedef typename __table::__node_traits                __node_traits;
491    typedef typename __table::__node_allocator             __node_allocator;
492    typedef typename __table::__node                       __node;
493    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
494    typedef std::unique_ptr<__node, _Dp>                   __node_holder;
495    typedef std::allocator_traits<allocator_type>          __alloc_traits;
496public:
497    typedef typename __alloc_traits::pointer         pointer;
498    typedef typename __alloc_traits::const_pointer   const_pointer;
499    typedef typename __alloc_traits::size_type       size_type;
500    typedef typename __alloc_traits::difference_type difference_type;
501
502    typedef __hash_map_iterator<typename __table::iterator>       iterator;
503    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
504
505    _LIBCPP_INLINE_VISIBILITY hash_map() {__table_.rehash(193);}
506    explicit hash_map(size_type __n, const hasher& __hf = hasher(),
507                           const key_equal& __eql = key_equal());
508    hash_map(size_type __n, const hasher& __hf,
509                  const key_equal& __eql,
510                  const allocator_type& __a);
511    template <class _InputIterator>
512        hash_map(_InputIterator __first, _InputIterator __last);
513    template <class _InputIterator>
514        hash_map(_InputIterator __first, _InputIterator __last,
515                      size_type __n, const hasher& __hf = hasher(),
516                      const key_equal& __eql = key_equal());
517    template <class _InputIterator>
518        hash_map(_InputIterator __first, _InputIterator __last,
519                      size_type __n, const hasher& __hf,
520                      const key_equal& __eql,
521                      const allocator_type& __a);
522    hash_map(const hash_map& __u);
523
524    _LIBCPP_INLINE_VISIBILITY
525    allocator_type get_allocator() const
526        {return allocator_type(__table_.__node_alloc());}
527
528    _LIBCPP_INLINE_VISIBILITY
529    bool      empty() const {return __table_.size() == 0;}
530    _LIBCPP_INLINE_VISIBILITY
531    size_type size() const  {return __table_.size();}
532    _LIBCPP_INLINE_VISIBILITY
533    size_type max_size() const {return __table_.max_size();}
534
535    _LIBCPP_INLINE_VISIBILITY
536    iterator       begin()        {return __table_.begin();}
537    _LIBCPP_INLINE_VISIBILITY
538    iterator       end()          {return __table_.end();}
539    _LIBCPP_INLINE_VISIBILITY
540    const_iterator begin()  const {return __table_.begin();}
541    _LIBCPP_INLINE_VISIBILITY
542    const_iterator end()    const {return __table_.end();}
543
544    _LIBCPP_INLINE_VISIBILITY
545    std::pair<iterator, bool> insert(const value_type& __x)
546        {return __table_.__insert_unique(__x);}
547    _LIBCPP_INLINE_VISIBILITY
548    iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}
549    template <class _InputIterator>
550        _LIBCPP_INLINE_VISIBILITY
551        void insert(_InputIterator __first, _InputIterator __last);
552
553    _LIBCPP_INLINE_VISIBILITY
554    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
555    _LIBCPP_INLINE_VISIBILITY
556    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
557    _LIBCPP_INLINE_VISIBILITY
558    void erase(const_iterator __first, const_iterator __last)
559        {__table_.erase(__first.__i_, __last.__i_);}
560    _LIBCPP_INLINE_VISIBILITY
561    void clear() {__table_.clear();}
562
563    _LIBCPP_INLINE_VISIBILITY
564    void swap(hash_map& __u) {__table_.swap(__u.__table_);}
565
566    _LIBCPP_INLINE_VISIBILITY
567    hasher hash_funct() const
568        {return __table_.hash_function().hash_function();}
569    _LIBCPP_INLINE_VISIBILITY
570    key_equal key_eq() const
571        {return __table_.key_eq().key_eq();}
572
573    _LIBCPP_INLINE_VISIBILITY
574    iterator       find(const key_type& __k)       {return __table_.find(__k);}
575    _LIBCPP_INLINE_VISIBILITY
576    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
577    _LIBCPP_INLINE_VISIBILITY
578    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
579    _LIBCPP_INLINE_VISIBILITY
580    std::pair<iterator, iterator>             equal_range(const key_type& __k)
581        {return __table_.__equal_range_unique(__k);}
582    _LIBCPP_INLINE_VISIBILITY
583    std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
584        {return __table_.__equal_range_unique(__k);}
585
586    mapped_type& operator[](const key_type& __k);
587
588    _LIBCPP_INLINE_VISIBILITY
589    size_type bucket_count() const {return __table_.bucket_count();}
590    _LIBCPP_INLINE_VISIBILITY
591    size_type max_bucket_count() const {return __table_.max_bucket_count();}
592
593    _LIBCPP_INLINE_VISIBILITY
594    size_type elems_in_bucket(size_type __n) const
595        {return __table_.bucket_size(__n);}
596
597    _LIBCPP_INLINE_VISIBILITY
598    void resize(size_type __n) {__table_.rehash(__n);}
599
600private:
601    __node_holder __construct_node(const key_type& __k);
602};
603
604template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
605hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
606        size_type __n, const hasher& __hf, const key_equal& __eql)
607    : __table_(__hf, __eql)
608{
609    __table_.rehash(__n);
610}
611
612template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
613hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
614        size_type __n, const hasher& __hf, const key_equal& __eql,
615        const allocator_type& __a)
616    : __table_(__hf, __eql, __a)
617{
618    __table_.rehash(__n);
619}
620
621template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
622template <class _InputIterator>
623hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
624        _InputIterator __first, _InputIterator __last)
625{
626    __table_.rehash(193);
627    insert(__first, __last);
628}
629
630template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
631template <class _InputIterator>
632hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
633        _InputIterator __first, _InputIterator __last, size_type __n,
634        const hasher& __hf, const key_equal& __eql)
635    : __table_(__hf, __eql)
636{
637    __table_.rehash(__n);
638    insert(__first, __last);
639}
640
641template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
642template <class _InputIterator>
643hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
644        _InputIterator __first, _InputIterator __last, size_type __n,
645        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
646    : __table_(__hf, __eql, __a)
647{
648    __table_.rehash(__n);
649    insert(__first, __last);
650}
651
652template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
653hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
654        const hash_map& __u)
655    : __table_(__u.__table_)
656{
657    __table_.rehash(__u.bucket_count());
658    insert(__u.begin(), __u.end());
659}
660
661template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
662typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
663hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k)
664{
665    __node_allocator& __na = __table_.__node_alloc();
666    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
667    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k);
668    __h.get_deleter().__first_constructed = true;
669    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
670    __h.get_deleter().__second_constructed = true;
671    return _LIBCPP_EXPLICIT_MOVE(__h);  // explicitly moved for C++03
672}
673
674template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
675template <class _InputIterator>
676inline
677void
678hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
679                                                       _InputIterator __last)
680{
681    for (; __first != __last; ++__first)
682        __table_.__insert_unique(*__first);
683}
684
685template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
686_Tp&
687hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
688{
689    iterator __i = find(__k);
690    if (__i != end())
691        return __i->second;
692    __node_holder __h = __construct_node(__k);
693    std::pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
694    __h.release();
695    return __r.first->second;
696}
697
698template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
699inline _LIBCPP_INLINE_VISIBILITY
700void
701swap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
702     hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
703{
704    __x.swap(__y);
705}
706
707template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
708bool
709operator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
710           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
711{
712    if (__x.size() != __y.size())
713        return false;
714    typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
715                                                                 const_iterator;
716    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
717            __i != __ex; ++__i)
718    {
719        const_iterator __j = __y.find(__i->first);
720        if (__j == __ey || !(*__i == *__j))
721            return false;
722    }
723    return true;
724}
725
726template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
727inline _LIBCPP_INLINE_VISIBILITY
728bool
729operator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
730           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
731{
732    return !(__x == __y);
733}
734
735template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>,
736          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
737class _LIBCPP_TEMPLATE_VIS hash_multimap
738{
739public:
740    // types
741    typedef _Key                                           key_type;
742    typedef _Tp                                            mapped_type;
743    typedef _Tp                                            data_type;
744    typedef _Hash                                          hasher;
745    typedef _Pred                                          key_equal;
746    typedef _Alloc                                         allocator_type;
747    typedef std::pair<const key_type, mapped_type>         value_type;
748    typedef value_type&                                    reference;
749    typedef const value_type&                              const_reference;
750
751private:
752    typedef std::pair<key_type, mapped_type>               __value_type;
753    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
754    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
755    typedef typename std::__rebind_alloc_helper<std::allocator_traits<allocator_type>, __value_type>::type __allocator_type;
756
757    typedef std::__hash_table<__value_type, __hasher,
758                         __key_equal,  __allocator_type>   __table;
759
760    __table __table_;
761
762    typedef typename __table::__node_traits                __node_traits;
763    typedef typename __table::__node_allocator             __node_allocator;
764    typedef typename __table::__node                       __node;
765    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
766    typedef std::unique_ptr<__node, _Dp>                         __node_holder;
767    typedef std::allocator_traits<allocator_type>               __alloc_traits;
768public:
769    typedef typename __alloc_traits::pointer         pointer;
770    typedef typename __alloc_traits::const_pointer   const_pointer;
771    typedef typename __alloc_traits::size_type       size_type;
772    typedef typename __alloc_traits::difference_type difference_type;
773
774    typedef __hash_map_iterator<typename __table::iterator>       iterator;
775    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
776
777    _LIBCPP_INLINE_VISIBILITY
778    hash_multimap() {__table_.rehash(193);}
779    explicit hash_multimap(size_type __n, const hasher& __hf = hasher(),
780                                const key_equal& __eql = key_equal());
781    hash_multimap(size_type __n, const hasher& __hf,
782                                const key_equal& __eql,
783                                const allocator_type& __a);
784    template <class _InputIterator>
785        hash_multimap(_InputIterator __first, _InputIterator __last);
786    template <class _InputIterator>
787        hash_multimap(_InputIterator __first, _InputIterator __last,
788                      size_type __n, const hasher& __hf = hasher(),
789                      const key_equal& __eql = key_equal());
790    template <class _InputIterator>
791        hash_multimap(_InputIterator __first, _InputIterator __last,
792                      size_type __n, const hasher& __hf,
793                      const key_equal& __eql,
794                      const allocator_type& __a);
795    hash_multimap(const hash_multimap& __u);
796
797    _LIBCPP_INLINE_VISIBILITY
798    allocator_type get_allocator() const
799        {return allocator_type(__table_.__node_alloc());}
800
801    _LIBCPP_INLINE_VISIBILITY
802    bool      empty() const {return __table_.size() == 0;}
803    _LIBCPP_INLINE_VISIBILITY
804    size_type size() const  {return __table_.size();}
805    _LIBCPP_INLINE_VISIBILITY
806    size_type max_size() const {return __table_.max_size();}
807
808    _LIBCPP_INLINE_VISIBILITY
809    iterator       begin()        {return __table_.begin();}
810    _LIBCPP_INLINE_VISIBILITY
811    iterator       end()          {return __table_.end();}
812    _LIBCPP_INLINE_VISIBILITY
813    const_iterator begin()  const {return __table_.begin();}
814    _LIBCPP_INLINE_VISIBILITY
815    const_iterator end()    const {return __table_.end();}
816
817    _LIBCPP_INLINE_VISIBILITY
818    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
819    _LIBCPP_INLINE_VISIBILITY
820    iterator insert(const_iterator, const value_type& __x) {return insert(__x);}
821    template <class _InputIterator>
822        _LIBCPP_INLINE_VISIBILITY
823        void insert(_InputIterator __first, _InputIterator __last);
824
825    _LIBCPP_INLINE_VISIBILITY
826    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
827    _LIBCPP_INLINE_VISIBILITY
828    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
829    _LIBCPP_INLINE_VISIBILITY
830    void erase(const_iterator __first, const_iterator __last)
831        {__table_.erase(__first.__i_, __last.__i_);}
832    _LIBCPP_INLINE_VISIBILITY
833    void clear() {__table_.clear();}
834
835    _LIBCPP_INLINE_VISIBILITY
836    void swap(hash_multimap& __u) {__table_.swap(__u.__table_);}
837
838    _LIBCPP_INLINE_VISIBILITY
839    hasher hash_funct() const
840        {return __table_.hash_function().hash_function();}
841    _LIBCPP_INLINE_VISIBILITY
842    key_equal key_eq() const
843        {return __table_.key_eq().key_eq();}
844
845    _LIBCPP_INLINE_VISIBILITY
846    iterator       find(const key_type& __k)       {return __table_.find(__k);}
847    _LIBCPP_INLINE_VISIBILITY
848    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
849    _LIBCPP_INLINE_VISIBILITY
850    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
851    _LIBCPP_INLINE_VISIBILITY
852    std::pair<iterator, iterator>             equal_range(const key_type& __k)
853        {return __table_.__equal_range_multi(__k);}
854    _LIBCPP_INLINE_VISIBILITY
855    std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
856        {return __table_.__equal_range_multi(__k);}
857
858    _LIBCPP_INLINE_VISIBILITY
859    size_type bucket_count() const {return __table_.bucket_count();}
860    _LIBCPP_INLINE_VISIBILITY
861    size_type max_bucket_count() const {return __table_.max_bucket_count();}
862
863    _LIBCPP_INLINE_VISIBILITY
864    size_type elems_in_bucket(size_type __n) const
865        {return __table_.bucket_size(__n);}
866
867    _LIBCPP_INLINE_VISIBILITY
868    void resize(size_type __n) {__table_.rehash(__n);}
869};
870
871template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
872hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
873        size_type __n, const hasher& __hf, const key_equal& __eql)
874    : __table_(__hf, __eql)
875{
876    __table_.rehash(__n);
877}
878
879template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
880hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
881        size_type __n, const hasher& __hf, const key_equal& __eql,
882        const allocator_type& __a)
883    : __table_(__hf, __eql, __a)
884{
885    __table_.rehash(__n);
886}
887
888template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
889template <class _InputIterator>
890hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
891        _InputIterator __first, _InputIterator __last)
892{
893    __table_.rehash(193);
894    insert(__first, __last);
895}
896
897template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
898template <class _InputIterator>
899hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
900        _InputIterator __first, _InputIterator __last, size_type __n,
901        const hasher& __hf, const key_equal& __eql)
902    : __table_(__hf, __eql)
903{
904    __table_.rehash(__n);
905    insert(__first, __last);
906}
907
908template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
909template <class _InputIterator>
910hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
911        _InputIterator __first, _InputIterator __last, size_type __n,
912        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
913    : __table_(__hf, __eql, __a)
914{
915    __table_.rehash(__n);
916    insert(__first, __last);
917}
918
919template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
920hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
921        const hash_multimap& __u)
922    : __table_(__u.__table_)
923{
924    __table_.rehash(__u.bucket_count());
925    insert(__u.begin(), __u.end());
926}
927
928template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
929template <class _InputIterator>
930inline
931void
932hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
933                                                            _InputIterator __last)
934{
935    for (; __first != __last; ++__first)
936        __table_.__insert_multi(*__first);
937}
938
939template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
940inline _LIBCPP_INLINE_VISIBILITY
941void
942swap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
943     hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
944{
945    __x.swap(__y);
946}
947
948template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
949bool
950operator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
951           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
952{
953    if (__x.size() != __y.size())
954        return false;
955    typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
956                                                                 const_iterator;
957    typedef std::pair<const_iterator, const_iterator> _EqRng;
958    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
959    {
960        _EqRng __xeq = __x.equal_range(__i->first);
961        _EqRng __yeq = __y.equal_range(__i->first);
962        if (_VSTD::distance(__xeq.first, __xeq.second) !=
963            _VSTD::distance(__yeq.first, __yeq.second) ||
964                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
965            return false;
966        __i = __xeq.second;
967    }
968    return true;
969}
970
971template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
972inline _LIBCPP_INLINE_VISIBILITY
973bool
974operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
975           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
976{
977    return !(__x == __y);
978}
979
980} // __gnu_cxx
981
982#endif  // _LIBCPP_HASH_MAP
983