refactor(furvm): improve thing value access

This commit is contained in:
2026-09-04 21:19:03 +02:00
parent 0354ec1e79
commit 24a9530abc
3 changed files with 89 additions and 2 deletions
+8 -2
View File
@@ -96,11 +96,17 @@ public:
struct dynamic_array {
std::size_t size;
std::byte* data;
static bool matches(const thing_type& type) {
return type.type == thing_type::Array && type.value.array.size == 0;
}
};
struct slice {
std::size_t length;
std::byte* data;
static bool matches(const thing_type& type) { return type.type == thing_type::Slice; }
};
struct header {
@@ -407,7 +413,7 @@ public:
*/
template <typename T>
T& get() {
if (compute_size_na(*m_type) != sizeof(T)) throw bad_thing_access();
if (!detail::thing_traits<T>{}(*m_type)) throw bad_thing_access();
return *std::launder(reinterpret_cast<T*>(m_data));
}
@@ -418,7 +424,7 @@ public:
*/
template <typename T>
const T& get() const {
if (compute_size_na(*m_type) != sizeof(T)) throw bad_thing_access();
if (!detail::thing_traits<T>{}(*m_type)) throw bad_thing_access();
return *std::launder(reinterpret_cast<const T*>(m_data));
}
public:
+72
View File
@@ -6,6 +6,8 @@
#include <cstdint>
#include <limits>
#include <stdexcept>
#include <type_traits>
#include <utility>
namespace furvm {
@@ -127,6 +129,76 @@ struct thing_type {
}
};
namespace detail {
template <typename T, typename = void>
struct overrides_thing_type_matching : std::false_type {};
template <typename T>
struct overrides_thing_type_matching<T, std::void_t<decltype(T::matches(std::declval<const thing_type&>()))>>
: std::is_same<decltype(T::matches(std::declval<const thing_type&>())), bool> {};
template <typename T>
struct thing_traits {
bool operator()(const thing_type& type) const {
if constexpr (overrides_thing_type_matching<T>::value) {
return T::matches(type);
} else {
return false;
}
}
};
template <>
struct thing_traits<s8> {
bool operator()(const thing_type& type) const { return type.type == thing_type::S8; }
};
template <>
struct thing_traits<u8> {
bool operator()(const thing_type& type) const { return type.type == thing_type::U8; }
};
template <>
struct thing_traits<s16> {
bool operator()(const thing_type& type) const { return type.type == thing_type::S16; }
};
template <>
struct thing_traits<u16> {
bool operator()(const thing_type& type) const { return type.type == thing_type::U16; }
};
template <>
struct thing_traits<s32> {
bool operator()(const thing_type& type) const { return type.type == thing_type::S32; }
};
template <>
struct thing_traits<u32> {
bool operator()(const thing_type& type) const { return type.type == thing_type::U32; }
};
template <>
struct thing_traits<s64> {
bool operator()(const thing_type& type) const { return type.type == thing_type::S64; }
};
template <>
struct thing_traits<u64> {
bool operator()(const thing_type& type) const { return type.type == thing_type::U64; }
};
template <typename Inner>
struct thing_traits<Inner*> {
bool operator()(const thing_type& type) const {
return (type.type == thing_type::Ptr || type.type == thing_type::Ref) &&
thing_traits<Inner>{}(*type.value.typeRef);
}
};
} // namespace detail
} // namespace furvm
#endif // FURVM_TYPES_HPP