libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
hashmap.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <unordered_map>
14#include <initializer_list>
15#include <promeki/namespace.h>
16#include <promeki/sharedptr.h>
17#include <promeki/list.h>
18
19PROMEKI_NAMESPACE_BEGIN
20
44template <typename K, typename V> class HashMap {
45 PROMEKI_SHARED_FINAL(HashMap)
46 public:
48 using Ptr = SharedPtr<HashMap>;
49
51 using Data = std::unordered_map<K, V>;
52
54 using Key = K;
55
57 using Value = V;
58
60 using Iterator = typename Data::iterator;
61
63 using ConstIterator = typename Data::const_iterator;
64
66 HashMap() = default;
67
69 HashMap(const HashMap &other) : d(other.d) {}
70
72 HashMap(HashMap &&other) noexcept : d(std::move(other.d)) {}
73
78 HashMap(std::initializer_list<std::pair<const K, V>> initList) : d(initList) {}
79
81 ~HashMap() = default;
82
84 HashMap &operator=(const HashMap &other) {
85 d = other.d;
86 return *this;
87 }
88
90 HashMap &operator=(HashMap &&other) noexcept {
91 d = std::move(other.d);
92 return *this;
93 }
94
95 // -- Iterators --
96
98 Iterator begin() noexcept { return d.begin(); }
99
101 ConstIterator begin() const noexcept { return d.cbegin(); }
102
104 ConstIterator cbegin() const noexcept { return d.cbegin(); }
105
107 ConstIterator constBegin() const noexcept { return d.cbegin(); }
108
110 Iterator end() noexcept { return d.end(); }
111
113 ConstIterator end() const noexcept { return d.cend(); }
114
116 ConstIterator cend() const noexcept { return d.cend(); }
117
119 ConstIterator constEnd() const noexcept { return d.cend(); }
120
121 // -- Capacity --
122
124 bool isEmpty() const noexcept { return d.empty(); }
125
127 size_t size() const noexcept { return d.size(); }
128
138 void reserve(size_t count) { d.reserve(count); }
139
140 // -- Lookup --
141
148 V &operator[](const K &key) { return d[key]; }
149
159 const V &operator[](const K &key) const { return d.at(key); }
160
168 V value(const K &key, const V &defaultValue = V{}) const {
169 auto it = d.find(key);
170 if (it != d.end()) return it->second;
171 return defaultValue;
172 }
173
175 bool contains(const K &key) const { return d.find(key) != d.end(); }
176
182 Iterator find(const K &key) { return d.find(key); }
183
185 ConstIterator find(const K &key) const { return d.find(key); }
186
187 // -- Modifiers --
188
194 void insert(const K &key, const V &val) {
195 d.insert_or_assign(key, val);
196 return;
197 }
198
204 void insert(const K &key, V &&val) {
205 d.insert_or_assign(key, std::move(val));
206 return;
207 }
208
220 bool insertNew(const K &key, const V &val) { return d.emplace(key, val).second; }
221
236 template <typename... ArgsT> std::pair<Iterator, bool> tryEmplace(const K &key, ArgsT &&...args) {
237 return d.try_emplace(key, std::forward<ArgsT>(args)...);
238 }
239
245 bool remove(const K &key) { return d.erase(key) > 0; }
246
252 Iterator remove(Iterator pos) { return d.erase(pos); }
253
255 void clear() noexcept {
256 d.clear();
257 return;
258 }
259
264 void swap(HashMap &other) noexcept {
265 d.swap(other.d);
266 return;
267 }
268
269 // -- Convenience --
270
272 List<K> keys() const {
273 List<K> ret;
274 ret.reserve(d.size());
275 for (const auto &[k, v] : d) ret.pushToBack(k);
276 return ret;
277 }
278
280 List<V> values() const {
281 List<V> ret;
282 ret.reserve(d.size());
283 for (const auto &[k, v] : d) ret.pushToBack(v);
284 return ret;
285 }
286
292 template <typename Func> void forEach(Func &&func) const {
293 for (const auto &[k, v] : d) func(k, v);
294 return;
295 }
296
297 // -- Comparison --
298
300 friend bool operator==(const HashMap &lhs, const HashMap &rhs) { return lhs.d == rhs.d; }
301
303 friend bool operator!=(const HashMap &lhs, const HashMap &rhs) { return lhs.d != rhs.d; }
304
305 private:
306 Data d;
307};
308
309PROMEKI_NAMESPACE_END
310
311#endif // PROMEKI_ENABLE_CORE