#pragma once #include "name-of.hpp" #include "accessor.hpp" #include "field.hpp" #include "concepts.hpp" #include #include #include #include namespace floormat::entities::detail { template requires std::invocable(std::declval()))> constexpr CORRADE_ALWAYS_INLINE void visit_tuple(F&& fun, Tuple&& tuple) { using Size = std::tuple_size>; static_assert(N < Size()); fun(std::get(tuple)); if constexpr(N+1 < Size()) visit_tuple(floormat::forward(fun), floormat::forward(tuple)); } template requires std::is_invocable_r_v(std::declval()))> constexpr CORRADE_ALWAYS_INLINE bool find_in_tuple(F&& fun, Tuple&& tuple) { using Size = std::tuple_size>; static_assert(N < Size()); if (fun(std::get(tuple))) return true; if constexpr(N+1 < Size()) return find_in_tuple(floormat::forward(fun), floormat::forward(tuple)); return false; } template struct decay_tuple_; template struct decay_tuple_> { using type = std::tuple...>; }; template using decay_tuple = typename decay_tuple_::type; } // namespace floormat::entities::detail namespace floormat::entities { template constexpr void visit_tuple(F&& fun, Tuple&& tuple) { using Size = std::tuple_size>; if constexpr(Size() > 0) detail::visit_tuple(floormat::forward(fun), floormat::forward(tuple)); } template constexpr bool find_in_tuple(F&& fun, Tuple&& tuple) { using Size = std::tuple_size>; if constexpr(Size() > 0) return detail::find_in_tuple(floormat::forward(fun), floormat::forward(tuple)); else return false; } struct inspect_intent_t {}; struct serialize_intent_t {}; struct report_intent_t {}; template struct entity_accessors; template struct Entity final { static_assert(std::is_same_v>); template struct type final { template R, FieldWriter W, typename... Ts> struct field final : entity_field { constexpr field(StringView field_name, R r, W w, Ts&&... ts) noexcept : entity_field{field_name, r, w, floormat::forward(ts)...} {} }; template R, FieldWriter W, typename... Ts> field(StringView name, R r, W w, Ts&&... ts) -> field; }; }; constexpr inline auto ignored_write = [](O&, T) {}; } // namespace floormat::entities namespace floormat { template class entity_metadata final { static_assert(std::is_same_v>); template static consteval auto erased_helper(const Tuple& tuple, std::index_sequence); public: static constexpr StringView class_name = name_of; static constexpr auto accessors = entities::entity_accessors::accessors(); static constexpr size_t size = std::tuple_size_v>; static constexpr auto erased_accessors = erased_helper(accessors, std::make_index_sequence{}); entity_metadata() = default; }; template template consteval auto entity_metadata::erased_helper(const Tuple& tuple, std::index_sequence) { std::array array { std::get(tuple).erased()..., }; return array; } } // namespace floormat