mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-19 07:33:20 +00:00

When T in HashTable<T> has a potentially slow equality check, it can be very profitable to check for a matching hash before full equality. This patch adds may_have_slow_equality_check() to AK::Traits and defaults it to true. For trivial types (pointers, integers, etc) we default it to false. This means we skip the hash check when the equality check would be a single-CPU-word compare anyway. This synergizes really well with things like HashMap<String, V> where collisions previously meant we may have to churn through multiple O(n) equality checks.
70 lines
1.8 KiB
C++
70 lines
1.8 KiB
C++
/*
|
|
* Copyright (c) 2024, the Ladybird developers.
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/Forward.h>
|
|
#include <AK/Noncopyable.h>
|
|
#include <AK/Traits.h>
|
|
|
|
namespace AK {
|
|
|
|
template<typename T>
|
|
requires(!IsLvalueReference<T> && !IsRvalueReference<T>) class [[nodiscard]] NonnullRawPtr {
|
|
AK_MAKE_DEFAULT_COPYABLE(NonnullRawPtr);
|
|
AK_MAKE_DEFAULT_MOVABLE(NonnullRawPtr);
|
|
|
|
public:
|
|
using ValueType = T;
|
|
|
|
constexpr NonnullRawPtr() = delete;
|
|
constexpr NonnullRawPtr(T const&&) = delete;
|
|
|
|
constexpr NonnullRawPtr(T& other)
|
|
: m_ptr(&other)
|
|
{
|
|
}
|
|
|
|
constexpr operator bool() const = delete;
|
|
constexpr bool operator!() const = delete;
|
|
|
|
constexpr operator T&() { return *m_ptr; }
|
|
constexpr operator T const&() const { return *m_ptr; }
|
|
|
|
[[nodiscard]] ALWAYS_INLINE constexpr T& value() { return *m_ptr; }
|
|
[[nodiscard]] ALWAYS_INLINE constexpr T const& value() const { return *m_ptr; }
|
|
|
|
[[nodiscard]] ALWAYS_INLINE constexpr T& operator*() { return value(); }
|
|
[[nodiscard]] ALWAYS_INLINE constexpr T const& operator*() const { return value(); }
|
|
|
|
ALWAYS_INLINE RETURNS_NONNULL constexpr T* operator->() { return &value(); }
|
|
ALWAYS_INLINE RETURNS_NONNULL constexpr T const* operator->() const { return &value(); }
|
|
|
|
private:
|
|
T* m_ptr;
|
|
};
|
|
|
|
template<typename T>
|
|
struct Traits<NonnullRawPtr<T>> : public DefaultTraits<NonnullRawPtr<T>> {
|
|
static unsigned hash(NonnullRawPtr<T> const& handle) { return Traits<T>::hash(handle); }
|
|
static constexpr bool may_have_slow_equality_check() { return false; }
|
|
};
|
|
|
|
namespace Detail {
|
|
|
|
template<typename T>
|
|
inline constexpr bool IsHashCompatible<NonnullRawPtr<T>, T> = true;
|
|
|
|
template<typename T>
|
|
inline constexpr bool IsHashCompatible<T, NonnullRawPtr<T>> = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#if USING_AK_GLOBALLY
|
|
using AK::NonnullRawPtr;
|
|
#endif
|