From 14d316a0261fb2a3541d27790cb7dc58e40de35c Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 18 Nov 2022 10:20:58 +0100 Subject: add template interface to erased accessor --- src/entity.hpp | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++------ test/entity.cpp | 5 +++++ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/entity.hpp b/src/entity.hpp index c73f6721..b1211d0b 100644 --- a/src/entity.hpp +++ b/src/entity.hpp @@ -113,9 +113,7 @@ struct read_field { template struct read_field) const>> { - template static constexpr Type read(const Obj& x, F&& fun) { - return fun(x); - } + template static constexpr Type read(const Obj& x, F&& fun) { return fun(x); } }; template W> struct write_field { @@ -134,9 +132,7 @@ struct write_field { template struct write_field) const>> { - template static constexpr void write(Obj& x, F&& fun, move_qualified value) { - fun(x, value); - } + template static constexpr void write(Obj& x, F&& fun, move_qualified value) { fun(x, value); } }; template @@ -205,6 +201,62 @@ struct erased_accessor final { object_name{object_name}, field_type_name{field_type_name}, read_fun{read_fun}, write_fun{write_fun} {} + + template + static constexpr bool check_name_static() + { + return !std::is_pointer_v && !std::is_reference_v && + !std::is_pointer_v && !std::is_reference_v; + } + + template + constexpr bool check_name() const noexcept + { + static_assert(check_name_static()); + constexpr auto obj = name_of, field = name_of; + return (obj.data() == object_name.data() && field.data() == field_type_name.data()) || + obj == object_name && field == field_type_name; + } + + template + constexpr void assert_name() const noexcept + { + fm_assert(check_name()); + } + + template + void read_unchecked(const Obj& x, FieldType& value) const noexcept + { + static_assert(check_name_static()); + read_fun(&x, reader, &value); + } + + template + requires std::is_default_constructible_v + FieldType read_unchecked(const Obj& x) const noexcept + { + static_assert(check_name_static()); + FieldType value; + read_unchecked(x, value); + return value; + } + + template + void write_unchecked(Obj& x, move_qualified value) const noexcept + { + static_assert(check_name_static()); + write_fun(&x, writer, &value); + } + + template + requires std::is_default_constructible_v + FieldType read(const Obj& x) const noexcept { assert_name(); return read_unchecked(x); } + + template + void read(const Obj& x, FieldType& value) const noexcept { assert_name(); read_unchecked(x, value); } + + template + void write(Obj& x, move_qualified value) const noexcept { assert_name(); write_unchecked(x, value); } }; template struct entity_field_base {}; diff --git a/test/entity.cpp b/test/entity.cpp index 72b0a598..d8255e26 100644 --- a/test/entity.cpp +++ b/test/entity.cpp @@ -122,6 +122,8 @@ static void test_metadata() int bar_ = 2; bar2.write_fun(&x, bar2.writer, &bar_); fm_assert(x.bar() == 2); + baz2.write(x, 3); + fm_assert(baz2.read(x) == 3); } static void test_type_name() @@ -130,6 +132,9 @@ static void test_type_name() struct foobar; constexpr StringView name = name_of; fm_assert(name.contains("foobar"_s)); + static_assert(name.data() == name_of.data()); + static_assert(name_of != name_of); + static_assert(name_of != name_of); } void test_app::test_entity() -- cgit v1.2.3