mirror of
https://github.com/luau-lang/luau.git
synced 2025-04-10 22:00:54 +01:00
Add ADL-based hash resolution.
This commit is contained in:
parent
c189ed6d18
commit
2fdc5c8f98
1 changed files with 53 additions and 16 deletions
|
@ -11,6 +11,26 @@
|
||||||
namespace Luau::EqSat
|
namespace Luau::EqSat
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template<typename T, typename = void>
|
||||||
|
struct LanguageHash
|
||||||
|
{
|
||||||
|
size_t operator()(const T&) const
|
||||||
|
{
|
||||||
|
// See available specializations at the bottom of this file.
|
||||||
|
static_assert(false, "missing languageHash specialization");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::size_t languageHash(const T& lang) {
|
||||||
|
return LanguageHash<T>{}(lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t hashCombine(size_t& seed, size_t hash)
|
||||||
|
{
|
||||||
|
return seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||||
|
}
|
||||||
|
|
||||||
#define LUAU_EQSAT_ATOM(name, t) \
|
#define LUAU_EQSAT_ATOM(name, t) \
|
||||||
struct name : public ::Luau::EqSat::Atom<name, t> \
|
struct name : public ::Luau::EqSat::Atom<name, t> \
|
||||||
{ \
|
{ \
|
||||||
|
@ -46,20 +66,22 @@ namespace Luau::EqSat
|
||||||
return !(*this == rhs); \
|
return !(*this == rhs); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DERIVE_HASH(name, field) \
|
||||||
|
struct Hash \
|
||||||
|
{ \
|
||||||
|
size_t operator()(const name& value) const \
|
||||||
|
{ \
|
||||||
|
return languageHash(value.field); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Phantom, typename T>
|
template<typename Phantom, typename T>
|
||||||
struct Atom
|
struct Atom
|
||||||
{
|
{
|
||||||
T value;
|
T value;
|
||||||
|
|
||||||
DERIVE_EQ(Atom, value);
|
DERIVE_EQ(Atom, value);
|
||||||
|
DERIVE_HASH(Atom, value);
|
||||||
struct Hash
|
|
||||||
{
|
|
||||||
size_t operator()(const Atom& atom) const
|
|
||||||
{
|
|
||||||
return std::hash<T>{}(atom.value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Empty base class just for static_asserts.
|
/// Empty base class just for static_asserts.
|
||||||
|
@ -111,17 +133,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
DERIVE_EQ(Node, array);
|
DERIVE_EQ(Node, array);
|
||||||
|
DERIVE_HASH(Node, array);
|
||||||
struct Hash
|
|
||||||
{
|
|
||||||
size_t operator()(const Node& node) const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef DERIVE_EQ
|
#undef DERIVE_EQ
|
||||||
|
#undef DERIVE_HASH
|
||||||
|
|
||||||
// `Language` is very similar to `Luau::Variant` with enough differences warranting a different type altogether.
|
// `Language` is very similar to `Luau::Variant` with enough differences warranting a different type altogether.
|
||||||
//
|
//
|
||||||
|
@ -270,4 +286,25 @@ public:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct LanguageHash<T, std::void_t<decltype(std::hash<T>{}(std::declval<T>()))>>
|
||||||
|
{
|
||||||
|
size_t operator()(const T& t) const
|
||||||
|
{
|
||||||
|
return std::hash<T>{}(t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, size_t I>
|
||||||
|
struct LanguageHash<std::array<T, I>>
|
||||||
|
{
|
||||||
|
size_t operator()(const std::array<T, I>& array) const
|
||||||
|
{
|
||||||
|
size_t seed = 0;
|
||||||
|
for (Id id : array)
|
||||||
|
hashCombine(seed, languageHash(id));
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Luau::EqSat
|
} // namespace Luau::EqSat
|
||||||
|
|
Loading…
Add table
Reference in a new issue