diff --git a/BAN/include/BAN/HashMap.h b/BAN/include/BAN/HashMap.h index 45457962..048b44b2 100644 --- a/BAN/include/BAN/HashMap.h +++ b/BAN/include/BAN/HashMap.h @@ -13,7 +13,7 @@ namespace BAN Entry& operator*() { - return m_iterator.operator*(); + return const_cast(m_iterator.operator*()); } const Entry& operator*() const { @@ -22,7 +22,7 @@ namespace BAN Entry* operator->() { - return m_iterator.operator->(); + return const_cast(m_iterator.operator->()); } const Entry* operator->() const { @@ -153,7 +153,7 @@ namespace BAN { if (auto it = m_hash_set.find(key); it != m_hash_set.end()) { - it->value = T(BAN::forward(args)...); + const_cast(it->value) = T(BAN::forward(args)...); return iterator(it); } diff --git a/BAN/include/BAN/HashSet.h b/BAN/include/BAN/HashSet.h index 3883eb38..af5392da 100644 --- a/BAN/include/BAN/HashSet.h +++ b/BAN/include/BAN/HashSet.h @@ -15,22 +15,12 @@ namespace BAN public: HashSetIterator() = default; - T& operator*() - { - ASSERT(m_bucket); - return *m_bucket->element(); - } const T& operator*() const { ASSERT(m_bucket); return *m_bucket->element(); } - T* operator->() - { - ASSERT(m_bucket); - return m_bucket->element(); - } const T* operator->() const { ASSERT(m_bucket); @@ -81,6 +71,12 @@ namespace BAN friend HashSet; }; + namespace detail + { + template + concept HashSetFindable = requires(const U& a, const T& b) { COMP()(a, b); HASH()(b); }; + } + template, typename COMP = BAN::equal> class HashSet { @@ -166,7 +162,8 @@ namespace BAN { if (!COMP()(*bucket.element(), value)) continue; - *bucket.element() = BAN::move(value); + bucket.element()->~T(); + new (bucket.element()) T(BAN::move(value)); } else { @@ -185,7 +182,8 @@ namespace BAN } } - void remove(const T& value) + template U> + void remove(const U& value) { if (auto it = find(value); it != end()) remove(it); @@ -202,13 +200,13 @@ namespace BAN return iterator(&bucket); } - template + template U> iterator find(const U& value) { return iterator(const_cast(find_impl(value).m_bucket)); } - template + template U> const_iterator find(const U& value) const { return find_impl(value); @@ -240,7 +238,8 @@ namespace BAN return {}; } - bool contains(const T& value) const + template U> + bool contains(const U& value) const { return find(value) != end(); } @@ -295,7 +294,7 @@ namespace BAN return {}; } - template requires requires(const T& a, const U& b) { COMP()(a, b); HASH()(b); } + template U> const_iterator find_impl(const U& value) const { if (m_capacity == 0)