mirror of
https://github.com/luau-lang/luau.git
synced 2025-04-19 19:23:49 +01:00
Make Language noexcept and final.
This commit is contained in:
parent
ab81f39b83
commit
15167ad497
1 changed files with 31 additions and 26 deletions
|
@ -27,13 +27,6 @@ std::size_t languageHash(const T& lang) {
|
||||||
return LanguageHash<T>{}(lang);
|
return LanguageHash<T>{}(lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void hashCombine(size_t& seed, size_t hash)
|
|
||||||
{
|
|
||||||
// Golden Ratio constant used for better hash scattering
|
|
||||||
// See https://softwareengineering.stackexchange.com/a/402543
|
|
||||||
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> \
|
||||||
{ \
|
{ \
|
||||||
|
@ -172,7 +165,7 @@ public:
|
||||||
//
|
//
|
||||||
// And finally, each `T` in `Ts` have additional requirements which `Luau::Variant` doesn't need.
|
// And finally, each `T` in `Ts` have additional requirements which `Luau::Variant` doesn't need.
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
class Language
|
class Language final
|
||||||
{
|
{
|
||||||
const char* tag;
|
const char* tag;
|
||||||
char buffer[std::max({sizeof(Ts)...})];
|
char buffer[std::max({sizeof(Ts)...})];
|
||||||
|
@ -189,37 +182,37 @@ private:
|
||||||
using FnOper = Slice<Id> (*)(void*);
|
using FnOper = Slice<Id> (*)(void*);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void fnCopy(void* dst, const void* src)
|
static void fnCopy(void* dst, const void* src) noexcept
|
||||||
{
|
{
|
||||||
new (dst) T(*static_cast<const T*>(src));
|
new (dst) T(*static_cast<const T*>(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void fnMove(void* dst, void* src)
|
static void fnMove(void* dst, void* src) noexcept
|
||||||
{
|
{
|
||||||
new (dst) T(static_cast<T&&>(*static_cast<T*>(src)));
|
new (dst) T(static_cast<T&&>(*static_cast<T*>(src)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void fnDtor(void* dst)
|
static void fnDtor(void* dst) noexcept
|
||||||
{
|
{
|
||||||
static_cast<T*>(dst)->~T();
|
static_cast<T*>(dst)->~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static bool fnPred(const void* lhs, const void* rhs)
|
static bool fnPred(const void* lhs, const void* rhs) noexcept
|
||||||
{
|
{
|
||||||
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>
|
template<typename T>
|
||||||
static size_t fnHash(const void* buffer)
|
static size_t fnHash(const void* buffer) noexcept
|
||||||
{
|
{
|
||||||
return typename T::Hash{}(*static_cast<const T*>(buffer));
|
return typename T::Hash{}(*static_cast<const T*>(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static Slice<Id> fnOper(void* buffer)
|
static Slice<Id> fnOper(void* buffer) noexcept
|
||||||
{
|
{
|
||||||
return static_cast<T*>(buffer)->operands();
|
return static_cast<T*>(buffer)->operands();
|
||||||
}
|
}
|
||||||
|
@ -231,7 +224,7 @@ private:
|
||||||
static constexpr FnHash tableHash[sizeof...(Ts)] = {&fnHash<Ts>...};
|
static constexpr FnHash tableHash[sizeof...(Ts)] = {&fnHash<Ts>...};
|
||||||
static constexpr FnOper tableOper[sizeof...(Ts)] = {&fnOper<Ts>...};
|
static constexpr FnOper tableOper[sizeof...(Ts)] = {&fnOper<Ts>...};
|
||||||
|
|
||||||
static constexpr int getIndexFromTag(const char* tag)
|
static constexpr int getIndexFromTag(const char* tag) noexcept
|
||||||
{
|
{
|
||||||
constexpr int N = sizeof...(Ts);
|
constexpr int N = sizeof...(Ts);
|
||||||
constexpr const char* is[N] = {Ts::tag...};
|
constexpr const char* is[N] = {Ts::tag...};
|
||||||
|
@ -245,37 +238,37 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Language(T&& t, std::enable_if_t<WithinDomain<T>::value>* = 0)
|
Language(T&& t, std::enable_if_t<WithinDomain<T>::value>* = 0) noexcept
|
||||||
{
|
{
|
||||||
tag = T::tag;
|
tag = T::tag;
|
||||||
new (&buffer) std::decay_t<T>(std::forward<T>(t));
|
new (&buffer) std::decay_t<T>(std::forward<T>(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
Language(const Language& other)
|
Language(const Language& other) noexcept
|
||||||
{
|
{
|
||||||
tag = other.tag;
|
tag = other.tag;
|
||||||
tableCopy[getIndexFromTag(tag)](&buffer, &other.buffer);
|
tableCopy[getIndexFromTag(tag)](&buffer, &other.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Language(Language&& other)
|
Language(Language&& other) noexcept
|
||||||
{
|
{
|
||||||
tag = other.tag;
|
tag = other.tag;
|
||||||
tableMove[getIndexFromTag(tag)](&buffer, &other.buffer);
|
tableMove[getIndexFromTag(tag)](&buffer, &other.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Language()
|
~Language() noexcept
|
||||||
{
|
{
|
||||||
tableDtor[getIndexFromTag(tag)](&buffer);
|
tableDtor[getIndexFromTag(tag)](&buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Language& operator=(const Language& other)
|
Language& operator=(const Language& other) noexcept
|
||||||
{
|
{
|
||||||
Language copy{other};
|
Language copy{other};
|
||||||
*this = static_cast<Language&&>(copy);
|
*this = static_cast<Language&&>(copy);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Language& operator=(Language&& other)
|
Language& operator=(Language&& other) noexcept
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
|
@ -286,31 +279,36 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index() const
|
int index() const noexcept
|
||||||
{
|
{
|
||||||
return getIndexFromTag(tag);
|
return getIndexFromTag(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// You should never call this function with the intention of mutating the `Id`.
|
/// You should never call this function with the intention of mutating the `Id`.
|
||||||
/// Reading is ok, but you should also never assume that these `Id`s are stable.
|
/// Reading is ok, but you should also never assume that these `Id`s are stable.
|
||||||
Slice<Id> operands()
|
Slice<Id> operands() noexcept
|
||||||
{
|
{
|
||||||
return tableOper[getIndexFromTag(tag)](&buffer);
|
return tableOper[getIndexFromTag(tag)](&buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Slice<Id> operands() const noexcept
|
||||||
|
{
|
||||||
|
return const_cast<Language*>(this)->operands();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const T* get() const
|
const T* get() const noexcept
|
||||||
{
|
{
|
||||||
static_assert(WithinDomain<T>::value);
|
static_assert(WithinDomain<T>::value);
|
||||||
return tag == T::tag ? reinterpret_cast<const T*>(&buffer) : nullptr;
|
return tag == T::tag ? reinterpret_cast<const T*>(&buffer) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Language& rhs) const
|
bool operator==(const Language& rhs) const noexcept
|
||||||
{
|
{
|
||||||
return tag == rhs.tag && tablePred[getIndexFromTag(tag)](&buffer, &rhs.buffer);
|
return tag == rhs.tag && tablePred[getIndexFromTag(tag)](&buffer, &rhs.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Language& rhs) const
|
bool operator!=(const Language& rhs) const noexcept
|
||||||
{
|
{
|
||||||
return !(*this == rhs);
|
return !(*this == rhs);
|
||||||
}
|
}
|
||||||
|
@ -327,6 +325,13 @@ public:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void hashCombine(size_t& seed, size_t hash)
|
||||||
|
{
|
||||||
|
// Golden Ratio constant used for better hash scattering
|
||||||
|
// See https://softwareengineering.stackexchange.com/a/402543
|
||||||
|
seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct LanguageHash<T, std::void_t<decltype(std::hash<T>{}(std::declval<T>()))>>
|
struct LanguageHash<T, std::void_t<decltype(std::hash<T>{}(std::declval<T>()))>>
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue