summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-11-18 10:20:58 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-11-18 10:27:54 +0100
commit14d316a0261fb2a3541d27790cb7dc58e40de35c (patch)
tree4a864228a707cde7aa9aa612667751586f49c095
parent4cf0ac3bcd8a2aa480a29ef43f2cca88c190d874 (diff)
add template interface to erased accessor
-rw-r--r--src/entity.hpp64
-rw-r--r--test/entity.cpp5
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<Obj, Type, Type Obj::*> {
template<typename Obj, typename Type, bool IsOwning, bool IsCopyable, typename Capacity, bool IsThrowing, bool HasStrongExceptionGuarantee>
struct read_field<Obj, Type, fu2::function_base<IsOwning, IsCopyable, Capacity, IsThrowing, HasStrongExceptionGuarantee, void(const Obj&, move_qualified<Type>) const>> {
- template<typename F> static constexpr Type read(const Obj& x, F&& fun) {
- return fun(x);
- }
+ template<typename F> static constexpr Type read(const Obj& x, F&& fun) { return fun(x); }
};
template<typename Obj, typename FieldType, FieldWriter<Obj, FieldType> W> struct write_field {
@@ -134,9 +132,7 @@ struct write_field<Obj, FieldType, FieldType Obj::*> {
template<typename Obj, typename Type, bool IsOwning, bool IsCopyable, typename Capacity, bool IsThrowing, bool HasStrongExceptionGuarantee>
struct write_field<Obj, Type, fu2::function_base<IsOwning, IsCopyable, Capacity, IsThrowing, HasStrongExceptionGuarantee, void(Obj&, move_qualified<Type>) const>> {
- template<typename F> static constexpr void write(Obj& x, F&& fun, move_qualified<Type> value) {
- fun(x, value);
- }
+ template<typename F> static constexpr void write(Obj& x, F&& fun, move_qualified<Type> value) { fun(x, value); }
};
template<typename F, typename Tuple, std::size_t N>
@@ -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<typename T, typename FieldType>
+ static constexpr bool check_name_static()
+ {
+ return !std::is_pointer_v<T> && !std::is_reference_v<T> &&
+ !std::is_pointer_v<FieldType> && !std::is_reference_v<T>;
+ }
+
+ template<typename T, typename FieldType>
+ constexpr bool 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;
+ }
+
+ template<typename Obj, typename FieldType>
+ constexpr void assert_name() const noexcept
+ {
+ fm_assert(check_name<Obj, FieldType>());
+ }
+
+ template<typename Obj, typename FieldType>
+ void read_unchecked(const Obj& x, FieldType& value) const noexcept
+ {
+ static_assert(check_name_static<Obj, FieldType>());
+ read_fun(&x, reader, &value);
+ }
+
+ template<typename Obj, typename FieldType>
+ requires std::is_default_constructible_v<FieldType>
+ FieldType read_unchecked(const Obj& x) const noexcept
+ {
+ static_assert(check_name_static<Obj, FieldType>());
+ FieldType value;
+ read_unchecked(x, value);
+ return value;
+ }
+
+ template<typename Obj, typename FieldType>
+ void write_unchecked(Obj& x, move_qualified<FieldType> value) const noexcept
+ {
+ static_assert(check_name_static<Obj, FieldType>());
+ write_fun(&x, writer, &value);
+ }
+
+ template<typename Obj, typename FieldType>
+ requires std::is_default_constructible_v<FieldType>
+ FieldType read(const Obj& x) const noexcept { assert_name<Obj, FieldType>(); return read_unchecked<Obj, FieldType>(x); }
+
+ template<typename Obj, typename FieldType>
+ void read(const Obj& x, FieldType& value) const noexcept { assert_name<Obj, FieldType>(); read_unchecked<Obj, FieldType>(x, value); }
+
+ template<typename Obj, typename FieldType>
+ void write(Obj& x, move_qualified<FieldType> value) const noexcept { assert_name<Obj, FieldType>(); write_unchecked<Obj, FieldType>(x, value); }
};
template<typename Obj, typename Type> 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<TestAccessors, int>(x, 3);
+ fm_assert(baz2.read<TestAccessors, int>(x) == 3);
}
static void test_type_name()
@@ -130,6 +132,9 @@ static void test_type_name()
struct foobar;
constexpr StringView name = name_of<foobar>;
fm_assert(name.contains("foobar"_s));
+ static_assert(name.data() == name_of<foobar>.data());
+ static_assert(name_of<int> != name_of<unsigned>);
+ static_assert(name_of<foobar*> != name_of<const foobar*>);
}
void test_app::test_entity()