From 4cd305a0420f1acc75a8f81ff15264a99581f9d0 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 13 Nov 2022 18:02:21 +0100 Subject: some WIP entity stuff --- src/entity.hpp | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/entity.hpp (limited to 'src') diff --git a/src/entity.hpp b/src/entity.hpp new file mode 100644 index 00000000..b63d13e8 --- /dev/null +++ b/src/entity.hpp @@ -0,0 +1,119 @@ +#pragma once +#include "compat/integer-types.hpp" +#include +#include +#include + +#include + +namespace floormat {} + +namespace floormat::entities { + +template using const_qualified = std::conditional_t, T, const T&>; +template using ref_qualified = std::conditional_t, T, T&>; +template using move_qualified = std::conditional_t, T, T&&>; + +template +concept FieldReader_memfn = requires(const T x, F f) { + { (x.*f)() } -> std::convertible_to; +}; + +template +concept FieldReader_ptr = requires(const T x, F f) { + { x.*f } -> std::convertible_to; +}; + +template +concept FieldReader_function = requires(const T x, F f) { + { f(x) } -> std::convertible_to; +}; + +template +concept FieldReader = requires { + requires FieldReader_memfn || + FieldReader_ptr || + FieldReader_function; +}; + +template +concept FieldWriter_memfn = requires(T x, move_qualified value, F f) { + { (x.*f)(value) } -> std::same_as; +}; + +template +concept FieldWriter_ptr = requires(T x, move_qualified value, F f) { + { x.*f = value }; +}; + +template +concept FieldWriter_function = requires(T x, move_qualified value, F f) { + { f(x, value) } -> std::same_as; +}; + +template +concept FieldWriter = requires { + requires FieldWriter_memfn || + FieldWriter_ptr || + FieldWriter_function; +}; + +template +struct read_field { + static Type read(const Obj& x, R r) { return r(x); } +}; + +template +struct read_field { + static Type read(const Obj& x, Type (Obj::*r)() const) { return (x.*r)(); } +}; + +template +struct read_field { + static Type read(const Obj& x, Type Obj::*r) { return x.*r; } +}; + +template struct write_field { + static FieldType write(const Obj& x, Writer w, move_qualified value) { return w(x, value); } +}; + +template +struct write_field)> { + static Type write(const Obj& x, void(Type::*w)(Type&&), move_qualified value) { return (x.*w)(value); } +}; + +template +struct write_field { + static Type write(const Obj& x, Type Obj::* w, move_qualified value) { return x.*w = value; } +}; + +template R, FieldWriter W> +struct field { + using Object = Obj; + using Type = FieldType; + using Reader = R; + using Writer = W; + + StringView name; + Reader reader; + 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::read(x, reader); } + void write(Obj& x, move_qualified v) const { return write_field::write(x, v); } +}; + +template +struct entity { + template + struct Field { + template R, FieldWriter W> + struct make final : field { + consteval make(StringView name_, R r, W w) noexcept : field{name_, r, w} {} + }; + template R, FieldWriter W> + make(StringView name, R r, W w) -> make; + }; +}; + +} // namespace floormat::entities -- cgit v1.2.3