From b3a4497cfc08877b5fd2e4a2c3ddd9b8983f7821 Mon Sep 17 00:00:00 2001 From: gsk <171930433@qq.com> Date: Fri, 28 Jun 2024 23:03:53 +0800 Subject: [PATCH 1/3] 1. add const to_* but to_pb 2. using auto const& in range for --- iguana/dynamic.hpp | 33 ++++++++++++++++++--------------- iguana/reflection.hpp | 9 +++++---- test/test_pb.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/iguana/dynamic.hpp b/iguana/dynamic.hpp index 14ff6ed5..5c8281bb 100644 --- a/iguana/dynamic.hpp +++ b/iguana/dynamic.hpp @@ -35,9 +35,9 @@ struct base_impl : public base { } } - void to_json(std::string& str) override { + void to_json(std::string& str) const override { if constexpr (ENABLE_FLAG & ENABLE_JSON) { - to_json_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); + to_json_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); } else { throw std::runtime_error("Json Disabled"); @@ -53,9 +53,9 @@ struct base_impl : public base { } } - void to_xml(std::string& str) override { + void to_xml(std::string& str) const override { if constexpr (ENABLE_FLAG & ENABLE_XML) { - to_xml_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); + to_xml_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); } else { throw std::runtime_error("Xml Disabled"); @@ -71,9 +71,9 @@ struct base_impl : public base { } } - void to_yaml(std::string& str) override { + void to_yaml(std::string& str) const override { if constexpr (ENABLE_FLAG & ENABLE_YAML) { - to_yaml_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); + to_yaml_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); } else { throw std::runtime_error("Yaml Disabled"); @@ -89,18 +89,20 @@ struct base_impl : public base { } } - 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(); iguana::detail::field_info info{}; - for (auto& [no, field] : map) { + for (auto const& [no, field] : map) { if (info.offset > 0) { break; } std::visit( - [&](auto val) { + [&](auto const& val) { if (val.field_name == name) { info.offset = member_offset((T*)this, val.member_ptr); - using value_type = typename decltype(val)::value_type; + using value_type = + typename std::remove_reference_t::value_type; #if defined(__clang__) || defined(_MSC_VER) || \ (defined(__GNUC__) && __GNUC__ > 8) info.type_name = type_string(); @@ -136,17 +138,18 @@ struct base_impl : public base { static constexpr auto map = iguana::get_members(); std::any result; - for (auto [no, field] : map) { + for (auto const& [no, field] : map) { if (result.has_value()) { break; } std::visit( - [&](auto val) { + [&](auto const& val) { if (val.field_name == name) { - using value_type = typename decltype(val)::value_type; + using value_type = + typename std::remove_reference_t::value_type; auto const offset = member_offset((T*)this, val.member_ptr); - auto ptr = (((char*)this) + offset); - result = {*((value_type*)ptr)}; + auto ptr = (char*)this + offset; + result = *((value_type*)ptr); } }, field); diff --git a/iguana/reflection.hpp b/iguana/reflection.hpp index d5029d7b..fb05c139 100644 --- a/iguana/reflection.hpp +++ b/iguana/reflection.hpp @@ -564,15 +564,16 @@ struct field_info { struct base { virtual void to_pb(std::string &str) {} virtual void from_pb(std::string_view str) {} - virtual void to_xml(std::string &str) {} + virtual void to_xml(std::string &str) const {} virtual void from_xml(std::string_view str) {} - virtual void to_json(std::string &str) {} + virtual void to_json(std::string &str) const {} virtual void from_json(std::string_view str) {} - virtual void to_yaml(std::string &str) {} + virtual void to_yaml(std::string &str) const {} virtual void from_yaml(std::string_view str) {} 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) { + virtual iguana::detail::field_info get_field_info( + std::string_view name) const { return {}; } diff --git a/test/test_pb.cpp b/test/test_pb.cpp index bf784338..28bb90ff 100644 --- a/test/test_pb.cpp +++ b/test/test_pb.cpp @@ -237,6 +237,18 @@ struct numer_st PUBLIC(numer_st) { }; REFLECTION(numer_st, a, b, c); +struct MyPerson : public iguana::base_impl { + MyPerson() = default; + MyPerson(std::string s, int d) : name(s), age(d) {} + std::string name; + int64_t age; + bool operator==(const MyPerson &other) const { + return name == other.name && age == other.age; + } +}; + +REFLECTION(MyPerson, name, age); + TEST_CASE("test reflection") { { auto t = iguana::create_instance("nest1"); @@ -286,6 +298,19 @@ TEST_CASE("test reflection") { std::any_cast>(mvariant_any); assert(mvariant == temp_variant); } + { + // to_json is an const member_function now + MyPerson const p1{"xiaoming", 10}; + std::string str; + p1.to_json(str); + + // p1.to_pb(str); // compile failed + + MyPerson p2; + p2.from_json(str); + + assert(p1 == p2); + } { auto t = iguana::create_instance("pair_t"); t->set_field_value("x", 12); From 386fb22d2e510480dee0cad297da3a60c470007c Mon Sep 17 00:00:00 2001 From: gsk <171930433@qq.com> Date: Fri, 5 Jul 2024 11:14:12 +0800 Subject: [PATCH 2/3] edit to_pb to const member function --- iguana/dynamic.hpp | 6 +++--- iguana/pb_util.hpp | 9 +++++---- iguana/pb_writer.hpp | 7 ++++--- iguana/reflection.hpp | 3 ++- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/iguana/dynamic.hpp b/iguana/dynamic.hpp index 74cc2da3..4b479b0c 100644 --- a/iguana/dynamic.hpp +++ b/iguana/dynamic.hpp @@ -17,9 +17,9 @@ constexpr inline uint8_t ENABLE_ALL = 0x0F; template struct base_impl : public base { - void to_pb(std::string& str) override { + void to_pb(std::string& str) const override { if constexpr ((ENABLE_FLAG & ENABLE_PB) != 0) { - to_pb_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); + to_pb_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); } else { throw std::runtime_error("Protobuf Disabled"); @@ -160,7 +160,7 @@ struct base_impl : public base { virtual ~base_impl() {} - size_t cache_size = 0; + mutable size_t cache_size = 0; }; IGUANA_INLINE std::shared_ptr create_instance(std::string_view name) { diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index 5fa7365c..9ef8212c 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -73,8 +73,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) ^ @@ -419,6 +419,7 @@ IGUANA_INLINE size_t pb_oneof_size(Type&& t, Arr& size_arr) { int len = 0; std::visit( [&len, &size_arr](auto&& value) IGUANA__INLINE_LAMBDA { + using raw_value_type = decltype(value); using value_type = std::remove_const_t>; constexpr auto offset = @@ -427,7 +428,7 @@ IGUANA_INLINE size_t pb_oneof_size(Type&& t, Arr& size_arr) { ((field_no + offset) << 3) | static_cast(get_wire_type()); len = pb_key_value_size( - std::forward(value), size_arr); + std::forward(value), size_arr); }, std::forward(t)); return len; @@ -454,7 +455,7 @@ IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) { std::decay_t>; constexpr auto value = std::get(tuple); using U = typename field_type::value_type; - auto& val = value.value(t); + auto const& val = value.value(t); if constexpr (variant_v) { constexpr auto offset = get_variant_index; std::visit( [&it, &sz_ptr](auto&& value) IGUANA__INLINE_LAMBDA { + using raw_value_type = decltype(value); using value_type = std::remove_const_t>; constexpr auto offset = @@ -90,7 +91,7 @@ IGUANA_INLINE void to_pb_oneof(Type&& t, It&& it, uint32_t*& sz_ptr) { constexpr uint32_t key = ((field_no + offset) << 3) | static_cast(get_wire_type()); - to_pb_impl(std::forward(value), it, sz_ptr); + to_pb_impl(std::forward(value), it, sz_ptr); }, std::forward(t)); } @@ -449,7 +450,7 @@ IGUANA_INLINE void build_sub_proto(Map& map, std::string_view str_type, } // namespace detail template -IGUANA_INLINE void to_pb(T& t, Stream& out) { +IGUANA_INLINE void to_pb(T const& t, Stream& out) { std::vector size_arr; auto byte_len = detail::pb_key_value_size<0>(t, size_arr); detail::resize(out, byte_len); @@ -491,7 +492,7 @@ IGUANA_INLINE void to_proto_file(Stream& stream, std::string_view ns = "") { #endif template -IGUANA_INLINE void to_pb_adl(iguana_adl_t* p, T& t, Stream& out) { +IGUANA_INLINE void to_pb_adl(iguana_adl_t* p, T const& t, Stream& out) { to_pb(t, out); } diff --git a/iguana/reflection.hpp b/iguana/reflection.hpp index df3ea91c..6bad499c 100644 --- a/iguana/reflection.hpp +++ b/iguana/reflection.hpp @@ -562,7 +562,7 @@ struct field_info { }; struct base { - virtual void to_pb(std::string &str) {} + virtual void to_pb(std::string &str) const {} virtual void from_pb(std::string_view str) {} virtual void to_xml(std::string &str) const {} virtual void from_xml(std::string_view str) {} @@ -803,6 +803,7 @@ struct field_t { uint32_t field_no; auto &value(owner_type &value) const { return value.*member_ptr; } + auto const &value(owner_type const &value) const { return value.*member_ptr; } }; template From 96496e75b2b0fad4f5029e7dc1e65df6b3e432df Mon Sep 17 00:00:00 2001 From: gsk <171930433@qq.com> Date: Fri, 5 Jul 2024 11:25:24 +0800 Subject: [PATCH 3/3] clang format --- iguana/pb_util.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index 9ef8212c..27bc9a89 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -73,8 +73,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) ^