diff --git a/src/mpp/Dec.hpp b/src/mpp/Dec.hpp index 79bc00d8e..f65cfbf41 100644 --- a/src/mpp/Dec.hpp +++ b/src/mpp/Dec.hpp @@ -1172,6 +1172,20 @@ bool jump_read_key(BUF& buf, T... t) return jump_find_key(val, IS, buf, t...); } +template +struct is_object_readable_by_value : std::false_type {}; + +template +struct is_object_readable_by_value::is_readable_by_value && + std::is_assignable_v(std::declval()))>, bool>::type> : std::true_type {}; + +template +constexpr bool is_object_readable_by_value_v = is_object_readable_by_value::value; + template bool jump_read_optional(BUF& buf, T... t) @@ -1184,10 +1198,15 @@ bool jump_read_optional(BUF& buf, T... t) dst.reset(); return decode_next(buf, t...); } else { - if (!dst.has_value()) - dst.emplace(); - using NEXT_PATH = path_push_t; - return decode_impl(buf, t...); + if constexpr (is_object_readable_by_value_v) { + dst = read_value(buf); + return decode_next(buf, t...); + } else { + if (!dst.has_value()) + dst.emplace(); + using NEXT_PATH = path_push_t; + return decode_impl(buf, t...); + } } } @@ -1219,7 +1238,12 @@ bool jump_read_variant(BUF& buf, T... t) auto&& dst = unwrap(path_resolve(PATH{}, t...)); using dst_t = std::remove_reference_t; static_assert(tnt::is_variant_v); - return jump_read_variant_impl<0, FAMILY, SUBRULE, PATH>(buf, t...); + if constexpr (is_object_readable_by_value()) { + dst = read_value(buf); + return decode_next(buf, t...); + } else { + return jump_read_variant_impl<0, FAMILY, SUBRULE, PATH>(buf, t...); + } } template