diff --git a/BAN/include/BAN/HashMap.h b/BAN/include/BAN/HashMap.h index 048b44b2..f78cc929 100644 --- a/BAN/include/BAN/HashMap.h +++ b/BAN/include/BAN/HashMap.h @@ -60,14 +60,40 @@ namespace BAN friend HashMap; }; + namespace detail + { + template + concept HashMapFindable = requires(const Key& a, const T& b) { COMP()(a, b); HASH()(b); }; + } + template, typename COMP = BAN::equal> class HashMap { public: struct Entry { - Key key; + const Key key; T value; + + Entry() = delete; + Entry& operator=(const Entry&) = delete; + Entry& operator=(Entry&&) = delete; + + Entry(const Entry& other) + : key(other.key) + , value(other.value) + { } + + Entry(Entry&& other) + : key(BAN::move(const_cast(other.key))) + , value(BAN::move(other.value)) + { } + + template + Entry(Key&& key, Args&&... args) + : key(BAN::move(key)) + , value(BAN::forward(args)...) + { } }; struct EntryHash @@ -105,15 +131,15 @@ namespace BAN HashMap() = default; ~HashMap() { clear(); } - HashMap(const HashMap& other) { *this = other; } - HashMap& operator=(const HashMap& other) + HashMap(const HashMap& other) { *this = other; } + HashMap& operator=(const HashMap& other) { m_hash_set = other.m_hash_set; return *this; } - HashMap(HashMap&& other) { *this = BAN::move(other); } - HashMap& operator=(HashMap&& other) + HashMap(HashMap&& other) { *this = BAN::move(other); } + HashMap& operator=(HashMap&& other) { m_hash_set = BAN::move(other.m_hash_set); return *this; @@ -161,7 +187,8 @@ namespace BAN return iterator(it); } - void remove(const Key& key) + template U> + void remove(const U& key) { if (auto it = find(key); it != end()) remove(it); @@ -172,13 +199,13 @@ namespace BAN return iterator(m_hash_set.remove(it.m_iterator)); } - template requires requires(const Key& a, const U& b) { COMP()(a, b); HASH()(b); } + template U> iterator find(const U& key) { return iterator(m_hash_set.find(key)); } - template requires requires(const Key& a, const U& b) { COMP()(a, b); HASH()(b); } + template U> const_iterator find(const U& key) const { return const_iterator(m_hash_set.find(key)); @@ -194,17 +221,20 @@ namespace BAN return m_hash_set.reserve(size); } - T& operator[](const Key& key) + template U> + T& operator[](const U& key) { return find(key)->value; } - const T& operator[](const Key& key) const + template U> + const T& operator[](const U& key) const { return find(key)->value; } - bool contains(const Key& key) const + template U> + bool contains(const U& key) const { return find(key) != end(); }