From 24a9530abcc95105625ba490ac94d16fb5534e33 Mon Sep 17 00:00:00 2001 From: CHatingPython Date: Fri, 4 Sep 2026 21:19:03 +0200 Subject: [PATCH] refactor(furvm): improve thing value access --- furvm/include/furvm/thing.hpp | 10 ++++- furvm/include/furvm/types.hpp | 72 +++++++++++++++++++++++++++++++++++ furvm/test/test.cpp | 9 +++++ 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/furvm/include/furvm/thing.hpp b/furvm/include/furvm/thing.hpp index e479c84..1531fdb 100644 --- a/furvm/include/furvm/thing.hpp +++ b/furvm/include/furvm/thing.hpp @@ -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 T& get() { - if (compute_size_na(*m_type) != sizeof(T)) throw bad_thing_access(); + if (!detail::thing_traits{}(*m_type)) throw bad_thing_access(); return *std::launder(reinterpret_cast(m_data)); } @@ -418,7 +424,7 @@ public: */ template const T& get() const { - if (compute_size_na(*m_type) != sizeof(T)) throw bad_thing_access(); + if (!detail::thing_traits{}(*m_type)) throw bad_thing_access(); return *std::launder(reinterpret_cast(m_data)); } public: diff --git a/furvm/include/furvm/types.hpp b/furvm/include/furvm/types.hpp index 6d27c3c..e9d5bdb 100644 --- a/furvm/include/furvm/types.hpp +++ b/furvm/include/furvm/types.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include namespace furvm { @@ -127,6 +129,76 @@ struct thing_type { } }; +namespace detail { + +template +struct overrides_thing_type_matching : std::false_type {}; + +template +struct overrides_thing_type_matching()))>> + : std::is_same())), bool> {}; + +template +struct thing_traits { + bool operator()(const thing_type& type) const { + if constexpr (overrides_thing_type_matching::value) { + return T::matches(type); + } else { + return false; + } + } +}; + +template <> +struct thing_traits { + bool operator()(const thing_type& type) const { return type.type == thing_type::S8; } +}; + +template <> +struct thing_traits { + bool operator()(const thing_type& type) const { return type.type == thing_type::U8; } +}; + +template <> +struct thing_traits { + bool operator()(const thing_type& type) const { return type.type == thing_type::S16; } +}; + +template <> +struct thing_traits { + bool operator()(const thing_type& type) const { return type.type == thing_type::U16; } +}; + +template <> +struct thing_traits { + bool operator()(const thing_type& type) const { return type.type == thing_type::S32; } +}; + +template <> +struct thing_traits { + bool operator()(const thing_type& type) const { return type.type == thing_type::U32; } +}; + +template <> +struct thing_traits { + bool operator()(const thing_type& type) const { return type.type == thing_type::S64; } +}; + +template <> +struct thing_traits { + bool operator()(const thing_type& type) const { return type.type == thing_type::U64; } +}; + +template +struct thing_traits { + bool operator()(const thing_type& type) const { + return (type.type == thing_type::Ptr || type.type == thing_type::Ref) && + thing_traits{}(*type.value.typeRef); + } +}; + +} // namespace detail + } // namespace furvm #endif // FURVM_TYPES_HPP diff --git a/furvm/test/test.cpp b/furvm/test/test.cpp index c28248b..f560151 100644 --- a/furvm/test/test.cpp +++ b/furvm/test/test.cpp @@ -1,3 +1,4 @@ +#include "furvm/exceptions.hpp" #include "furvm/furvm.hpp" #include "furvm/thing.hpp" @@ -77,4 +78,12 @@ TEST(ThingOps, Iterators) { } } +TEST(ThingOps, Access) { + furvm::thing thing{ furvm::thing_type{ furvm::thing_type::U8 } }; + EXPECT_NO_THROW(thing.get()); + EXPECT_THROW(thing.get(), furvm::bad_thing_access); + EXPECT_THROW(thing.get(), furvm::bad_thing_access); + EXPECT_THROW(thing.get(), furvm::bad_thing_access); +} + } // namespace