IGUANA_INLINE size_t pb_key_value_size()

in include/ylt/standalone/iguana/pb_util.hpp [444:542]


IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) {
  using T = std::remove_const_t<std::remove_reference_t<Type>>;
  if constexpr (ylt_refletable_v<T> || is_custom_reflection_v<T>) {
    size_t len = 0;
    static auto tuple = get_pb_members_tuple(std::forward<Type>(t));
    constexpr size_t SIZE = std::tuple_size_v<std::decay_t<decltype(tuple)>>;
    size_t pre_index = -1;
    if constexpr (!inherits_from_base_v<T> && key_size != 0) {
      pre_index = size_arr.size();
      size_arr.push_back(0);  // placeholder
    }
    for_each_n(
        [&len, &t, &size_arr](auto i) IGUANA__INLINE_LAMBDA {
          using field_type =
              std::tuple_element_t<decltype(i)::value,
                                   std::decay_t<decltype(tuple)>>;
          auto value = std::get<decltype(i)::value>(tuple);
          using U = typename field_type::value_type;
          using sub_type = typename field_type::sub_type;
          auto& val = value.value(t);
          if constexpr (variant_v<U>) {
            constexpr auto offset =
                get_variant_index<U, sub_type, std::variant_size_v<U> - 1>();
            if constexpr (offset == 0) {
              len += pb_oneof_size<value.field_no>(val, size_arr);
            }
          }
          else {
            constexpr uint32_t sub_key =
                (value.field_no << 3) |
                static_cast<uint32_t>(get_wire_type<U>());
            constexpr auto sub_keysize = variant_uint32_size_constexpr(sub_key);
            len += pb_key_value_size<sub_keysize>(val, size_arr);
          }
        },
        std::make_index_sequence<SIZE>{});
    if constexpr (inherits_from_base_v<T>) {
      t.cache_size = len;
    }
    else if constexpr (key_size != 0) {
      size_arr[pre_index] = len;
    }
    if constexpr (key_size == 0) {
      // for top level
      return len;
    }
    else {
      if (len == 0) {
        // equals key_size  + variant_uint32_size(len)
        return key_size + 1;
      }
      else {
        return key_size + variant_uint32_size(static_cast<uint32_t>(len)) + len;
      }
    }
  }
  else if constexpr (is_sequence_container<T>::value) {
    using item_type = typename T::value_type;
    size_t len = 0;
    if constexpr (is_lenprefix_v<item_type>) {
      for (auto& item : t) {
        len += pb_key_value_size<key_size, false>(item, size_arr);
      }
      return len;
    }
    else {
      for (auto& item : t) {
        // here 0 to get pakced size, and item must be numeric
        len += str_numeric_size<0, false>(item);
      }
      if (len == 0) {
        return 0;
      }
      else {
        return key_size + variant_uint32_size(static_cast<uint32_t>(len)) + len;
      }
    }
  }
  else if constexpr (is_map_container<T>::value) {
    size_t len = 0;
    for (auto& [k, v] : t) {
      // the key_size of  k and v  is constant 1
      auto kv_len = pb_key_value_size<1, false>(k, size_arr) +
                    pb_key_value_size<1, false>(v, size_arr);
      len += key_size + variant_uint32_size(static_cast<uint32_t>(kv_len)) +
             kv_len;
    }
    return len;
  }
  else if constexpr (optional_v<T>) {
    if (!t.has_value()) {
      return 0;
    }
    return pb_key_value_size<key_size, omit_default_val>(*t, size_arr);
  }
  else {
    return str_numeric_size<key_size, omit_default_val>(t);
  }
}