mirror of
https://github.com/luau-lang/luau.git
synced 2025-04-10 22:00:54 +01:00
Language is also Hash.
This commit is contained in:
parent
38ccd662f2
commit
b574667c80
2 changed files with 38 additions and 3 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Add table
Reference in a new issue