11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <unordered_map>
14#include <initializer_list>
19PROMEKI_NAMESPACE_BEGIN
44template <
typename K,
typename V>
class HashMap {
45 PROMEKI_SHARED_FINAL(HashMap)
48 using Ptr = SharedPtr<HashMap>;
51 using Data = std::unordered_map<K, V>;
60 using Iterator =
typename Data::iterator;
63 using ConstIterator =
typename Data::const_iterator;
69 HashMap(
const HashMap &other) : d(other.d) {}
72 HashMap(HashMap &&other) noexcept : d(std::move(other.d)) {}
78 HashMap(std::initializer_list<std::pair<const K, V>> initList) : d(initList) {}
84 HashMap &operator=(
const HashMap &other) {
90 HashMap &operator=(HashMap &&other)
noexcept {
91 d = std::move(other.d);
98 Iterator begin() noexcept {
return d.begin(); }
101 ConstIterator begin() const noexcept {
return d.cbegin(); }
104 ConstIterator cbegin() const noexcept {
return d.cbegin(); }
107 ConstIterator constBegin() const noexcept {
return d.cbegin(); }
110 Iterator end() noexcept {
return d.end(); }
113 ConstIterator end() const noexcept {
return d.cend(); }
116 ConstIterator cend() const noexcept {
return d.cend(); }
119 ConstIterator constEnd() const noexcept {
return d.cend(); }
124 bool isEmpty() const noexcept {
return d.empty(); }
127 size_t size() const noexcept {
return d.size(); }
138 void reserve(
size_t count) { d.reserve(count); }
148 V &operator[](
const K &key) {
return d[key]; }
159 const V &operator[](
const K &key)
const {
return d.at(key); }
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;
175 bool contains(
const K &key)
const {
return d.find(key) != d.end(); }
182 Iterator find(
const K &key) {
return d.find(key); }
185 ConstIterator find(
const K &key)
const {
return d.find(key); }
194 void insert(
const K &key,
const V &val) {
195 d.insert_or_assign(key, val);
204 void insert(
const K &key, V &&val) {
205 d.insert_or_assign(key, std::move(val));
220 bool insertNew(
const K &key,
const V &val) {
return d.emplace(key, val).second; }
236 template <
typename... ArgsT> std::pair<Iterator, bool> tryEmplace(
const K &key, ArgsT &&...args) {
237 return d.try_emplace(key, std::forward<ArgsT>(args)...);
245 bool remove(
const K &key) {
return d.erase(key) > 0; }
252 Iterator remove(Iterator pos) {
return d.erase(pos); }
255 void clear() noexcept {
264 void swap(HashMap &other)
noexcept {
272 List<K> keys()
const {
274 ret.reserve(d.size());
275 for (
const auto &[k, v] : d) ret.pushToBack(k);
280 List<V> values()
const {
282 ret.reserve(d.size());
283 for (
const auto &[k, v] : d) ret.pushToBack(v);
292 template <
typename Func>
void forEach(Func &&func)
const {
293 for (
const auto &[k, v] : d) func(k, v);
300 friend bool operator==(
const HashMap &lhs,
const HashMap &rhs) {
return lhs.d == rhs.d; }
303 friend bool operator!=(
const HashMap &lhs,
const HashMap &rhs) {
return lhs.d != rhs.d; }