From 64cb198514bc7c5ae41035b68294a7a4a7b003c6 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 22 Jul 2024 10:38:36 +0800 Subject: [PATCH] for const object --- include/ylt/reflection/member_ptr.hpp | 20 +++--- include/ylt/reflection/user_reflect_macro.hpp | 66 ++++++++++++------- src/reflection/tests/test_reflection.cpp | 4 +- 3 files changed, 55 insertions(+), 35 deletions(-) diff --git a/include/ylt/reflection/member_ptr.hpp b/include/ylt/reflection/member_ptr.hpp index 2499958ce..2a847d8b5 100644 --- a/include/ylt/reflection/member_ptr.hpp +++ b/include/ylt/reflection/member_ptr.hpp @@ -49,12 +49,12 @@ struct object_tuple_view_helper { template struct wrapper { - inline static T value; + inline static remove_cvref_t value; }; template -inline constexpr T& get_fake_object() noexcept { - return wrapper::value; +inline constexpr remove_cvref_t& get_fake_object() noexcept { + return wrapper>::value; } #define RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS( \ @@ -103,16 +103,16 @@ inline constexpr auto struct_to_tuple() { } template -inline constexpr auto object_to_tuple(T& t) { +inline constexpr auto object_to_tuple(T&& t) { using type = remove_cvref_t; if constexpr (is_out_ylt_refl_v) { - return refl_object_to_tuple(t); + return refl_object_to_tuple(std::forward(t)); } else if constexpr (is_inner_ylt_refl_v) { - return type::refl_object_to_tuple(t); + return type::refl_object_to_tuple(std::forward(t)); } else { - return internal::tuple_view(t); + return internal::tuple_view(std::forward(t)); } } @@ -120,10 +120,12 @@ template > inline constexpr decltype(auto) visit_members(T&& t, Visitor&& visitor) { using type = remove_cvref_t; if constexpr (is_out_ylt_refl_v) { - return refl_visit_members(t, visitor); + return refl_visit_members(std::forward(t), + std::forward(visitor)); } else if constexpr (is_inner_ylt_refl_v) { - return type::refl_object_to_tuple(t, visitor); + return type::refl_object_to_tuple(std::forward(t), + std::forward(visitor)); } else { return internal::tuple_view(std::forward(t), diff --git a/include/ylt/reflection/user_reflect_macro.hpp b/include/ylt/reflection/user_reflect_macro.hpp index 52b2115a6..9aeee665c 100644 --- a/include/ylt/reflection/user_reflect_macro.hpp +++ b/include/ylt/reflection/user_reflect_macro.hpp @@ -34,6 +34,9 @@ using member_value_type_t = typename member_traits::value_type; inline static decltype(auto) refl_object_to_tuple(STRUCT &t) { \ return std::tie(WRAP_ARGS(CONCAT_MEMBER, t, __VA_ARGS__)); \ } \ + inline static decltype(auto) refl_object_to_tuple(const STRUCT &t) { \ + return std::tie(WRAP_ARGS(CONCAT_MEMBER, t, __VA_ARGS__)); \ + } \ inline static constexpr decltype(auto) refl_member_names( \ const ylt::reflection::identity &t) { \ constexpr std::array arr{ \ @@ -46,7 +49,7 @@ using member_value_type_t = typename member_traits::value_type; } template -inline constexpr auto visit_private_fields_impl(T &t, const Tuple &tp, +inline constexpr auto visit_private_fields_impl(T &&t, const Tuple &tp, Visitor &&visitor) { return std::apply( [&](auto... args) { @@ -56,31 +59,46 @@ inline constexpr auto visit_private_fields_impl(T &t, const Tuple &tp, } template -inline constexpr auto visit_private_fields(T &t, Visitor &&visitor) { - auto tp = get_private_ptrs(identity{}); - return visit_private_fields_impl(t, tp, visitor); +inline constexpr auto visit_private_fields(T &&t, Visitor &&visitor) { + auto tp = get_private_ptrs( + identity>>{}); + return visit_private_fields_impl(std::forward(t), tp, visitor); +} + +template +inline static decltype(auto) refl_object_to_tuple_impl(T &&t) { + auto tp = get_private_ptrs( + identity>>{}); + auto to_ref = [&t](auto... fields) { + return std::tie(t.*fields...); + }; + return std::apply(to_ref, tp); } -#define YLT_REFL_PRIVATE_(STRUCT, ...) \ - namespace ylt::reflection { \ - inline constexpr auto get_private_ptrs(const identity &t); \ - template struct private_visitor; \ - template \ - inline static constexpr decltype(auto) refl_visit_members( \ - STRUCT &t, Visitor &&visitor) { \ - return visit_private_fields(t, visitor); \ - } \ - inline static decltype(auto) refl_object_to_tuple(STRUCT &t) { \ - auto tp = get_private_ptrs(identity{}); \ - auto to_ref = [&t](auto... fields) { \ - return std::tie(t.*fields...); \ - }; \ - return std::apply(to_ref, tp); \ - } \ - inline static constexpr std::size_t refl_member_count( \ - const ylt::reflection::identity &t) { \ - return (std::size_t)YLT_ARG_COUNT(__VA_ARGS__); \ - } \ +#define YLT_REFL_PRIVATE_(STRUCT, ...) \ + namespace ylt::reflection { \ + inline constexpr auto get_private_ptrs(const identity &t); \ + template struct private_visitor; \ + template \ + inline static constexpr decltype(auto) refl_visit_members( \ + STRUCT &t, Visitor &&visitor) { \ + return visit_private_fields(t, std::forward(visitor)); \ + } \ + template \ + inline static constexpr decltype(auto) refl_visit_members( \ + const STRUCT &t, Visitor &&visitor) { \ + return visit_private_fields(t, std::forward(visitor)); \ + } \ + inline static decltype(auto) refl_object_to_tuple(STRUCT &t) { \ + return refl_object_to_tuple_impl(t); \ + } \ + inline static decltype(auto) refl_object_to_tuple(const STRUCT &t) { \ + return refl_object_to_tuple_impl(t); \ + } \ + inline static constexpr std::size_t refl_member_count( \ + const ylt::reflection::identity &t) { \ + return (std::size_t)YLT_ARG_COUNT(__VA_ARGS__); \ + } \ } #define YLT_REFL_PRIVATE(STRUCT, ...) \ diff --git a/src/reflection/tests/test_reflection.cpp b/src/reflection/tests/test_reflection.cpp index b97e09330..c33116f23 100644 --- a/src/reflection/tests/test_reflection.cpp +++ b/src/reflection/tests/test_reflection.cpp @@ -333,7 +333,7 @@ TEST_CASE("test macros") { constexpr size_t size5 = members_count_v; static_assert(size5 == 3); - dummy_t5 d5{}; + const dummy_t5 d5{}; refl_visit_members(d5, [](auto&... args) { CHECK(sizeof...(args) == 3); ((std::cout << args << ", "), ...); @@ -431,7 +431,7 @@ class private_struct { YLT_REFL_PRIVATE(private_struct, a, b); TEST_CASE("test visit private") { - Bank_t bank(1, "ok"); + const Bank_t bank(1, "ok"); constexpr auto tp = get_private_ptrs(identity{}); refl_visit_members(bank, [](auto&... args) { ((std::cout << args << " "), ...);