Skip to content

Commit

Permalink
for const object (#723)
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Jul 22, 2024
1 parent 152f879 commit c2c5c40
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 35 deletions.
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

0 comments on commit c2c5c40

Please sign in to comment.