Language is also Hash.

This commit is contained in:
Alexander McCord 2024-05-26 15:46:39 -07:00
parent 38ccd662f2
commit b574667c80
2 changed files with 38 additions and 3 deletions

View file

@ -29,6 +29,14 @@ struct Atom
{ {
return !(*this == rhs); return !(*this == rhs);
} }
struct Hash
{
size_t operator()(const Atom& atom) const
{
return std::hash<T>{}(atom.value);
}
};
}; };
// `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.
@ -55,6 +63,7 @@ class Language
using FnMove = void (*)(void*, void*); using FnMove = void (*)(void*, void*);
using FnDtor = void (*)(void*); using FnDtor = void (*)(void*);
using FnPred = bool (*)(const void*, const void*); using FnPred = bool (*)(const void*, const void*);
using FnHash = size_t (*)(const void*);
template<typename T> template<typename T>
static void fnCopy(void* dst, const void* src) static void fnCopy(void* dst, const void* src)
@ -81,10 +90,17 @@ class Language
return *static_cast<const T*>(lhs) == *static_cast<const T*>(rhs); return *static_cast<const T*>(lhs) == *static_cast<const T*>(rhs);
} }
template<typename T>
static size_t fnHash(const void* buffer)
{
return typename T::Hash{}(*static_cast<const T*>(buffer));
}
static constexpr FnCopy tableCopy[sizeof...(Ts)] = {&fnCopy<Ts>...}; static constexpr FnCopy tableCopy[sizeof...(Ts)] = {&fnCopy<Ts>...};
static constexpr FnMove tableMove[sizeof...(Ts)] = {&fnMove<Ts>...}; static constexpr FnMove tableMove[sizeof...(Ts)] = {&fnMove<Ts>...};
static constexpr FnDtor tableDtor[sizeof...(Ts)] = {&fnDtor<Ts>...}; static constexpr FnDtor tableDtor[sizeof...(Ts)] = {&fnDtor<Ts>...};
static constexpr FnPred tablePred[sizeof...(Ts)] = {&fnPred<Ts>...}; static constexpr FnPred tablePred[sizeof...(Ts)] = {&fnPred<Ts>...};
static constexpr FnHash tableHash[sizeof...(Ts)] = {&fnHash<Ts>...};
static constexpr int getIndexFromTag(const char* tag) static constexpr int getIndexFromTag(const char* tag)
{ {
@ -161,10 +177,11 @@ public:
public: public:
struct Hash struct Hash
{ {
size_t operator()(const Language<Ts...>& lang) size_t operator()(const Language& language) const
{ {
// TODO. Currently here so I can build and test this project. size_t hash = std::hash<const char*>{}(language.tag);
return 0; hash ^= tableHash[getIndexFromTag(language.tag)](&language.buffer);
return hash;
} }
}; };
}; };

View file

@ -4,6 +4,7 @@
#include "Luau/Language.h" #include "Luau/Language.h"
#include <string> #include <string>
#include <unordered_map>
LUAU_EQSAT_ATOM(I32, int); LUAU_EQSAT_ATOM(I32, int);
LUAU_EQSAT_ATOM(Bool, bool); LUAU_EQSAT_ATOM(Bool, bool);
@ -76,4 +77,21 @@ TEST_CASE("language_equality")
CHECK(v3 != v4); CHECK(v3 != v4);
} }
TEST_CASE("language_is_mappable")
{
std::unordered_map<Value, int, Value::Hash> map;
Value v1{I32{5}};
Value v2{I32{5}};
Value v3{Bool{true}};
map[v1] = 1;
map[v2] = 2;
map[v3] = 42;
CHECK(map[v1] == 2);
CHECK(map[v2] == 2);
CHECK(map[v3] == 42);
}
TEST_SUITE_END(); TEST_SUITE_END();