diff --git a/include/ylt/struct_pack/reflection.hpp b/include/ylt/struct_pack/reflection.hpp index ee82f42873..5c5220e976 100644 --- a/include/ylt/struct_pack/reflection.hpp +++ b/include/ylt/struct_pack/reflection.hpp @@ -750,7 +750,7 @@ namespace detail { if constexpr (user_defined_refl) { return decltype(STRUCT_PACK_FIELD_COUNT(std::declval()))::value; } - if constexpr (tuple_size) { + else if constexpr (tuple_size) { return std::tuple_size::value; } else { @@ -760,6 +760,14 @@ namespace detail { constexpr static auto MaxVisitMembers = 64; + template + constexpr decltype(auto) STRUCT_PACK_INLINE visit_members_by_user_defined_refl(Object &&object, + Visitor &&visitor); + + template + constexpr decltype(auto) STRUCT_PACK_INLINE visit_members_by_structure_binding(Object &&object, + Visitor &&visitor); + template constexpr decltype(auto) STRUCT_PACK_INLINE visit_members(Object &&object, Visitor &&visitor) { diff --git a/include/ylt/struct_pack/struct_pack_impl.hpp b/include/ylt/struct_pack/struct_pack_impl.hpp index e03870e44a..d4ef84d6c6 100644 --- a/include/ylt/struct_pack/struct_pack_impl.hpp +++ b/include/ylt/struct_pack/struct_pack_impl.hpp @@ -1176,7 +1176,7 @@ constexpr size_info inline calculate_one_size(const T &item) { static_assert(id != detail::type_id::type_end_flag); using type = remove_cvref_t; static_assert(!std::is_pointer_v); - size_info ret{.total = 0, .size_cnt = 0, .max_size = 0}; + size_info ret{}; if constexpr (id == type_id::monostate_t) { } else if constexpr (std::is_fundamental_v || std::is_enum_v || @@ -2476,16 +2476,6 @@ class unpacker { } } - template - auto get_container_value_t(const U &) { - if constexpr (map_container) { - return std::pair{}; - } - else { - return typename U::value_type{}; - } - }; - template constexpr struct_pack::errc inline deserialize_one(T &item) { struct_pack::errc code{}; @@ -2595,11 +2585,29 @@ class unpacker { if SP_UNLIKELY (size == 0) { return {}; } - if constexpr (map_container || set_container) { - // value is the element of map/set container. - // if the type is set, then value is set::value_type; - // if the type is map, then value is pair - decltype(get_container_value_t(item)) value; + if constexpr (map_container) { + std::pair + value{}; + if constexpr (is_trivial_serializable::value && + !NotSkip) { + return reader_.ignore(size * sizeof(value)) ? errc{} + : errc::no_buffer_space; + } + else { + for (size_t i = 0; i < size; ++i) { + code = deserialize_one(value); + if SP_UNLIKELY (code != struct_pack::errc{}) { + return code; + } + if constexpr (NotSkip) { + item.emplace(std::move(value)); + // TODO: mapped_type can deserialize without be moved + } + } + } + } + else if constexpr (set_container) { + typename type::value_type value{}; if constexpr (is_trivial_serializable::value && !NotSkip) { return reader_.ignore(size * sizeof(value)) ? errc{}