From 33155f65b50515b85201007828d3f25ca0f30c25 Mon Sep 17 00:00:00 2001 From: gsk <171930433@qq.com> Date: Sun, 23 Jun 2024 22:00:58 +0800 Subject: [PATCH 1/2] =?UTF-8?q?1.=20fix=E5=BD=93=E6=88=90=E5=91=98?= =?UTF-8?q?=E6=98=AFstd::variant=E7=B1=BB=E5=9E=8B=E6=97=B6.get=5Ffields?= =?UTF-8?q?=5Fname=20=E4=BC=9A=E6=9C=89=E9=87=8D=E5=A4=8D=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E5=90=8Dbug=202.=20=E6=B7=BB=E5=8A=A0get=5Ffield=5Fan?= =?UTF-8?q?y=E6=8E=A5=E5=8F=A3,=E5=85=B7=E4=BD=93=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E5=BB=B6=E8=BF=9F=E5=88=B0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/ylt/standalone/iguana/pb_util.hpp | 44 ++++++++++++++++---- include/ylt/standalone/iguana/reflection.hpp | 4 +- src/struct_pb/examples/main.cpp | 22 +++++++++- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/include/ylt/standalone/iguana/pb_util.hpp b/include/ylt/standalone/iguana/pb_util.hpp index b2e467721..67162b625 100644 --- a/include/ylt/standalone/iguana/pb_util.hpp +++ b/include/ylt/standalone/iguana/pb_util.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -76,20 +77,49 @@ struct base_impl : public base { return info; } - std::vector get_fields_name() override { + std::vector get_fields_name() const override { static constexpr auto map = iguana::get_members(); + std::vector vec; - for (auto [no, val] : map) { + std::set sets; + + for (auto const& [no, val] : map) { std::visit( - [&](auto& field) { - vec.push_back(std::string_view(field.field_name.data(), - field.field_name.size())); + [&](auto const& field) { + if (auto it = sets.emplace(field.field_name.data(), + field.field_name.size()); + it.second) { + vec.push_back(*it.first); + } }, val); } return vec; } + std::any get_field_any(std::string_view name) const override { + static constexpr auto map = iguana::get_members(); + std::any result; + + for (auto [no, field] : map) { + if (result.has_value()) { + break; + } + std::visit( + [&](auto val) { + if (val.field_name == name) { + using value_type = typename decltype(val)::value_type; + auto const offset = member_offset((T*)this, val.member_ptr); + auto ptr = (((char*)this) + offset); + result = {*((value_type*)ptr)}; + } + }, + field); + } + + return result; + } + virtual ~base_impl() {} size_t cache_size = 0; @@ -148,8 +178,8 @@ constexpr inline WireType get_wire_type() { } template -constexpr bool is_lenprefix_v = (get_wire_type() == - WireType::LengthDelimeted); +constexpr bool is_lenprefix_v = + (get_wire_type() == WireType::LengthDelimeted); [[nodiscard]] IGUANA_INLINE uint32_t encode_zigzag(int32_t v) { return (static_cast(v) << 1U) ^ diff --git a/include/ylt/standalone/iguana/reflection.hpp b/include/ylt/standalone/iguana/reflection.hpp index cb0ff86a8..f250d8614 100644 --- a/include/ylt/standalone/iguana/reflection.hpp +++ b/include/ylt/standalone/iguana/reflection.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "detail/string_stream.hpp" #include "detail/traits.hpp" @@ -563,7 +564,8 @@ struct field_info { struct base { virtual void to_pb(std::string &str) {} virtual void from_pb(std::string_view str) {} - virtual std::vector get_fields_name() { return {}; } + virtual std::vector get_fields_name() const { return {}; } + virtual std::any get_field_any(std::string_view name) const { return {}; } virtual iguana::detail::field_info get_field_info(std::string_view name) { return {}; } diff --git a/src/struct_pb/examples/main.cpp b/src/struct_pb/examples/main.cpp index 6b631d608..124a0e7d7 100644 --- a/src/struct_pb/examples/main.cpp +++ b/src/struct_pb/examples/main.cpp @@ -18,8 +18,9 @@ struct nest : struct_pb::base_impl { std::string name; my_struct value; int var; + std::variant mv; }; -REFLECTION(nest, name, value, var); +REFLECTION(nest, name, value, var, mv); struct person { int id; @@ -52,9 +53,15 @@ int main() { // dynamic reflection auto t = struct_pb::create_instance("nest"); auto names = t->get_fields_name(); - bool r = (names == std::vector{"name", "value", "var"}); + bool r = (names == std::vector{"name", "value", "var", "mv"}); assert(r); + t->set_field_value("mv", std::variant{1}); + auto mv = t->get_field_value>("mv"); + auto const temp = std::variant{1}; + assert(mv == temp); + + t->set_field_value("name", std::string("tom")); auto name = t->get_field_value("name"); assert(name == "tom"); @@ -65,4 +72,15 @@ int main() { t->set_field_value("name", "hello"); auto &field_name = t->get_field_value("name"); assert(field_name == "hello"); + + // dynamic any + auto const& any_name = t->get_field_any("name"); + assert(std::any_cast(any_name) == "hello"); + + auto const& mvar_any = t->get_field_any("mv"); + auto const& mvar = std::any_cast>(mvar_any); + assert(mvar == temp); + + + } \ No newline at end of file From 3dd52b98a4ce84b8b3c39462e2b0a88962c6439d Mon Sep 17 00:00:00 2001 From: gsk <171930433@qq.com> Date: Mon, 24 Jun 2024 22:10:59 +0800 Subject: [PATCH 2/2] using clang-format-13 format --- include/ylt/standalone/iguana/pb_util.hpp | 4 ++-- include/ylt/standalone/iguana/reflection.hpp | 2 +- src/struct_pb/examples/main.cpp | 13 +++++-------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/include/ylt/standalone/iguana/pb_util.hpp b/include/ylt/standalone/iguana/pb_util.hpp index 67162b625..d1bd3d03b 100644 --- a/include/ylt/standalone/iguana/pb_util.hpp +++ b/include/ylt/standalone/iguana/pb_util.hpp @@ -178,8 +178,8 @@ constexpr inline WireType get_wire_type() { } template -constexpr bool is_lenprefix_v = - (get_wire_type() == WireType::LengthDelimeted); +constexpr bool is_lenprefix_v = (get_wire_type() == + WireType::LengthDelimeted); [[nodiscard]] IGUANA_INLINE uint32_t encode_zigzag(int32_t v) { return (static_cast(v) << 1U) ^ diff --git a/include/ylt/standalone/iguana/reflection.hpp b/include/ylt/standalone/iguana/reflection.hpp index f250d8614..354d8a119 100644 --- a/include/ylt/standalone/iguana/reflection.hpp +++ b/include/ylt/standalone/iguana/reflection.hpp @@ -4,6 +4,7 @@ #ifndef IGUANA_REFLECTION_HPP #define IGUANA_REFLECTION_HPP +#include #include #include #include @@ -17,7 +18,6 @@ #include #include #include -#include #include "detail/string_stream.hpp" #include "detail/traits.hpp" diff --git a/src/struct_pb/examples/main.cpp b/src/struct_pb/examples/main.cpp index 124a0e7d7..e2b4d08ba 100644 --- a/src/struct_pb/examples/main.cpp +++ b/src/struct_pb/examples/main.cpp @@ -18,7 +18,7 @@ struct nest : struct_pb::base_impl { std::string name; my_struct value; int var; - std::variant mv; + std::variant mv; }; REFLECTION(nest, name, value, var, mv); @@ -53,7 +53,8 @@ int main() { // dynamic reflection auto t = struct_pb::create_instance("nest"); auto names = t->get_fields_name(); - bool r = (names == std::vector{"name", "value", "var", "mv"}); + bool r = + (names == std::vector{"name", "value", "var", "mv"}); assert(r); t->set_field_value("mv", std::variant{1}); @@ -61,16 +62,15 @@ int main() { auto const temp = std::variant{1}; assert(mv == temp); - t->set_field_value("name", std::string("tom")); auto name = t->get_field_value("name"); assert(name == "tom"); - auto d = dynamic_cast(t.get()); + auto d = dynamic_cast(t.get()); assert(d->name == "tom"); t->set_field_value("name", "hello"); - auto &field_name = t->get_field_value("name"); + auto& field_name = t->get_field_value("name"); assert(field_name == "hello"); // dynamic any @@ -80,7 +80,4 @@ int main() { auto const& mvar_any = t->get_field_any("mv"); auto const& mvar = std::any_cast>(mvar_any); assert(mvar == temp); - - - } \ No newline at end of file