#pragma once
#include <wtf/HashTraits.h>
#include <wtf/text/AtomicString.h>
#include <wtf/text/StringHasher.h>
namespace WTF {
inline bool HashTraits<String>::isEmptyValue(const String& value)
{
return value.isNull();
}
inline void HashTraits<String>::customDeleteBucket(String& value)
{
ASSERT(!isDeletedValue(value));
String valueToBeDestroyed = WTFMove(value);
constructDeletedValue(value);
}
struct StringHash {
static unsigned hash(StringImpl* key) { return key->hash(); }
static inline bool equal(const StringImpl* a, const StringImpl* b)
{
return WTF::equal(*a, *b);
}
static unsigned hash(const RefPtr<StringImpl>& key) { return key->hash(); }
static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b)
{
return equal(a.get(), b.get());
}
static bool equal(const RefPtr<StringImpl>& a, const StringImpl* b)
{
return equal(a.get(), b);
}
static bool equal(const StringImpl* a, const RefPtr<StringImpl>& b)
{
return equal(a, b.get());
}
static unsigned hash(const String& key) { return key.impl()->hash(); }
static bool equal(const String& a, const String& b)
{
return equal(a.impl(), b.impl());
}
static const bool safeToCompareToEmptyOrDeleted = false;
};
struct ASCIICaseInsensitiveHash {
template<typename T>
struct FoldCase {
static inline UChar convert(T character)
{
return toASCIILower(character);
}
};
static unsigned hash(const UChar* data, unsigned length)
{
return StringHasher::computeHashAndMaskTop8Bits<UChar, FoldCase<UChar>>(data, length);
}
static unsigned hash(StringImpl& string)
{
if (string.is8Bit())
return hash(string.characters8(), string.length());
return hash(string.characters16(), string.length());
}
static unsigned hash(StringImpl* string)
{
ASSERT(string);
return hash(*string);
}
static unsigned hash(const LChar* data, unsigned length)
{
return StringHasher::computeHashAndMaskTop8Bits<LChar, FoldCase<LChar>>(data, length);
}
static inline unsigned hash(const char* data, unsigned length)
{
return hash(reinterpret_cast<const LChar*>(data), length);
}
static inline bool equal(const StringImpl& a, const StringImpl& b)
{
return equalIgnoringASCIICase(a, b);
}
static inline bool equal(const StringImpl* a, const StringImpl* b)
{
ASSERT(a);
ASSERT(b);
return equal(*a, *b);
}
static unsigned hash(const RefPtr<StringImpl>& key)
{
return hash(key.get());
}
static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b)
{
return equal(a.get(), b.get());
}
static unsigned hash(const String& key)
{
return hash(key.impl());
}
static unsigned hash(const AtomicString& key)
{
return hash(key.impl());
}
static bool equal(const String& a, const String& b)
{
return equal(a.impl(), b.impl());
}
static bool equal(const AtomicString& a, const AtomicString& b)
{
return a == b || equal(a.impl(), b.impl());
}
static const bool safeToCompareToEmptyOrDeleted = false;
};
struct AlreadyHashed : IntHash<unsigned> {
static unsigned hash(unsigned key) { return key; }
static unsigned avoidDeletedValue(unsigned hash)
{
ASSERT(hash);
unsigned newHash = hash | (!(hash + 1) << 31);
ASSERT(newHash);
ASSERT(newHash != 0xFFFFFFFF);
return newHash;
}
};
struct ASCIICaseInsensitiveStringViewHashTranslator {
static unsigned hash(StringView key)
{
if (key.is8Bit())
return ASCIICaseInsensitiveHash::hash(key.characters8(), key.length());
return ASCIICaseInsensitiveHash::hash(key.characters16(), key.length());
}
static bool equal(const String& a, StringView b)
{
return equalIgnoringASCIICaseCommon(a, b);
}
};
}
using WTF::ASCIICaseInsensitiveHash;
using WTF::ASCIICaseInsensitiveStringViewHashTranslator;
using WTF::AlreadyHashed;
using WTF::StringHash;