Skip to content

Commit

Permalink
improve[struct_pb]
Browse files Browse the repository at this point in the history
  • Loading branch information
bbbgan committed May 14, 2024
1 parent 9dd7b1a commit a71d9c0
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 31 deletions.
2 changes: 1 addition & 1 deletion iguana/pb_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ IGUANA_INLINE void from_pb(T& t, std::string_view pb_str) {
uint32_t field_number = key >> 3;

pb_str = pb_str.substr(pos);
constexpr auto map = get_members<T>();
constexpr static auto map = get_members<T>();
auto& member = map.at(field_number);
std::visit(
[&t, &pb_str, wire_type](auto& val) IGUANA__INLINE_LAMBDA {
Expand Down
38 changes: 30 additions & 8 deletions iguana/pb_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,20 +336,39 @@ IGUANA_INLINE size_t numeric_size(T&& t) {
template <size_t key_size, typename T>
IGUANA_INLINE size_t pb_key_value_size(T&& t);

template <size_t field_no, typename T>
IGUANA_INLINE size_t pb_oneof_size(T&& t) {
template <typename Variant, typename T, size_t I>
constexpr inline size_t get_variant_index() {
if constexpr (I == 0) {
static_assert(std::is_same_v<std::variant_alternative_t<0, Variant>, T>,
"Type T is not found in Variant");
return 0;
}
else if constexpr (std::is_same_v<std::variant_alternative_t<I, Variant>,
T>) {
return I;
}
else {
return get_variant_index<Variant, T, I - 1>();
}
}

template <size_t field_no, typename Type>
IGUANA_INLINE size_t pb_oneof_size(Type&& t) {
using T = std::decay_t<Type>;
int len = 0;
std::visit(
[&len](auto&& value) IGUANA__INLINE_LAMBDA {
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 << 3) |
((field_no + offset) << 3) |
static_cast<uint32_t>(get_wire_type<value_type>());
len = pb_key_value_size<variant_uint32_size_constexpr(key)>(
std::forward<value_type>(value));
},
std::forward<T>(t));
std::forward<Type>(t));
return len;
}

Expand All @@ -364,18 +383,21 @@ IGUANA_INLINE size_t pb_key_value_size(T&& t) {
constexpr auto tuple = get_members_tuple<value_type>();
constexpr size_t SIZE = std::tuple_size_v<std::decay_t<decltype(tuple)>>;
for_each_n(
[&len, &t, &tuple](auto i) IGUANA__INLINE_LAMBDA {
[&len, &t](auto i) IGUANA__INLINE_LAMBDA {
constexpr auto tuple = get_members_tuple<value_type>();
using field_type =
std::tuple_element_t<decltype(i)::value,
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);
if constexpr (variant_v<U>) {
if (!std::holds_alternative<typename field_type::sub_type>(val)) {
return;
constexpr auto offset =
get_variant_index<U, typename field_type::sub_type,
std::variant_size_v<U> - 1>();
if constexpr (offset == 0) {
len += pb_oneof_size<value.field_no>(val);
}
len += pb_oneof_size<value.field_no>(val);
}
else {
constexpr uint32_t sub_key =
Expand Down
33 changes: 11 additions & 22 deletions iguana/pb_writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,30 +76,17 @@ IGUANA_INLINE void encode_numeric_field(T t, Stream& out) {
}
}

template <typename Variant, typename T, size_t I>
constexpr size_t get_variant_index() {
if constexpr (I == 0) {
static_assert(std::is_same_v<std::variant_alternative_t<0, Variant>, T>,
"Type T is not found in Variant");
return 0;
}
else if constexpr (std::is_same_v<std::variant_alternative_t<I, Variant>,
T>) {
return I;
}
else {
return get_variant_index<Variant, T, I - 1>();
}
}

template <uint32_t field_no, typename Type, typename Stream>
IGUANA_INLINE void to_pb_oneof(Type&& t, Stream& out) {
using T = std::decay_t<Type>;
std::visit(
[&out](auto&& value) IGUANA__INLINE_LAMBDA {
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 << 3) |
((field_no + offset) << 3) |
static_cast<uint32_t>(get_wire_type<value_type>());
to_pb_impl<key, false>(std::forward<value_type>(value), out);
},
Expand All @@ -123,7 +110,8 @@ IGUANA_INLINE void to_pb_impl(Type&& t, Stream& out) {
constexpr auto tuple = get_members_tuple<T>();
constexpr size_t SIZE = std::tuple_size_v<std::decay_t<decltype(tuple)>>;
for_each_n(
[&t, &out, &tuple](auto i) IGUANA__INLINE_LAMBDA {
[&t, &out](auto i) IGUANA__INLINE_LAMBDA {
constexpr auto tuple = get_members_tuple<T>();
using field_type =
std::tuple_element_t<decltype(i)::value,
std::decay_t<decltype(tuple)>>;
Expand All @@ -132,11 +120,12 @@ IGUANA_INLINE void to_pb_impl(Type&& t, Stream& out) {

using U = typename field_type::value_type;
if constexpr (variant_v<U>) {
if (!std::holds_alternative<typename field_type::sub_type>(val)) {
return;
constexpr auto offset =
get_variant_index<U, typename field_type::sub_type,
std::variant_size_v<U> - 1>();
if constexpr (offset == 0) {
to_pb_oneof<value.field_no>(val, out);
}

to_pb_oneof<value.field_no>(val, out);
}
else {
constexpr uint32_t sub_key =
Expand Down

0 comments on commit a71d9c0

Please sign in to comment.