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