From b65b34a976b586f4e407f7a89567163c85b94aa6 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 18 Nov 2022 10:42:26 +0100 Subject: split erased accessor from main header --- entity/accessor.hpp | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 entity/accessor.hpp (limited to 'entity/accessor.hpp') diff --git a/entity/accessor.hpp b/entity/accessor.hpp new file mode 100644 index 00000000..9b836420 --- /dev/null +++ b/entity/accessor.hpp @@ -0,0 +1,112 @@ +#pragma once +#include "util.hpp" +#include +#include + +namespace floormat::entities { + +struct erased_accessor final { + using erased_reader_t = void; + using erased_writer_t = void; + using Object = void; + using Value = void; + + const erased_reader_t* reader; + const erased_writer_t* writer; + StringView object_name, field_type_name; + 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, + 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}, + read_fun{read_fun}, write_fun{write_fun} + {} + + template + static constexpr bool check_name_static(); + + template + constexpr bool check_name() const noexcept; + + template constexpr void assert_name() const noexcept; + template void read_unchecked(const Obj& x, FieldType& value) const noexcept; + template requires std::is_default_constructible_v FieldType read_unchecked(const Obj& x) const noexcept; + template void write_unchecked(Obj& x, move_qualified value) const noexcept; + template requires std::is_default_constructible_v FieldType read(const Obj& x) const noexcept; + template void read(const Obj& x, FieldType& value) const noexcept; + template void write(Obj& x, move_qualified value) const noexcept; +}; + +template +constexpr bool erased_accessor::check_name_static() +{ + return !std::is_pointer_v && !std::is_reference_v && + !std::is_pointer_v && !std::is_reference_v; +} + +template +constexpr bool erased_accessor::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 erased_accessor::assert_name() const noexcept +{ + fm_assert(check_name()); +} + +template +void erased_accessor::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 erased_accessor::read_unchecked(const Obj& x) const noexcept +{ + static_assert(check_name_static()); + FieldType value; + read_unchecked(x, value); + return value; +} + +template +void erased_accessor::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 erased_accessor::read(const Obj& x) const noexcept { + assert_name(); + return read_unchecked(x); +} + +template +void erased_accessor::read(const Obj& x, FieldType& value) const noexcept +{ + assert_name(); + read_unchecked(x, value); +} + +template +void erased_accessor::write(Obj& x, move_qualified value) const noexcept +{ + assert_name(); + write_unchecked(x, value); +} + +} // namespace floormat::entities -- cgit v1.2.3