diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-18 15:55:10 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-18 15:55:10 +0100 |
commit | 28449ce459900bd88527ed424c4297b4cd936fe6 (patch) | |
tree | d13c7ed823655434c5539589e825d45450c04e4f | |
parent | 9b8b439132b00f0aa6f0c307fa06641803dd75a8 (diff) |
entity/field: add field name to erased accessor
-rw-r--r-- | entity/accessor.hpp | 11 | ||||
-rw-r--r-- | entity/field.hpp | 15 | ||||
-rw-r--r-- | test/entity.cpp | 18 |
3 files changed, 31 insertions, 13 deletions
diff --git a/entity/accessor.hpp b/entity/accessor.hpp index a097afd4..b88b6686 100644 --- a/entity/accessor.hpp +++ b/entity/accessor.hpp @@ -13,17 +13,16 @@ struct erased_accessor final { const erased_reader_t* reader; const erased_writer_t* writer; - StringView object_name, field_type_name; + StringView field_name, object_type, field_type; void(*read_fun)(const Object*, const erased_reader_t*, Value*); void(*write_fun)(Object*, const erased_writer_t*, Value*); constexpr erased_accessor(const erased_accessor&) = default; - constexpr erased_accessor(erased_reader_t* reader, erased_writer_t * writer, + constexpr erased_accessor(erased_reader_t* reader, erased_writer_t * writer, StringView field_name, StringView object_name, StringView field_type_name, void(*read_fun)(const Object*, const erased_reader_t*, Value*), void(*write_fun)(Object*, const erased_writer_t*, Value*)) : - reader{reader}, writer{writer}, - object_name{object_name}, field_type_name{field_type_name}, + reader{reader}, writer{writer}, field_name{field_name}, object_type{object_name}, field_type{field_type_name}, read_fun{read_fun}, write_fun{write_fun} {} @@ -55,8 +54,8 @@ constexpr bool erased_accessor::check_name() const noexcept { static_assert(check_name_static<T, FieldType>()); constexpr auto obj = name_of<T>, field = name_of<FieldType>; - return (obj.data() == object_name.data() && field.data() == field_type_name.data()) || - obj == object_name && field == field_type_name; + return (obj.data() == object_type.data() && field.data() == field_type.data()) || + obj == object_type && field == field_type; } template<typename Obj, typename FieldType> diff --git a/entity/field.hpp b/entity/field.hpp index 9b64da56..4e18493d 100644 --- a/entity/field.hpp +++ b/entity/field.hpp @@ -4,11 +4,9 @@ #include "util.hpp" #include <cstddef> #include <concepts> -#include <compare> #include <type_traits> #include <utility> #include <tuple> -#include <typeinfo> #include <array> #include <compat/function2.hpp> #include <Corrade/Containers/StringView.h> @@ -178,24 +176,27 @@ constexpr erased_accessor entity_field<Obj, Type, R, W>::erased() const using writer_t = typename erased_accessor::erased_writer_t; constexpr auto obj_name = name_of<Obj>, field_name = name_of<Type>; - constexpr auto reader_fn = [](const void* obj, const reader_t* reader, void* value) - { + constexpr auto reader_fn = [](const void* obj, const reader_t* reader, void* value) { const auto& obj_ = *reinterpret_cast<const Obj*>(obj); const auto& reader_ = *reinterpret_cast<const R*>(reader); auto& value_ = *reinterpret_cast<Type*>(value); value_ = read(reader_, obj_); }; - constexpr auto writer_fn = [](void* obj, const writer_t* writer, void* value) - { + constexpr auto writer_fn = [](void* obj, const writer_t* writer, void* value) { auto& obj_ = *reinterpret_cast<Obj*>(obj); const auto& writer_ = *reinterpret_cast<const W*>(writer); move_qualified<Type> value_ = std::move(*reinterpret_cast<Type*>(value)); write(writer_, obj_, value_); }; + constexpr auto writer_stub_fn = [](void*, const writer_t*, void*) { + fm_abort("no writer for this accessor"); + }; + return erased_accessor { (void*)&reader, writer ? (void*)&writer : nullptr, + name, obj_name, field_name, - reader_fn, writer_fn, + reader_fn, writer ? writer_fn : writer_stub_fn, }; } diff --git a/test/entity.cpp b/test/entity.cpp index f18b30ca..8e80ba64 100644 --- a/test/entity.cpp +++ b/test/entity.cpp @@ -119,6 +119,7 @@ void test_erasure() { void test_metadata() { constexpr auto m = entity_metadata<TestAccessors>(); + static_assert(sizeof m == 1); fm_assert(m.class_name == name_of<TestAccessors>); fm_assert(m.class_name.contains("TestAccessors"_s)); const auto [foo, bar, baz] = m.accessors; @@ -156,11 +157,28 @@ constexpr bool test_null_writer() } // namespace +static constexpr bool test_names() +{ + constexpr auto m = entity_metadata<TestAccessors>(); + auto [foo1, bar1, baz1] = m.accessors; + auto [foo2, bar2, baz2] = m.erased_accessors; + + fm_assert(foo1.name == "foo"_s); + fm_assert(bar1.name == "bar"_s); + fm_assert(baz1.name == "baz"_s); + + fm_assert(foo2.field_name == "foo"_s); + fm_assert(bar2.field_name == "bar"_s); + fm_assert(baz2.field_name == "baz"_s); + return true; +} + void test_app::test_entity() { static_assert(test_accessors()); static_assert(test_visitor()); static_assert(test_null_writer()); + static_assert(test_names()); test_fun2(); test_erasure(); test_type_name(); |