Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[reflection][improve]for const object #723

Merged
merged 1 commit into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions include/ylt/reflection/member_ptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ struct object_tuple_view_helper<T, 0> {

template <class T>
struct wrapper {
inline static T value;
inline static remove_cvref_t<T> value;
};

template <class T>
inline constexpr T& get_fake_object() noexcept {
return wrapper<T>::value;
inline constexpr remove_cvref_t<T>& get_fake_object() noexcept {
return wrapper<remove_cvref_t<T>>::value;
}

#define RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS( \
Expand Down Expand Up @@ -103,27 +103,29 @@ inline constexpr auto struct_to_tuple() {
}

template <class T>
inline constexpr auto object_to_tuple(T& t) {
inline constexpr auto object_to_tuple(T&& t) {
using type = remove_cvref_t<T>;
if constexpr (is_out_ylt_refl_v<type>) {
return refl_object_to_tuple(t);
return refl_object_to_tuple(std::forward<T>(t));
}
else if constexpr (is_inner_ylt_refl_v<type>) {
return type::refl_object_to_tuple(t);
return type::refl_object_to_tuple(std::forward<T>(t));
}
else {
return internal::tuple_view(t);
return internal::tuple_view(std::forward<T>(t));
}
}

template <class T, typename Visitor, size_t Count = members_count_v<T>>
inline constexpr decltype(auto) visit_members(T&& t, Visitor&& visitor) {
using type = remove_cvref_t<T>;
if constexpr (is_out_ylt_refl_v<type>) {
return refl_visit_members(t, visitor);
return refl_visit_members(std::forward<T>(t),
std::forward<Visitor>(visitor));
}
else if constexpr (is_inner_ylt_refl_v<type>) {
return type::refl_object_to_tuple(t, visitor);
return type::refl_object_to_tuple(std::forward<T>(t),
std::forward<Visitor>(visitor));
}
else {
return internal::tuple_view<Count>(std::forward<T>(t),
Expand Down
66 changes: 42 additions & 24 deletions include/ylt/reflection/user_reflect_macro.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ using member_value_type_t = typename member_traits<T>::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<STRUCT> &t) { \
constexpr std::array<std::string_view, YLT_ARG_COUNT(__VA_ARGS__)> arr{ \
Expand All @@ -46,7 +49,7 @@ using member_value_type_t = typename member_traits<T>::value_type;
}

template <typename T, typename Tuple, typename Visitor>
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) {
Expand All @@ -56,31 +59,46 @@ inline constexpr auto visit_private_fields_impl(T &t, const Tuple &tp,
}

template <typename T, typename Visitor>
inline constexpr auto visit_private_fields(T &t, Visitor &&visitor) {
auto tp = get_private_ptrs(identity<T>{});
return visit_private_fields_impl(t, tp, visitor);
inline constexpr auto visit_private_fields(T &&t, Visitor &&visitor) {
auto tp = get_private_ptrs(
identity<std::remove_const_t<std::remove_reference_t<T>>>{});
return visit_private_fields_impl(std::forward<T>(t), tp, visitor);
}

template <typename T>
inline static decltype(auto) refl_object_to_tuple_impl(T &&t) {
auto tp = get_private_ptrs(
identity<std::remove_const_t<std::remove_reference_t<T>>>{});
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<STRUCT> &t); \
template struct private_visitor<STRUCT, __VA_ARGS__>; \
template <typename Visitor> \
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<STRUCT>{}); \
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<STRUCT> &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<STRUCT> &t); \
template struct private_visitor<STRUCT, __VA_ARGS__>; \
template <typename Visitor> \
inline static constexpr decltype(auto) refl_visit_members( \
STRUCT &t, Visitor &&visitor) { \
return visit_private_fields(t, std::forward<Visitor>(visitor)); \
} \
template <typename Visitor> \
inline static constexpr decltype(auto) refl_visit_members( \
const STRUCT &t, Visitor &&visitor) { \
return visit_private_fields(t, std::forward<Visitor>(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<STRUCT> &t) { \
return (std::size_t)YLT_ARG_COUNT(__VA_ARGS__); \
} \
}

#define YLT_REFL_PRIVATE(STRUCT, ...) \
Expand Down
4 changes: 2 additions & 2 deletions src/reflection/tests/test_reflection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ TEST_CASE("test macros") {
constexpr size_t size5 = members_count_v<dummy_t5>;
static_assert(size5 == 3);

dummy_t5 d5{};
const dummy_t5 d5{};
refl_visit_members(d5, [](auto&... args) {
CHECK(sizeof...(args) == 3);
((std::cout << args << ", "), ...);
Expand Down Expand Up @@ -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<Bank_t>{});
refl_visit_members(bank, [](auto&... args) {
((std::cout << args << " "), ...);
Expand Down
Loading