2 // Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
3 // Copyright (C) 2005-2009 Daniel James.
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // See http://www.boost.org/libs/unordered for documentation
9 #ifndef BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
10 #define BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
12 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
16 #include <boost/unordered/unordered_map_fwd.hpp>
17 #include <boost/functional/hash.hpp>
18 #include <boost/unordered/detail/hash_table.hpp>
20 #if !defined(BOOST_HAS_RVALUE_REFS)
21 #include <boost/unordered/detail/move.hpp>
24 #if defined(BOOST_MSVC)
26 #if BOOST_MSVC >= 1400
27 #pragma warning(disable:4396) //the inline specifier cannot be used when a
28 // friend declaration refers to a specialization
29 // of a function template
35 template <class Key
, class T
, class Hash
, class Pred
, class Alloc
>
38 typedef boost::unordered_detail::hash_types_unique_keys
<
39 std::pair
<const Key
, T
>, Key
, Hash
, Pred
, Alloc
42 BOOST_DEDUCED_TYPENAME
implementation::hash_table base
;
49 typedef std::pair
<const Key
, T
> value_type
;
50 typedef T mapped_type
;
52 typedef Pred key_equal
;
54 typedef Alloc allocator_type
;
55 typedef BOOST_DEDUCED_TYPENAME
allocator_type::pointer pointer
;
56 typedef BOOST_DEDUCED_TYPENAME
allocator_type::const_pointer const_pointer
;
57 typedef BOOST_DEDUCED_TYPENAME
allocator_type::reference reference
;
58 typedef BOOST_DEDUCED_TYPENAME
allocator_type::const_reference const_reference
;
60 typedef BOOST_DEDUCED_TYPENAME
implementation::size_type size_type
;
61 typedef BOOST_DEDUCED_TYPENAME
implementation::difference_type difference_type
;
63 typedef BOOST_DEDUCED_TYPENAME
implementation::iterator iterator
;
64 typedef BOOST_DEDUCED_TYPENAME
implementation::const_iterator const_iterator
;
65 typedef BOOST_DEDUCED_TYPENAME
implementation::local_iterator local_iterator
;
66 typedef BOOST_DEDUCED_TYPENAME
implementation::const_local_iterator const_local_iterator
;
68 // construct/destroy/copy
70 explicit unordered_map(
71 size_type n
= boost::unordered_detail::default_initial_bucket_count
,
72 const hasher
&hf
= hasher(),
73 const key_equal
&eql
= key_equal(),
74 const allocator_type
&a
= allocator_type())
79 explicit unordered_map(allocator_type
const& a
)
80 : base(boost::unordered_detail::default_initial_bucket_count
,
81 hasher(), key_equal(), a
)
85 unordered_map(unordered_map
const& other
, allocator_type
const& a
)
90 template <class InputIterator
>
91 unordered_map(InputIterator f
, InputIterator l
)
92 : base(f
, l
, boost::unordered_detail::default_initial_bucket_count
,
93 hasher(), key_equal(), allocator_type())
97 template <class InputIterator
>
98 unordered_map(InputIterator f
, InputIterator l
,
100 const hasher
&hf
= hasher(),
101 const key_equal
&eql
= key_equal(),
102 const allocator_type
&a
= allocator_type())
103 : base(f
, l
, n
, hf
, eql
, a
)
107 #if defined(BOOST_HAS_RVALUE_REFS)
108 unordered_map(unordered_map
&& other
)
109 : base(other
.base
, boost::unordered_detail::move_tag())
113 unordered_map(unordered_map
&& other
, allocator_type
const& a
)
114 : base(other
.base
, a
, boost::unordered_detail::move_tag())
118 unordered_map
& operator=(unordered_map
&& x
)
124 unordered_map(boost::unordered_detail::move_from
<unordered_map
<Key
, T
, Hash
, Pred
, Alloc
> > other
)
125 : base(other
.source
.base
, boost::unordered_detail::move_tag())
129 #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
130 unordered_map
& operator=(unordered_map x
)
138 #if !defined(BOOST_NO_INITIALIZER_LISTS)
139 unordered_map(std::initializer_list
<value_type
> list
,
140 size_type n
= boost::unordered_detail::default_initial_bucket_count
,
141 const hasher
&hf
= hasher(),
142 const key_equal
&eql
= key_equal(),
143 const allocator_type
&a
= allocator_type())
144 : base(list
.begin(), list
.end(), n
, hf
, eql
, a
)
148 unordered_map
& operator=(std::initializer_list
<value_type
> list
)
151 base
.insert_range(list
.begin(), list
.end());
158 BOOST_DEDUCED_TYPENAME
implementation::iterator_base
const&
159 get(const_iterator
const& it
)
161 return boost::unordered_detail::iterator_access::get(it
);
166 allocator_type
get_allocator() const
168 return base
.get_allocator();
178 size_type
size() const
183 size_type
max_size() const
185 return base
.max_size();
192 return iterator(base
.data_
.begin());
195 const_iterator
begin() const
197 return const_iterator(base
.data_
.begin());
202 return iterator(base
.data_
.end());
205 const_iterator
end() const
207 return const_iterator(base
.data_
.end());
210 const_iterator
cbegin() const
212 return const_iterator(base
.data_
.begin());
215 const_iterator
cend() const
217 return const_iterator(base
.data_
.end());
222 #if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
223 template <class... Args
>
224 std::pair
<iterator
, bool> emplace(Args
&&... args
)
226 return boost::unordered_detail::pair_cast
<iterator
, bool>(
227 base
.emplace(std::forward
<Args
>(args
)...));
230 template <class... Args
>
231 iterator
emplace_hint(const_iterator hint
, Args
&&... args
)
233 return iterator(base
.emplace_hint(get(hint
), std::forward
<Args
>(args
)...));
237 std::pair
<iterator
, bool> emplace(value_type
const& v
= value_type())
239 return boost::unordered_detail::pair_cast
<iterator
, bool>(
243 iterator
emplace_hint(const_iterator hint
, value_type
const& v
= value_type())
245 return iterator(base
.emplace_hint(get(hint
), v
));
248 #define BOOST_UNORDERED_EMPLACE(z, n, _) \
250 BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
252 std::pair<iterator, bool> emplace( \
253 BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
256 return boost::unordered_detail::pair_cast<iterator, bool>( \
258 BOOST_UNORDERED_CALL_PARAMS(z, n) \
263 BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
265 iterator emplace_hint(const_iterator hint, \
266 BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
269 return iterator(base.emplace_hint(get(hint), \
270 BOOST_UNORDERED_CALL_PARAMS(z, n) \
274 BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT
,
275 BOOST_UNORDERED_EMPLACE
, _
)
277 #undef BOOST_UNORDERED_EMPLACE
281 std::pair
<iterator
, bool> insert(const value_type
& obj
)
283 return boost::unordered_detail::pair_cast
<iterator
, bool>(
287 iterator
insert(const_iterator hint
, const value_type
& obj
)
289 return iterator(base
.emplace_hint(get(hint
), obj
));
292 template <class InputIterator
>
293 void insert(InputIterator first
, InputIterator last
)
295 base
.insert_range(first
, last
);
298 iterator
erase(const_iterator position
)
300 return iterator(base
.data_
.erase(get(position
)));
303 size_type
erase(const key_type
& k
)
305 return base
.erase_key(k
);
308 iterator
erase(const_iterator first
, const_iterator last
)
310 return iterator(base
.data_
.erase_range(get(first
), get(last
)));
318 void swap(unordered_map
& other
)
320 base
.swap(other
.base
);
325 hasher
hash_function() const
327 return base
.hash_function();
330 key_equal
key_eq() const
332 return base
.key_eq();
335 mapped_type
& operator[](const key_type
&k
)
337 return base
[k
].second
;
340 mapped_type
& at(const key_type
& k
)
342 return base
.at(k
).second
;
345 mapped_type
const& at(const key_type
& k
) const
347 return base
.at(k
).second
;
352 iterator
find(const key_type
& k
)
354 return iterator(base
.find(k
));
357 const_iterator
find(const key_type
& k
) const
359 return const_iterator(base
.find(k
));
362 size_type
count(const key_type
& k
) const
364 return base
.count(k
);
367 std::pair
<iterator
, iterator
>
368 equal_range(const key_type
& k
)
370 return boost::unordered_detail::pair_cast
<iterator
, iterator
>(
371 base
.equal_range(k
));
374 std::pair
<const_iterator
, const_iterator
>
375 equal_range(const key_type
& k
) const
377 return boost::unordered_detail::pair_cast
<const_iterator
, const_iterator
>(
378 base
.equal_range(k
));
383 size_type
bucket_count() const
385 return base
.bucket_count();
388 size_type
max_bucket_count() const
390 return base
.max_bucket_count();
393 size_type
bucket_size(size_type n
) const
395 return base
.data_
.bucket_size(n
);
398 size_type
bucket(const key_type
& k
) const
400 return base
.bucket(k
);
403 local_iterator
begin(size_type n
)
405 return local_iterator(base
.data_
.begin(n
));
408 const_local_iterator
begin(size_type n
) const
410 return const_local_iterator(base
.data_
.begin(n
));
413 local_iterator
end(size_type n
)
415 return local_iterator(base
.data_
.end(n
));
418 const_local_iterator
end(size_type n
) const
420 return const_local_iterator(base
.data_
.end(n
));
423 const_local_iterator
cbegin(size_type n
) const
425 return const_local_iterator(base
.data_
.begin(n
));
428 const_local_iterator
cend(size_type n
) const
430 return const_local_iterator(base
.data_
.end(n
));
435 float load_factor() const
437 return base
.load_factor();
440 float max_load_factor() const
442 return base
.max_load_factor();
445 void max_load_factor(float m
)
447 base
.max_load_factor(m
);
450 void rehash(size_type n
)
455 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
456 friend bool operator==(unordered_map
const&, unordered_map
const&);
457 friend bool operator!=(unordered_map
const&, unordered_map
const&);
459 friend bool operator==<Key
, T
, Hash
, Pred
, Alloc
>(unordered_map
const&, unordered_map
const&);
460 friend bool operator!=<Key
, T
, Hash
, Pred
, Alloc
>(unordered_map
const&, unordered_map
const&);
462 }; // class template unordered_map
464 template <class K
, class T
, class H
, class P
, class A
>
465 inline bool operator==(unordered_map
<K
, T
, H
, P
, A
> const& m1
,
466 unordered_map
<K
, T
, H
, P
, A
> const& m2
)
468 return boost::unordered_detail::equals(m1
.base
, m2
.base
);
471 template <class K
, class T
, class H
, class P
, class A
>
472 inline bool operator!=(unordered_map
<K
, T
, H
, P
, A
> const& m1
,
473 unordered_map
<K
, T
, H
, P
, A
> const& m2
)
475 return !boost::unordered_detail::equals(m1
.base
, m2
.base
);
478 template <class K
, class T
, class H
, class P
, class A
>
479 inline void swap(unordered_map
<K
, T
, H
, P
, A
> &m1
,
480 unordered_map
<K
, T
, H
, P
, A
> &m2
)
485 template <class Key
, class T
, class Hash
, class Pred
, class Alloc
>
486 class unordered_multimap
488 typedef boost::unordered_detail::hash_types_equivalent_keys
<
489 std::pair
<const Key
, T
>, Key
, Hash
, Pred
, Alloc
492 BOOST_DEDUCED_TYPENAME
implementation::hash_table base
;
498 typedef Key key_type
;
499 typedef std::pair
<const Key
, T
> value_type
;
500 typedef T mapped_type
;
502 typedef Pred key_equal
;
504 typedef Alloc allocator_type
;
505 typedef BOOST_DEDUCED_TYPENAME
allocator_type::pointer pointer
;
506 typedef BOOST_DEDUCED_TYPENAME
allocator_type::const_pointer const_pointer
;
507 typedef BOOST_DEDUCED_TYPENAME
allocator_type::reference reference
;
508 typedef BOOST_DEDUCED_TYPENAME
allocator_type::const_reference const_reference
;
510 typedef BOOST_DEDUCED_TYPENAME
implementation::size_type size_type
;
511 typedef BOOST_DEDUCED_TYPENAME
implementation::difference_type difference_type
;
513 typedef BOOST_DEDUCED_TYPENAME
implementation::iterator iterator
;
514 typedef BOOST_DEDUCED_TYPENAME
implementation::const_iterator const_iterator
;
515 typedef BOOST_DEDUCED_TYPENAME
implementation::local_iterator local_iterator
;
516 typedef BOOST_DEDUCED_TYPENAME
implementation::const_local_iterator const_local_iterator
;
518 // construct/destroy/copy
520 explicit unordered_multimap(
521 size_type n
= boost::unordered_detail::default_initial_bucket_count
,
522 const hasher
&hf
= hasher(),
523 const key_equal
&eql
= key_equal(),
524 const allocator_type
&a
= allocator_type())
525 : base(n
, hf
, eql
, a
)
529 explicit unordered_multimap(allocator_type
const& a
)
530 : base(boost::unordered_detail::default_initial_bucket_count
,
531 hasher(), key_equal(), a
)
535 unordered_multimap(unordered_multimap
const& other
, allocator_type
const& a
)
536 : base(other
.base
, a
)
540 template <class InputIterator
>
541 unordered_multimap(InputIterator f
, InputIterator l
)
542 : base(f
, l
, boost::unordered_detail::default_initial_bucket_count
,
543 hasher(), key_equal(), allocator_type())
547 template <class InputIterator
>
548 unordered_multimap(InputIterator f
, InputIterator l
,
550 const hasher
&hf
= hasher(),
551 const key_equal
&eql
= key_equal(),
552 const allocator_type
&a
= allocator_type())
553 : base(f
, l
, n
, hf
, eql
, a
)
557 #if defined(BOOST_HAS_RVALUE_REFS)
558 unordered_multimap(unordered_multimap
&& other
)
559 : base(other
.base
, boost::unordered_detail::move_tag())
563 unordered_multimap(unordered_multimap
&& other
, allocator_type
const& a
)
564 : base(other
.base
, a
, boost::unordered_detail::move_tag())
568 unordered_multimap
& operator=(unordered_multimap
&& x
)
574 unordered_multimap(boost::unordered_detail::move_from
<unordered_multimap
<Key
, T
, Hash
, Pred
, Alloc
> > other
)
575 : base(other
.source
.base
, boost::unordered_detail::move_tag())
579 #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
580 unordered_multimap
& operator=(unordered_multimap x
)
588 #if !defined(BOOST_NO_INITIALIZER_LISTS)
589 unordered_multimap(std::initializer_list
<value_type
> list
,
590 size_type n
= boost::unordered_detail::default_initial_bucket_count
,
591 const hasher
&hf
= hasher(),
592 const key_equal
&eql
= key_equal(),
593 const allocator_type
&a
= allocator_type())
594 : base(list
.begin(), list
.end(), n
, hf
, eql
, a
)
598 unordered_multimap
& operator=(std::initializer_list
<value_type
> list
)
601 base
.insert_range(list
.begin(), list
.end());
609 BOOST_DEDUCED_TYPENAME
implementation::iterator_base
const&
610 get(const_iterator
const& it
)
612 return boost::unordered_detail::iterator_access::get(it
);
617 allocator_type
get_allocator() const
619 return base
.get_allocator();
629 size_type
size() const
634 size_type
max_size() const
636 return base
.max_size();
643 return iterator(base
.data_
.begin());
646 const_iterator
begin() const
648 return const_iterator(base
.data_
.begin());
653 return iterator(base
.data_
.end());
656 const_iterator
end() const
658 return const_iterator(base
.data_
.end());
661 const_iterator
cbegin() const
663 return const_iterator(base
.data_
.begin());
666 const_iterator
cend() const
668 return const_iterator(base
.data_
.end());
673 #if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
674 template <class... Args
>
675 iterator
emplace(Args
&&... args
)
677 return iterator(base
.emplace(std::forward
<Args
>(args
)...));
680 template <class... Args
>
681 iterator
emplace_hint(const_iterator hint
, Args
&&... args
)
683 return iterator(base
.emplace_hint(get(hint
), std::forward
<Args
>(args
)...));
687 iterator
emplace(value_type
const& v
= value_type())
689 return iterator(base
.emplace(v
));
692 iterator
emplace_hint(const_iterator hint
, value_type
const& v
= value_type())
694 return iterator(base
.emplace_hint(get(hint
), v
));
698 #define BOOST_UNORDERED_EMPLACE(z, n, _) \
700 BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
703 BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
708 BOOST_UNORDERED_CALL_PARAMS(z, n) \
713 BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
715 iterator emplace_hint(const_iterator hint, \
716 BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
719 return iterator(base.emplace_hint(get(hint), \
720 BOOST_UNORDERED_CALL_PARAMS(z, n) \
724 BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT
,
725 BOOST_UNORDERED_EMPLACE
, _
)
727 #undef BOOST_UNORDERED_EMPLACE
731 iterator
insert(const value_type
& obj
)
733 return iterator(base
.emplace(obj
));
736 iterator
insert(const_iterator hint
, const value_type
& obj
)
738 return iterator(base
.emplace_hint(get(hint
), obj
));
741 template <class InputIterator
>
742 void insert(InputIterator first
, InputIterator last
)
744 base
.insert_range(first
, last
);
747 iterator
erase(const_iterator position
)
749 return iterator(base
.data_
.erase(get(position
)));
752 size_type
erase(const key_type
& k
)
754 return base
.erase_key(k
);
757 iterator
erase(const_iterator first
, const_iterator last
)
759 return iterator(base
.data_
.erase_range(get(first
), get(last
)));
767 void swap(unordered_multimap
& other
)
769 base
.swap(other
.base
);
774 hasher
hash_function() const
776 return base
.hash_function();
779 key_equal
key_eq() const
781 return base
.key_eq();
786 iterator
find(const key_type
& k
)
788 return iterator(base
.find(k
));
791 const_iterator
find(const key_type
& k
) const
793 return const_iterator(base
.find(k
));
796 size_type
count(const key_type
& k
) const
798 return base
.count(k
);
801 std::pair
<iterator
, iterator
>
802 equal_range(const key_type
& k
)
804 return boost::unordered_detail::pair_cast
<iterator
, iterator
>(
805 base
.equal_range(k
));
808 std::pair
<const_iterator
, const_iterator
>
809 equal_range(const key_type
& k
) const
811 return boost::unordered_detail::pair_cast
<const_iterator
, const_iterator
>(
812 base
.equal_range(k
));
817 size_type
bucket_count() const
819 return base
.bucket_count();
822 size_type
max_bucket_count() const
824 return base
.max_bucket_count();
827 size_type
bucket_size(size_type n
) const
829 return base
.data_
.bucket_size(n
);
832 size_type
bucket(const key_type
& k
) const
834 return base
.bucket(k
);
837 local_iterator
begin(size_type n
)
839 return local_iterator(base
.data_
.begin(n
));
842 const_local_iterator
begin(size_type n
) const
844 return const_local_iterator(base
.data_
.begin(n
));
847 local_iterator
end(size_type n
)
849 return local_iterator(base
.data_
.end(n
));
852 const_local_iterator
end(size_type n
) const
854 return const_local_iterator(base
.data_
.end(n
));
857 const_local_iterator
cbegin(size_type n
) const
859 return const_local_iterator(base
.data_
.begin(n
));
862 const_local_iterator
cend(size_type n
) const
864 return const_local_iterator(base
.data_
.end(n
));
869 float load_factor() const
871 return base
.load_factor();
874 float max_load_factor() const
876 return base
.max_load_factor();
879 void max_load_factor(float m
)
881 base
.max_load_factor(m
);
884 void rehash(size_type n
)
889 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
890 friend bool operator==(unordered_multimap
const&, unordered_multimap
const&);
891 friend bool operator!=(unordered_multimap
const&, unordered_multimap
const&);
893 friend bool operator==<Key
, T
, Hash
, Pred
, Alloc
>(unordered_multimap
const&, unordered_multimap
const&);
894 friend bool operator!=<Key
, T
, Hash
, Pred
, Alloc
>(unordered_multimap
const&, unordered_multimap
const&);
896 }; // class template unordered_multimap
898 template <class K
, class T
, class H
, class P
, class A
>
899 inline bool operator==(unordered_multimap
<K
, T
, H
, P
, A
> const& m1
,
900 unordered_multimap
<K
, T
, H
, P
, A
> const& m2
)
902 return boost::unordered_detail::equals(m1
.base
, m2
.base
);
905 template <class K
, class T
, class H
, class P
, class A
>
906 inline bool operator!=(unordered_multimap
<K
, T
, H
, P
, A
> const& m1
,
907 unordered_multimap
<K
, T
, H
, P
, A
> const& m2
)
909 return !boost::unordered_detail::equals(m1
.base
, m2
.base
);
912 template <class K
, class T
, class H
, class P
, class A
>
913 inline void swap(unordered_multimap
<K
, T
, H
, P
, A
> &m1
,
914 unordered_multimap
<K
, T
, H
, P
, A
> &m2
)
921 #if defined(BOOST_MSVC)
925 #endif // BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED