summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-11-18 10:42:26 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-11-18 10:42:26 +0100
commitb65b34a976b586f4e407f7a89567163c85b94aa6 (patch)
tree3c7ca19603fbe6b76dc9b24511a23b337a1c341d
parent41d3bbf3f3783b70a4a47e18478c227d12e73b06 (diff)
split erased accessor from main header
-rw-r--r--entity/accessor.hpp112
-rw-r--r--entity/entity.hpp (renamed from src/entity.hpp)107
-rw-r--r--entity/name-of.hpp18
-rw-r--r--entity/util.hpp22
-rw-r--r--test/entity.cpp2
5 files changed, 156 insertions, 105 deletions
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 <type_traits>
+#include <Corrade/Containers/StringView.h>
+
+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<typename T, typename FieldType>
+ static constexpr bool check_name_static();
+
+ template<typename T, typename FieldType>
+ constexpr bool check_name() const noexcept;
+
+ template<typename Obj, typename FieldType> constexpr void assert_name() const noexcept;
+ template<typename Obj, typename FieldType> void read_unchecked(const Obj& x, FieldType& value) const noexcept;
+ template<typename Obj, typename FieldType> requires std::is_default_constructible_v<FieldType> FieldType read_unchecked(const Obj& x) const noexcept;
+ template<typename Obj, typename FieldType> void write_unchecked(Obj& x, move_qualified<FieldType> value) const noexcept;
+ template<typename Obj, typename FieldType> requires std::is_default_constructible_v<FieldType> FieldType read(const Obj& x) const noexcept;
+ template<typename Obj, typename FieldType> void read(const Obj& x, FieldType& value) const noexcept;
+ template<typename Obj, typename FieldType> void write(Obj& x, move_qualified<FieldType> value) const noexcept;
+};
+
+template<typename T, typename FieldType>
+constexpr bool erased_accessor::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 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;
+}
+
+template<typename Obj, typename FieldType>
+constexpr void erased_accessor::assert_name() const noexcept
+{
+ fm_assert(check_name<Obj, FieldType>());
+}
+
+template<typename Obj, typename FieldType>
+void erased_accessor::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 erased_accessor::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 erased_accessor::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 erased_accessor::read(const Obj& x) const noexcept {
+ assert_name<Obj, FieldType>();
+ return read_unchecked<Obj, FieldType>(x);
+}
+
+template<typename Obj, typename FieldType>
+void erased_accessor::read(const Obj& x, FieldType& value) const noexcept
+{
+ assert_name<Obj, FieldType>();
+ read_unchecked<Obj, FieldType>(x, value);
+}
+
+template<typename Obj, typename FieldType>
+void erased_accessor::write(Obj& x, move_qualified<FieldType> value) const noexcept
+{
+ assert_name<Obj, FieldType>();
+ write_unchecked<Obj, FieldType>(x, value);
+}
+
+} // namespace floormat::entities
diff --git a/src/entity.hpp b/entity/entity.hpp
index 0f7ccbe0..8f0980ae 100644
--- a/src/entity.hpp
+++ b/entity/entity.hpp
@@ -1,5 +1,8 @@
#pragma once
+#include "name-of.hpp"
#include "compat/integer-types.hpp"
+#include "accessor.hpp"
+#include "util.hpp"
#include <concepts>
#include <compare>
#include <type_traits>
@@ -10,33 +13,8 @@
#include <compat/function2.hpp>
#include <Corrade/Containers/StringView.h>
-#if defined _MSC_VER
-#define FM_PRETTY_FUNCTION __FUNCSIG__
-#else
-#define FM_PRETTY_FUNCTION __PRETTY_FUNCTION__
-#endif
-
-template<typename T>
-static constexpr auto _name_of() {
- using namespace Corrade::Containers;
- using SVF = StringViewFlag;
- constexpr const char* str = FM_PRETTY_FUNCTION;
- return StringView { str, Implementation::strlen_(str), SVF::Global|SVF::NullTerminated };
-}
-
-template<typename T> constexpr inline Corrade::Containers::StringView name_of = _name_of<T>();
-
namespace floormat::entities {
-template<typename T, typename = void> struct pass_by_value : std::bool_constant<std::is_fundamental_v<T>> {};
-template<> struct pass_by_value<StringView> : std::true_type {};
-template<typename T> struct pass_by_value<T, std::enable_if_t<std::is_trivially_copy_constructible_v<T> && sizeof(T) <= sizeof(void*)>> : std::true_type {};
-template<typename T> constexpr inline bool pass_by_value_v = pass_by_value<T>::value;
-
-template<typename T> using const_qualified = std::conditional_t<pass_by_value_v<T>, T, const T&>;
-template<typename T> using ref_qualified = std::conditional_t<pass_by_value_v<T>, T, T&>;
-template<typename T> using move_qualified = std::conditional_t<pass_by_value_v<T>, T, T&&>;
-
template<typename F, typename T, typename FieldType>
concept FieldReader_memfn = requires(const T x, F f) {
{ (x.*f)() } -> std::convertible_to<FieldType>;
@@ -167,85 +145,6 @@ using accessors_for = typename accessors_for_<T>::type;
} // namespace detail
-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<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 {};
template<typename Obj, typename Type, FieldReader<Obj, Type> R, FieldWriter<Obj, Type> W>
diff --git a/entity/name-of.hpp b/entity/name-of.hpp
new file mode 100644
index 00000000..592f07c1
--- /dev/null
+++ b/entity/name-of.hpp
@@ -0,0 +1,18 @@
+#pragma once
+#include <Corrade/Containers/StringView.h>
+
+#if defined _MSC_VER
+#define FM_PRETTY_FUNCTION __FUNCSIG__
+#else
+#define FM_PRETTY_FUNCTION __PRETTY_FUNCTION__
+#endif
+
+template<typename T>
+static constexpr auto _name_of() {
+ using namespace Corrade::Containers;
+ using SVF = StringViewFlag;
+ constexpr const char* str = FM_PRETTY_FUNCTION;
+ return StringView { str, Implementation::strlen_(str), SVF::Global|SVF::NullTerminated };
+}
+
+template<typename T> constexpr inline Corrade::Containers::StringView name_of = _name_of<T>();
diff --git a/entity/util.hpp b/entity/util.hpp
new file mode 100644
index 00000000..073745e9
--- /dev/null
+++ b/entity/util.hpp
@@ -0,0 +1,22 @@
+#pragma once
+#include <type_traits>
+
+namespace Corrade::Containers {
+
+template<typename T> class BasicStringView;
+using StringView = BasicStringView<const char>;
+
+} // namespace Corrade::Containers
+
+namespace floormat::entities {
+
+template<typename T, typename = void> struct pass_by_value : std::bool_constant<std::is_fundamental_v<T>> {};
+template<> struct pass_by_value<StringView> : std::true_type {};
+template<typename T> struct pass_by_value<T, std::enable_if_t<std::is_trivially_copy_constructible_v<T> && sizeof(T) <= sizeof(void*)>> : std::true_type {};
+template<typename T> constexpr inline bool pass_by_value_v = pass_by_value<T>::value;
+
+template<typename T> using const_qualified = std::conditional_t<pass_by_value_v<T>, T, const T&>;
+template<typename T> using ref_qualified = std::conditional_t<pass_by_value_v<T>, T, T&>;
+template<typename T> using move_qualified = std::conditional_t<pass_by_value_v<T>, T, T&&>;
+
+} // namespace floormat::entities
diff --git a/test/entity.cpp b/test/entity.cpp
index d8255e26..afec3f7c 100644
--- a/test/entity.cpp
+++ b/test/entity.cpp
@@ -1,6 +1,6 @@
#include "app.hpp"
#include "compat/assert.hpp"
-#include "src/entity.hpp"
+#include "entity/entity.hpp"
#include <tuple>
using namespace floormat;