Skip to content

Commit

Permalink
Merge pull request #290 from 171930433/gsk/add_const
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Jul 5, 2024
2 parents c5efa3a + 96496e7 commit 3795450
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 28 deletions.
39 changes: 21 additions & 18 deletions iguana/dynamic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ constexpr inline uint8_t ENABLE_ALL = 0x0F;

template <typename T, uint8_t ENABLE_FLAG = ENABLE_PB>
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<T*>(this)), str);
to_pb_adl((iguana_adl_t*)nullptr, *(static_cast<T const*>(this)), str);
}
else {
throw std::runtime_error("Protobuf Disabled");
Expand All @@ -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) != 0) {
to_json_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
to_json_adl((iguana_adl_t*)nullptr, *(static_cast<T const*>(this)), str);
}
else {
throw std::runtime_error("Json Disabled");
Expand All @@ -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) != 0) {
to_xml_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
to_xml_adl((iguana_adl_t*)nullptr, *(static_cast<T const*>(this)), str);
}
else {
throw std::runtime_error("Xml Disabled");
Expand All @@ -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) != 0) {
to_yaml_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
to_yaml_adl((iguana_adl_t*)nullptr, *(static_cast<T const*>(this)), str);
}
else {
throw std::runtime_error("Yaml Disabled");
Expand All @@ -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<T>();
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<decltype(val)>::value_type;
#if defined(__clang__) || defined(_MSC_VER) || \
(defined(__GNUC__) && __GNUC__ > 8)
info.type_name = type_string<value_type>();
Expand Down Expand Up @@ -136,17 +138,18 @@ struct base_impl : public base {
static constexpr auto map = iguana::get_members<T>();
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<decltype(val)>::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);
Expand All @@ -157,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<base> create_instance(std::string_view name) {
Expand Down
5 changes: 3 additions & 2 deletions iguana/pb_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::remove_reference_t<decltype(value)>>;
constexpr auto offset =
Expand All @@ -427,7 +428,7 @@ IGUANA_INLINE size_t pb_oneof_size(Type&& t, Arr& size_arr) {
((field_no + offset) << 3) |
static_cast<uint32_t>(get_wire_type<value_type>());
len = pb_key_value_size<variant_uint32_size_constexpr(key), false>(
std::forward<value_type>(value), size_arr);
std::forward<raw_value_type>(value), size_arr);
},
std::forward<Type>(t));
return len;
Expand All @@ -454,7 +455,7 @@ IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) {
std::decay_t<decltype(tuple)>>;
constexpr auto value = std::get<decltype(i)::value>(tuple);
using U = typename field_type::value_type;
auto& val = value.value(t);
auto const& val = value.value(t);
if constexpr (variant_v<U>) {
constexpr auto offset =
get_variant_index<U, typename field_type::sub_type,
Expand Down
7 changes: 4 additions & 3 deletions iguana/pb_writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,15 @@ IGUANA_INLINE void to_pb_oneof(Type&& t, It&& it, uint32_t*& sz_ptr) {
using T = std::decay_t<Type>;
std::visit(
[&it, &sz_ptr](auto&& value) IGUANA__INLINE_LAMBDA {
using raw_value_type = decltype(value);
using value_type =
std::remove_const_t<std::remove_reference_t<decltype(value)>>;
constexpr auto offset =
get_variant_index<T, value_type, std::variant_size_v<T> - 1>();
constexpr uint32_t key =
((field_no + offset) << 3) |
static_cast<uint32_t>(get_wire_type<value_type>());
to_pb_impl<key, false>(std::forward<value_type>(value), it, sz_ptr);
to_pb_impl<key, false>(std::forward<raw_value_type>(value), it, sz_ptr);
},
std::forward<Type>(t));
}
Expand Down Expand Up @@ -449,7 +450,7 @@ IGUANA_INLINE void build_sub_proto(Map& map, std::string_view str_type,
} // namespace detail

template <typename T, typename Stream>
IGUANA_INLINE void to_pb(T& t, Stream& out) {
IGUANA_INLINE void to_pb(T const& t, Stream& out) {
std::vector<uint32_t> size_arr;
auto byte_len = detail::pb_key_value_size<0>(t, size_arr);
detail::resize(out, byte_len);
Expand Down Expand Up @@ -491,7 +492,7 @@ IGUANA_INLINE void to_proto_file(Stream& stream, std::string_view ns = "") {
#endif

template <typename T, typename Stream>
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);
}

Expand Down
12 changes: 7 additions & 5 deletions iguana/reflection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,17 +562,18 @@ 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) {}
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<std::string_view> 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 {};
}

Expand Down Expand Up @@ -802,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 <typename T>
Expand Down
24 changes: 24 additions & 0 deletions test/test_pb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,17 @@ struct numer_st PUBLIC(numer_st) {
};
REFLECTION(numer_st, a, b, c);

struct MyPerson : public iguana::base_impl<MyPerson, iguana::ENABLE_JSON> {
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);
struct person PUBLIC(person) {
person() = default;
person(int32_t a, std::string b, int c, double d)
Expand Down Expand Up @@ -386,6 +397,19 @@ TEST_CASE("test reflection") {
std::any_cast<std::variant<int, double>>(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);
Expand Down

0 comments on commit 3795450

Please sign in to comment.