Skip to content

Commit

Permalink
need refine
Browse files Browse the repository at this point in the history
  • Loading branch information
171930433 committed Jun 20, 2024
1 parent 0042719 commit 6ad4a53
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 44 deletions.
46 changes: 25 additions & 21 deletions include/ylt/standalone/iguana/pb_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,44 +54,48 @@ struct base_impl : public base {
}

std::any get_field_any(std::string_view name) const override {
static constexpr auto map = iguana::get_members_fieldname_map<T>();
static constexpr auto map = iguana::get_members<T>();
static constexpr auto name_no = iguana::get_fieldname_map<T>();

if (map.find(name) == map.end()) {
if (name_no.find(name) == name_no.end()) {
return {};
}

auto const no = name_no.at(name) + 1;

return std::visit(
[&](auto val) {
auto const offset = member_offset((T*)this, val.member_ptr);
auto const ptr = (((char*)this) + offset);
using value_type = typename decltype(val)::value_type;
return std::any{*((value_type*)ptr)};
},
map.at(name));
map.at(no));
}

iguana::detail::field_info get_field_info(std::string_view name) override {
iguana::detail::field_info get_field_info(
std::string_view name) const override {
static constexpr auto map = iguana::get_members<T>();
iguana::detail::field_info info{};
for (auto [no, field] : map) {
if (info.offset > 0) {
break;
}
std::visit(
[&](auto val) {
if (val.field_name == name) {
info.offset = member_offset((T*)this, val.member_ptr);
using value_type = typename decltype(val)::value_type;
static constexpr auto name_no = iguana::get_fieldname_map<T>();

if (name_no.find(name) == name_no.end()) {
return {};
}

auto const no = name_no.at(name) + 1;

return std::visit(
[&](auto val) {
iguana::detail::field_info info;
info.offset = member_offset((T*)this, val.member_ptr);
using value_type = typename decltype(val)::value_type;
#if defined(__clang__) || defined(_MSC_VER) || \
(defined(__GNUC__) && __GNUC__ > 8)
info.type_name = type_string<value_type>();
info.type_name = type_string<value_type>();
#endif
}
},
field);
}

return info;
return info;
},
map.at(no));
}

std::vector<std::string_view> get_fields_name() override {
Expand Down
31 changes: 16 additions & 15 deletions include/ylt/standalone/iguana/reflection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#ifndef IGUANA_REFLECTION_HPP
#define IGUANA_REFLECTION_HPP
#include <any>
#include <array>
#include <functional>
#include <iomanip>
Expand Down Expand Up @@ -564,7 +565,8 @@ struct base {
virtual void to_pb(std::string &str) {}
virtual void from_pb(std::string_view str) {}
virtual std::vector<std::string_view> get_fields_name() { return {}; }
virtual iguana::detail::field_info get_field_info(std::string_view name) {
virtual iguana::detail::field_info get_field_info(
std::string_view name) const {
return {};
}
virtual std::any get_field_any(std::string_view name) const { return {}; }
Expand Down Expand Up @@ -874,13 +876,6 @@ constexpr auto inline get_members_impl(Tuple &&tp, std::index_sequence<I...>) {
T{std::in_place_index<I>, std::move(std::get<I>(tp))}}...};
}

template <typename T, size_t Size, typename Tuple, size_t... I>
constexpr auto inline get_members_fieldname_map_impl(Tuple &&tp, std::index_sequence<I...>) {
return frozen::unordered_map<frozen::string, T, sizeof...(I)>{
{std::get<I>(tp).field_name,
T{std::in_place_index<I>, std::move(std::get<I>(tp))}}...};
}

template <typename T>
constexpr size_t count_variant_size() {
if constexpr (is_variant<T>::value) {
Expand Down Expand Up @@ -919,15 +914,21 @@ constexpr inline auto get_members() {
}
}

template <size_t Size, typename T, size_t... I>
constexpr auto inline get_fieldname_map_impl(T &&arr,
std::index_sequence<I...>) {
return frozen::unordered_map<frozen::string, uint32_t, sizeof...(I)>{
{arr.at(I), uint32_t(I)}...};
}

template <typename T>
constexpr inline auto get_members_fieldname_map() {
constexpr inline auto get_fieldname_map() {
if constexpr (is_reflection_v<T> || is_custom_reflection_v<T>) {
constexpr auto tp = get_members_tuple<T>();
using Tuple = std::decay_t<decltype(tp)>;
using value_type = typename field_type_t<Tuple>::value_type;
constexpr auto Size = tuple_type_count<Tuple>();
return get_members_fieldname_map_impl<value_type, Size>(tp,
std::make_index_sequence<Size>{});
using reflect_members = decltype(iguana_reflect_type(std::declval<T>()));
constexpr size_t Size = reflect_members::size_type::value;

return get_fieldname_map_impl<Size>(reflect_members::arr(),
std::make_index_sequence<Size>{});
}
else {
static_assert(!sizeof(T), "expected reflection or custom reflection");
Expand Down
6 changes: 3 additions & 3 deletions src/struct_pb/examples/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ int main() {

t->set_field_value("name", std::string("tom"));
auto name = t->get_field_value<std::string>("name");
auto const& name2 = t->get_field_any("name");
auto const &name2 = t->get_field_any("name");
assert(name == "tom");
assert(std::any_cast<std::string>(name2) == "tom");
// assert(std::any_cast<std::string>(name2) == "tom");

auto d = dynamic_cast<nest *>(t.get());
assert(d->name == "tom");
Expand All @@ -68,5 +68,5 @@ int main() {
auto &field_name = t->get_field_value<std::string>("name");
auto const &field_name2 = t->get_field_any("name");
assert(field_name == "hello");
assert(std::any_cast<std::string>(field_name2) == "hello");
// assert(std::any_cast<std::string>(field_name2) == "hello");
}
13 changes: 8 additions & 5 deletions src/struct_pb/tests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,11 +568,14 @@ struct inner_struct PUBLIC(inner_struct) {
int z;
};

constexpr inline auto get_members_impl(inner_struct *) {
return std::make_tuple(struct_pb::field_t{&inner_struct::x, 7, "a"},
struct_pb::field_t{&inner_struct::y, 9, "b"},
struct_pb::field_t{&inner_struct::z, 12, "c"});
}
REFLECTION(inner_struct, x, y, z);


// constexpr inline auto get_members_impl(inner_struct *) {
// return std::make_tuple(struct_pb::field_t{&inner_struct::x, 7, "a"},
// struct_pb::field_t{&inner_struct::y, 9, "b"},
// struct_pb::field_t{&inner_struct::z, 12, "c"});
// }
} // namespace my_space

struct test_pb_st1 PUBLIC(test_pb_st1) {
Expand Down

0 comments on commit 6ad4a53

Please sign in to comment.