AK: Make StringView::hash() constexpr

This required moving string_hash() to its own header so that everyone
can see it.
This commit is contained in:
Andreas Kling 2021-05-14 15:21:50 +02:00
parent 9c38475608
commit 3e603b2f32
Notes: sideshowbarker 2024-07-18 18:09:53 +09:00
5 changed files with 36 additions and 25 deletions

27
AK/StringHash.h Normal file
View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2018-2021, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
namespace AK {
constexpr u32 string_hash(char const* characters, size_t length)
{
u32 hash = 0;
for (size_t i = 0; i < length; ++i) {
hash += (u32)characters[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
return hash;
}
}
using AK::string_hash;

View file

@ -6,9 +6,9 @@
#include <AK/Debug.h> #include <AK/Debug.h>
#include <AK/FlyString.h> #include <AK/FlyString.h>
#include <AK/HashTable.h>
#include <AK/Memory.h> #include <AK/Memory.h>
#include <AK/StdLibExtras.h> #include <AK/StdLibExtras.h>
#include <AK/StringHash.h>
#include <AK/StringImpl.h> #include <AK/StringImpl.h>
#include <AK/kmalloc.h> #include <AK/kmalloc.h>

View file

@ -96,20 +96,6 @@ private:
char m_inline_buffer[0]; char m_inline_buffer[0];
}; };
constexpr u32 string_hash(const char* characters, size_t length)
{
u32 hash = 0;
for (size_t i = 0; i < length; ++i) {
hash += (u32)characters[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
return hash;
}
template<> template<>
struct Formatter<StringImpl> : Formatter<StringView> { struct Formatter<StringImpl> : Formatter<StringView> {
void format(FormatBuilder& builder, const StringImpl& value) void format(FormatBuilder& builder, const StringImpl& value)
@ -122,5 +108,4 @@ struct Formatter<StringImpl> : Formatter<StringView> {
using AK::Chomp; using AK::Chomp;
using AK::NoChomp; using AK::NoChomp;
using AK::string_hash;
using AK::StringImpl; using AK::StringImpl;

View file

@ -214,13 +214,6 @@ template Optional<u64> StringView::to_uint() const;
template Optional<long> StringView::to_uint() const; template Optional<long> StringView::to_uint() const;
template Optional<long long> StringView::to_uint() const; template Optional<long long> StringView::to_uint() const;
unsigned StringView::hash() const
{
if (is_empty())
return 0;
return string_hash(characters_without_null_termination(), length());
}
bool StringView::operator==(const String& string) const bool StringView::operator==(const String& string) const
{ {
if (string.is_null()) if (string.is_null())

View file

@ -11,6 +11,7 @@
#include <AK/Forward.h> #include <AK/Forward.h>
#include <AK/Span.h> #include <AK/Span.h>
#include <AK/StdLibExtras.h> #include <AK/StdLibExtras.h>
#include <AK/StringHash.h>
#include <AK/StringUtils.h> #include <AK/StringUtils.h>
#include <AK/Vector.h> #include <AK/Vector.h>
@ -49,7 +50,7 @@ public:
[[nodiscard]] constexpr bool is_null() const { return !m_characters; } [[nodiscard]] constexpr bool is_null() const { return !m_characters; }
[[nodiscard]] constexpr bool is_empty() const { return m_length == 0; } [[nodiscard]] constexpr bool is_empty() const { return m_length == 0; }
[[nodiscard]] const char* characters_without_null_termination() const { return m_characters; } [[nodiscard]] constexpr char const* characters_without_null_termination() const { return m_characters; }
[[nodiscard]] constexpr size_t length() const { return m_length; } [[nodiscard]] constexpr size_t length() const { return m_length; }
[[nodiscard]] ReadonlyBytes bytes() const { return { m_characters, m_length }; } [[nodiscard]] ReadonlyBytes bytes() const { return { m_characters, m_length }; }
@ -61,7 +62,12 @@ public:
[[nodiscard]] constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } [[nodiscard]] constexpr ConstIterator begin() const { return ConstIterator::begin(*this); }
[[nodiscard]] constexpr ConstIterator end() const { return ConstIterator::end(*this); } [[nodiscard]] constexpr ConstIterator end() const { return ConstIterator::end(*this); }
[[nodiscard]] unsigned hash() const; [[nodiscard]] constexpr unsigned hash() const
{
if (is_empty())
return 0;
return string_hash(characters_without_null_termination(), length());
}
[[nodiscard]] bool starts_with(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const; [[nodiscard]] bool starts_with(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
[[nodiscard]] bool ends_with(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const; [[nodiscard]] bool ends_with(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const;