MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
unordered_map.hpp
1#ifndef MSTL_CORE_CONTAINER_UNORDERED_MAP_HPP__
2#define MSTL_CORE_CONTAINER_UNORDERED_MAP_HPP__
3#include "hashtable.hpp"
5
6template <typename Key, typename T, typename HashFcn = hash<Key>, typename EqualKey = equal_to<Key>,
7 typename Alloc = allocator<hashtable_node<pair<const Key, T>>>>
8class unordered_map : public icollector<unordered_map<Key, T, HashFcn, EqualKey, Alloc>> {
9#ifdef MSTL_STANDARD_20__
10 static_assert(is_hash_v<HashFcn, Key>, "unordered map requires valid hash function.");
11 static_assert(is_allocator_v<Alloc>, "Alloc type is not a standard allocator type.");
12#endif
13 static_assert(is_same_v<hashtable_node<pair<const Key, T>>, typename Alloc::value_type>,
14 "allocator type mismatch.");
15 static_assert(is_object_v<Key>, "unordered map only contains object types.");
16
17 using base_type = hashtable<pair<const Key, T>, Key, HashFcn, select1st<pair<const Key, T>>, EqualKey, Alloc>;
18
19public:
20 using key_type = typename base_type::key_type;
21 using value_type = typename base_type::value_type;
22 using hasher = typename base_type::hasher;
23 using key_equal = typename base_type::key_equal;
24
25 using size_type = typename base_type::size_type;
26 using difference_type = typename base_type::difference_type;
27 using pointer = typename base_type::pointer;
28 using const_pointer = typename base_type::const_pointer;
29 using reference = typename base_type::reference;
30 using const_reference = typename base_type::const_reference;
31
32 using iterator = typename base_type::iterator;
33 using const_iterator = typename base_type::const_iterator;
34
35 using allocator_type = typename base_type::allocator_type;
36
37private:
38 base_type ht_{100};
39
40public:
41 unordered_map() = default;
42 explicit unordered_map(size_type n) : ht_(n) {}
43
44 unordered_map(size_type n, const hasher& hf) : ht_(n, hf, key_equal()) {}
45 unordered_map(size_type n, const hasher& hf, const key_equal& eql) : ht_(n, hf, eql) {}
46
47 unordered_map(const unordered_map& ht) : ht_(ht.ht_) {}
48 unordered_map& operator =(const unordered_map& x) = default;
49
50 unordered_map(unordered_map&& x) noexcept(noexcept(ht_.swap(x.ht_)))
51 : ht_(_MSTL forward<base_type>(x.ht_)) {}
52
53 unordered_map& operator =(unordered_map&& x) noexcept(noexcept(ht_.swap(x.ht_))) {
54 ht_ = _MSTL move(x.ht_);
55 return *this;
56 }
57
58 template <typename Iterator>
59 unordered_map(Iterator first, Iterator last) : ht_(100, hasher(), key_equal()) {
60 ht_.insert_unique(first, last);
61 }
62 template <typename Iterator>
63 unordered_map(Iterator first, Iterator list, size_type n) : ht_(n, hasher(), key_equal()) {
64 ht_.insert_unique(first, list);
65 }
66 template <typename Iterator>
67 unordered_map(Iterator first, Iterator last, size_type n, const hasher& hf) : ht_(n, hf, key_equal()) {
68 ht_.insert_unique(first, last);
69 }
70 template <typename Iterator>
71 unordered_map(Iterator first, Iterator last, size_type n, const hasher& hf, const key_equal& eql)
72 : ht_(n, hf, eql) {
73 ht_.insert_unique(first, last);
74 }
75
76 unordered_map(std::initializer_list<value_type> l)
77 : unordered_map(l.begin(), l.end()) {}
78 unordered_map(std::initializer_list<value_type> l, size_type n)
79 : unordered_map(l.begin(), l.end(), n) {}
80 unordered_map(std::initializer_list<value_type> l, size_type n, const hasher& hf)
81 : unordered_map(l.begin(), l.end(), n, hf) {}
82 unordered_map(std::initializer_list<value_type> l, size_type n, const hasher& hf, const key_equal& eql)
83 : unordered_map(l.begin(), l.end(), n, hf, eql) {}
84
85 MSTL_NODISCARD iterator begin() noexcept { return ht_.begin(); }
86 MSTL_NODISCARD iterator end() noexcept { return ht_.end(); }
87 MSTL_NODISCARD const_iterator begin() const noexcept { return ht_.begin(); }
88 MSTL_NODISCARD const_iterator end() const noexcept { return ht_.end(); }
89 MSTL_NODISCARD const_iterator cbegin() const noexcept { return ht_.cbegin(); }
90 MSTL_NODISCARD const_iterator cend() const noexcept { return ht_.cend(); }
91
92 MSTL_NODISCARD size_type size() const noexcept { return ht_.size(); }
93 MSTL_NODISCARD size_type max_size() const noexcept { return ht_.max_size(); }
94 MSTL_NODISCARD bool empty() const noexcept { return ht_.empty(); }
95
96 MSTL_NODISCARD size_type count(const key_type& key) const noexcept(noexcept(ht_.count(key))) {
97 return ht_.count(key);
98 }
99 MSTL_NODISCARD size_type bucket_count() const noexcept { return ht_.bucket_count(); }
100 MSTL_NODISCARD size_type max_bucket_count() const noexcept { return ht_.max_bucket_count(); }
101 MSTL_NODISCARD size_type bucket_size(size_type n) const noexcept { return ht_.bucket_size(n); }
102
103 MSTL_NODISCARD allocator_type get_allocator() const noexcept { return allocator_type(); }
104
105 MSTL_NODISCARD hasher hash_funct() const noexcept(noexcept(ht_.hash_func())) { return ht_.hash_func(); }
106 MSTL_NODISCARD key_equal key_eq() const noexcept(noexcept(ht_.key_eql())) { return ht_.key_eql(); }
107
108 MSTL_NODISCARD float load_factor() const noexcept { return ht_.load_factor(); }
109 MSTL_NODISCARD float max_load_factor() const noexcept { return ht_.max_load_factor(); }
110 void max_load_factor(float new_max) noexcept { ht_.max_load_factor(new_max); }
111
112 void rehash(size_type new_size) { ht_.rehash(new_size); }
113 void reserve(size_type max_count) { ht_.reserve(max_count); }
114
115 template <typename... Args>
116 pair<iterator, bool> emplace(Args&&... args) {
117 return ht_.emplace_unique(_MSTL forward<Args>(args)...);
118 }
119
120 pair<iterator, bool> insert(const value_type& obj) {
121 return ht_.insert_unique(obj);
122 }
123 pair<iterator, bool> insert(value_type&& obj) {
124 return ht_.insert_unique(_MSTL forward<value_type>(obj));
125 }
126 template <typename Iterator>
127 void insert(Iterator first, Iterator last) { ht_.insert_unique(first, last); }
128
129 size_type erase(const key_type& key) noexcept { return ht_.erase(key); }
130 iterator erase(iterator it) noexcept { return ht_.erase(it); }
131 iterator erase(iterator first, iterator last) noexcept { return ht_.erase(first, last); }
132 const_iterator erase(const_iterator it) noexcept { return ht_.erase(it); }
133 const_iterator erase(const_iterator first, const_iterator last) noexcept { return ht_.erase(first, last); }
134 void clear() noexcept { ht_.clear(); }
135
136 MSTL_NODISCARD iterator find(const key_type& key) { return ht_.find(key); }
137 MSTL_NODISCARD const_iterator find(const key_type& key) const { return ht_.find(key); }
138
139 MSTL_NODISCARD pair<iterator, iterator> equal_range(const key_type& key) { return ht_.equal_range(key); }
140 MSTL_NODISCARD pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
141 return ht_.equal_range(key);
142 }
143
144 MSTL_NODISCARD T& operator [](const key_type& key) {
145 auto iter = ht_.find(key);
146 if (iter == ht_.end())
147 iter = ht_.emplace_unique(key, T()).first;
148 return iter->second;
149 }
150 MSTL_NODISCARD const T& at(const key_type& key) const {
151 auto iter = ht_.find(key);
152 if (iter == cend()) throw_exception(iterator_exception());
153 return iter->second;
154 }
155 MSTL_NODISCARD T& at(const key_type& key) {
156 return const_cast<reference>(static_cast<const unordered_map*>(this)->at(key));
157 }
158
159 void swap(unordered_map& x) noexcept(noexcept(ht_.swap(x.ht_))) { ht_.swap(x.ht_); }
160
161 MSTL_NODISCARD bool operator ==(const unordered_map& rhs) const
162 noexcept(noexcept(ht_ == rhs.ht_)) {
163 return ht_ == rhs.ht_;
164 }
165 MSTL_NODISCARD bool operator <(const unordered_map& rhs) const
166 noexcept(noexcept(ht_ < rhs.ht_)) {
167 return ht_ < rhs.ht_;
168 }
169};
170#ifdef MSTL_SUPPORT_DEDUCTION_GUIDES__
171template <typename Iterator, typename HashFcn = hash<iter_map_key_t<Iterator>>,
172 typename Compare = equal_to<iter_map_key_t<Iterator>>, typename Alloc>
173unordered_map(Iterator, Iterator, HashFcn = HashFcn(), Compare = Compare(), Alloc = Alloc())
174-> unordered_map<iter_map_key_t<Iterator>, iter_map_value_t<Iterator>, HashFcn, Compare, Alloc>;
175
176template <typename Key, typename T, typename HashFcn = hash<Key>, typename Compare = equal_to<Key>,
177 typename Alloc = allocator<pair<const Key, T>>>
178unordered_map(std::initializer_list<pair<Key, T>>, HashFcn = HashFcn(), Compare = Compare(), Alloc = Alloc())
179-> unordered_map<Key, T, HashFcn, Compare, Alloc>;
180
181template <typename Iterator, typename Alloc>
182unordered_map(Iterator, Iterator, Alloc) -> unordered_map<iter_map_key_t<Iterator>, iter_map_value_t<Iterator>,
184
185template <typename Iterator, typename HashFcn, typename Alloc>
186unordered_map(Iterator, Iterator, HashFcn, Alloc) -> unordered_map<iter_map_key_t<Iterator>,
188
189template <typename Key, typename T, typename Alloc>
190unordered_map(std::initializer_list<pair<Key, T>>, Alloc)
191-> unordered_map<Key, T, hash<Key>, equal_to<Key>, Alloc>;
192
193template <typename Key, typename T, typename HashFcn, typename Alloc>
194unordered_map(std::initializer_list<pair<Key, T>>, HashFcn, Alloc)
195-> unordered_map<Key, T, HashFcn, equal_to<Key>, Alloc>;
196#endif
197
199#endif // MSTL_CORE_CONTAINER_UNORDERED_MAP_HPP__
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
typename iter_value_t< Iterator >::second_type iter_map_value_t
从映射迭代器中提取值类型
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
void swap()=delete
删除无参数的swap重载
相等比较仿函数
哈希函数的主模板
集合器接口模板
存储两个值的元组对