diff options
-rw-r--r-- | src/entity.hpp | 42 | ||||
-rw-r--r-- | test/entity.cpp | 43 |
2 files changed, 51 insertions, 34 deletions
diff --git a/src/entity.hpp b/src/entity.hpp index 7d55bfd6..b46fefcc 100644 --- a/src/entity.hpp +++ b/src/entity.hpp @@ -1,8 +1,10 @@ #pragma once #include "compat/integer-types.hpp" -#include <type_traits> #include <concepts> -#include <functional> +#include <type_traits> +#include <tuple> +#include <utility> +#include <algorithm> #include <Corrade/Containers/StringView.h> @@ -10,9 +12,13 @@ namespace floormat {} namespace floormat::entities { -template<typename T> using const_qualified = std::conditional_t<std::is_fundamental_v<T>, T, const T&>; -template<typename T> using ref_qualified = std::conditional_t<std::is_fundamental_v<T>, T, T&>; -template<typename T> using move_qualified = std::conditional_t<std::is_fundamental_v<T>, T, T&&>; +template<typename T> struct pass_by_value : std::bool_constant<std::is_fundamental_v<T>> {}; +template<typename T> constexpr inline bool pass_by_value_v = pass_by_value<T>::value; +template<> struct pass_by_value<StringView> : std::true_type {}; + +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) { @@ -95,8 +101,8 @@ struct field { using Writer = W; StringView name; - Reader reader; - Writer writer; + [[no_unique_address]] Reader reader; + [[no_unique_address]] Writer writer; constexpr field(StringView name, Reader r, Writer w) noexcept : name{name}, reader{r}, writer{w} {} decltype(auto) read(const Obj& x) const { return read_field<Obj, FieldType, R>::read(x, reader); } @@ -104,16 +110,26 @@ struct field { }; template<typename Obj> -struct entity { +struct entity final { template<typename FieldType> struct Field { template<FieldReader<Obj, FieldType> R, FieldWriter<Obj, FieldType> W> - struct make final : field<Obj, FieldType, R, W> { - consteval make(StringView name_, R r, W w) noexcept : field<Obj, FieldType, R, W>{name_, r, w} {} - }; - template<FieldReader<Obj, FieldType> R, FieldWriter<Obj, FieldType> W> - make(StringView name, R r, W w) -> make<R, W>; + static consteval auto make(StringView name, R r, W w) noexcept { + return field<Obj, FieldType, R, W> { name, r, w }; + } }; }; +template<typename Key, typename KeyT, typename... Xs> +struct assoc final { + template<typename T> using Types = std::tuple<Xs...>; + consteval assoc(Xs&&... xs) { + + } + +private: + template<typename T> struct cell { Key key; T value; }; + std::tuple<cell<Xs>...> _tuple; +}; + } // namespace floormat::entities diff --git a/test/entity.cpp b/test/entity.cpp index ae50853c..6789a241 100644 --- a/test/entity.cpp +++ b/test/entity.cpp @@ -2,34 +2,32 @@ #include "compat/assert.hpp" #include "src/entity.hpp" +struct Test { + int foo = 111; + int bar() const { return _bar; } + void set_bar(int value) { _bar = value; } + int _baz = 333; +private: + int _bar = 222; +}; + namespace floormat { using namespace floormat::entities; -void test_app::test_entity() +static void test_accessors() { - struct Test { - int foo = 111; - int bar() const { return _bar; } - void set_bar(int value) { _bar = value; } - int _baz = 333; - private: - int _bar = 222; - }; - using Entity = entity<Test>; - constexpr const auto m_foo = Entity::Field<int>::make{ "foo"_s, &Test::foo, &Test::foo, }; - constexpr const auto m_bar = Entity::Field<int>::make{ "bar"_s, &Test::bar, &Test::set_bar, }; - constexpr const auto r_baz = [](const Test& x) { return x._baz; }; - constexpr const auto w_baz = [](Test& x, int v) { x._baz = v; }; - constexpr const auto m_baz = Entity::Field<int>::make{ "baz"_s, r_baz, w_baz }; + constexpr auto m_foo = Entity::Field<int>::make("foo"_s, &Test::foo, &Test::foo); + constexpr auto m_bar = Entity::Field<int>::make("bar"_s, &Test::bar, &Test::set_bar); + constexpr auto r_baz = [](const Test& x) { return x._baz; }; + constexpr auto w_baz = [](Test& x, int v) { x._baz = v; }; + constexpr auto m_baz = Entity::Field<int>::make("baz"_s, r_baz, w_baz); auto x = Test{}; { - auto a = m_foo.read(x); - auto b = m_bar.read(x); - auto c = m_baz.read(x); + auto a = m_foo.read(x), b = m_bar.read(x), c = m_baz.read(x); fm_assert(a == 111 && b == 222 && c == 333); } @@ -37,11 +35,14 @@ void test_app::test_entity() m_foo.write(x, 1111); m_bar.write(x, 2222); m_baz.write(x, 3333); - auto a = m_foo.read(x); - auto b = m_bar.read(x); - auto c = m_baz.read(x); + auto a = m_foo.read(x), b = m_bar.read(x), c = m_baz.read(x); fm_assert(a == 1111 && b == 2222 && c == 3333); } } +void test_app::test_entity() +{ + test_accessors(); +} + } // namespace floormat |