summaryrefslogtreecommitdiff
path: root/AK/HashMap.h
diff options
context:
space:
mode:
authorHendiadyoin1 <leon2002.la@gmail.com>2021-11-07 14:52:20 +0100
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-12-15 13:09:49 +0330
commitd50360f5dd97505e057c1d0dc92717a745576feb (patch)
tree3e72bff54ec2807ad6b8282cafd156e1a05f6b98 /AK/HashMap.h
parentc8bee92fb9ae1479077071cd5ffed58be77d0b26 (diff)
downloadserenity-d50360f5dd97505e057c1d0dc92717a745576feb.zip
AK: Allow hash-compatible key types in Hash[Table|Map] lookup
This will allow us to avoid some potentially expensive type conversion during lookup, like form String to StringView, which would allocate memory otherwise.
Diffstat (limited to 'AK/HashMap.h')
-rw-r--r--AK/HashMap.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/AK/HashMap.h b/AK/HashMap.h
index 5303bdf32d..78a307e3ee 100644
--- a/AK/HashMap.h
+++ b/AK/HashMap.h
@@ -91,6 +91,19 @@ public:
return m_table.find(hash, predicate);
}
+ // FIXME: Use some sort of Traits to get the comparison operation
+ template<Concepts::HashCompatible<K> Key>
+ requires(IsSame<KeyTraits, Traits<K>>) [[nodiscard]] IteratorType find(Key const& value)
+ {
+ return m_table.find(Traits<Key>::hash(value), [&](auto& entry) { return value == entry.key; });
+ }
+
+ template<Concepts::HashCompatible<K> Key>
+ requires(IsSame<KeyTraits, Traits<K>>) [[nodiscard]] ConstIteratorType find(Key const& value) const
+ {
+ return m_table.find(Traits<Key>::hash(value), [&](auto& entry) { return value == entry.key; });
+ }
+
void ensure_capacity(size_t capacity) { m_table.ensure_capacity(capacity); }
ErrorOr<void> try_ensure_capacity(size_t capacity) { return m_table.try_ensure_capacity(capacity); }
@@ -118,11 +131,44 @@ public:
return (*it).value;
}
+ template<Concepts::HashCompatible<K> Key>
+ requires(IsSame<KeyTraits, Traits<K>>) Optional<typename Traits<V>::PeekType> get(const Key& key) const requires(!IsPointer<typename Traits<V>::PeekType>)
+ {
+ auto it = find(key);
+ if (it == end())
+ return {};
+ return (*it).value;
+ }
+
+ template<Concepts::HashCompatible<K> Key>
+ requires(IsSame<KeyTraits, Traits<K>>) Optional<typename Traits<V>::ConstPeekType> get(const Key& key) const requires(IsPointer<typename Traits<V>::PeekType>)
+ {
+ auto it = find(key);
+ if (it == end())
+ return {};
+ return (*it).value;
+ }
+
+ template<Concepts::HashCompatible<K> Key>
+ requires(IsSame<KeyTraits, Traits<K>>) Optional<typename Traits<V>::PeekType> get(const Key& key) requires(!IsConst<typename Traits<V>::PeekType>)
+ {
+ auto it = find(key);
+ if (it == end())
+ return {};
+ return (*it).value;
+ }
+
[[nodiscard]] bool contains(const K& key) const
{
return find(key) != end();
}
+ template<Concepts::HashCompatible<K> Key>
+ requires(IsSame<KeyTraits, Traits<K>>) [[nodiscard]] bool contains(Key const& value)
+ {
+ return find(value) != end();
+ }
+
void remove(IteratorType it)
{
m_table.remove(it);