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);