From 6901a2d6a888a6f2dd9c1f5b8507217cb449de6e Mon Sep 17 00:00:00 2001 From: "Zezheng.Li" Date: Mon, 31 Jul 2023 17:43:32 +0800 Subject: [PATCH] fix explicit template paramters in lamdba --- include/ylt/struct_pack/reflection.hpp | 37 +++--- include/ylt/struct_pack/struct_pack_impl.hpp | 113 +++++++++++------- .../test_pragma_pack_and_alignas_mix.cpp | 6 +- 3 files changed, 89 insertions(+), 67 deletions(-) diff --git a/include/ylt/struct_pack/reflection.hpp b/include/ylt/struct_pack/reflection.hpp index f41210b2ab..51734379db 100644 --- a/include/ylt/struct_pack/reflection.hpp +++ b/include/ylt/struct_pack/reflection.hpp @@ -54,14 +54,19 @@ using remove_cvref_t = std::remove_cv_t>; template constexpr auto get_types(); +template typename Op, + typename... Contexts, std::size_t... I> +constexpr void for_each_impl(std::index_sequence, Contexts &...contexts) { + using type = decltype(get_types()); + (Op, I>{}(contexts...), ...); +} + template typename Op, typename... Contexts> constexpr void for_each(Contexts &...contexts) { using type = decltype(get_types()); - [&](std::index_sequence) { - (Op, I>{}(contexts...), ...); - } - (std::make_index_sequence>()); + for_each_impl(std::make_index_sequence>(), + contexts...); } template @@ -611,6 +616,12 @@ template template struct is_trivial_serializable { private: + template + static constexpr bool class_visit_helper(std::index_sequence) { + return (is_trivial_serializable, + ignore_compatible_field>::value && + ...); + } static constexpr bool solve() { if constexpr (is_compatible_v || is_trivial_view_v) { return ignore_compatible_field; @@ -648,23 +659,11 @@ template ignore_compatible_field>::value; } else if constexpr (is_trivial_tuple) { - return [](std::index_sequence) - CONSTEXPR_INLINE_LAMBDA { - return (is_trivial_serializable, - ignore_compatible_field>::value && - ...); - } - (std::make_index_sequence>{}); + return class_visit_helper(std::make_index_sequence>{}); } else if constexpr (std::is_class_v) { - using T_ = decltype(get_types()); - return [](std::index_sequence) - CONSTEXPR_INLINE_LAMBDA { - return (is_trivial_serializable, - ignore_compatible_field>::value && - ...); - } - (std::make_index_sequence>{}); + using U = decltype(get_types()); + return class_visit_helper(std::make_index_sequence>{}); } else return false; diff --git a/include/ylt/struct_pack/struct_pack_impl.hpp b/include/ylt/struct_pack/struct_pack_impl.hpp index 1f9ac0bca7..d74c4ac22e 100644 --- a/include/ylt/struct_pack/struct_pack_impl.hpp +++ b/include/ylt/struct_pack/struct_pack_impl.hpp @@ -257,9 +257,8 @@ constexpr auto get_types() { else if constexpr (std::is_class_v) { // clang-format off return visit_members( - declval(), [](Args && - ...) constexpr { - return declval...>>(); + declval(), [](auto &&... args) constexpr { + return declval...>>(); }); // clang-format on } @@ -664,16 +663,20 @@ constexpr decltype(auto) get_size_literal() { "The size is too large."); } } -template -constexpr std::size_t check_circle() { + +template +constexpr std::size_t check_circle_impl(std::index_sequence) { using types_tuple = std::tuple; + return (std::max)( + {(std::is_same_v, Arg> ? I + 1 + : 0)...}); +} + +template +constexpr std::size_t check_circle() { if constexpr (sizeof...(ParentArgs)) { - return [](std::index_sequence) { - return (std::max)( - {(std::is_same_v, arg> ? I + 1 - : 0)...}); - } - (std::make_index_sequence()); + return check_circle_impl( + std::make_index_sequence()); } else { return 0; @@ -726,18 +729,21 @@ constexpr std::size_t alignment_impl(); template constexpr std::size_t alignment_v = alignment_impl(); +template +constexpr std::size_t default_alignment_helper(std::index_sequence) { + return (std::max)( + {(is_compatible_v>> + ? std::size_t{0} + : align::alignment_v< + remove_cvref_t>>)...}); +} + template constexpr std::size_t default_alignment() { if constexpr (!is_trivial_serializable::value && !is_trivial_view_v) { using type = decltype(get_types()); - return [&](std::index_sequence) constexpr { - return (std::max)( - {(is_compatible_v>> - ? std::size_t{0} - : align::alignment_v< - remove_cvref_t>>)...}); - } - (std::make_index_sequence>()); + return default_alignment_helper( + std::make_index_sequence>()); } else if constexpr (is_trivial_view_v) { return std::alignment_of_v; @@ -752,6 +758,15 @@ constexpr std::size_t default_alignment_v = default_alignment(); template constexpr std::size_t alignment_impl(); +template +constexpr std::size_t pack_alignment_impl_helper(std::index_sequence) { + return (std::max)( + {(is_compatible_v>> + ? std::size_t{0} + : align::alignment_v< + remove_cvref_t>>)...}); +} + template constexpr std::size_t pack_alignment_impl() { static_assert(std::is_class_v); @@ -761,14 +776,8 @@ constexpr std::size_t pack_alignment_impl() { ret == 16); if constexpr (ret == 0) { using type = decltype(get_types()); - return [&](std::index_sequence) constexpr { - return (std::max)( - {(is_compatible_v>> - ? std::size_t{0} - : align::alignment_v< - remove_cvref_t>>)...}); - } - (std::make_index_sequence>()); + return pack_alignment_impl_helper( + std::make_index_sequence>()); } else { return ret; @@ -1633,6 +1642,15 @@ class packer { packer(const packer &) = delete; packer &operator=(const packer &) = delete; + template + void serialize_expand_compatible_helper(const T &t, std::index_sequence, + const Args &...args) { + using Type = get_args_type; + (serialize_many[I]>(t, args...), + ...); + } + template STRUCT_PACK_INLINE void serialize(const T &t, const Args &...args) { serialize_metainfo(); @@ -1640,12 +1658,8 @@ class packer { using Type = get_args_type; if constexpr (serialize_static_config::has_compatible) { constexpr std::size_t sz = compatible_version_number.size(); - [&](std::index_sequence) { - (serialize_many[I]>(t, - args...), - ...); - } - (std::make_index_sequence{}); + return serialize_expand_compatible_helper( + t, std::make_index_sequence{}, args...); } } @@ -2512,7 +2526,7 @@ class unpacker { } } else if constexpr (unique_ptr) { - bool has_value; + bool has_value{}; if SP_UNLIKELY (!reader_.read((char *)&has_value, sizeof(bool))) { return struct_pack::errc::no_buffer_space; } @@ -2679,7 +2693,7 @@ class unpacker { item); } else if constexpr (optional || expected) { - bool has_value; + bool has_value{}; if SP_UNLIKELY (!reader_.read((char *)&has_value, sizeof(bool))) { return struct_pack::errc::no_buffer_space; } @@ -2704,7 +2718,7 @@ class unpacker { } } else if constexpr (is_variant_v) { - uint8_t index; + uint8_t index{}; if SP_UNLIKELY (!reader_.read((char *)&index, sizeof(index))) { return struct_pack::errc::no_buffer_space; } @@ -2774,7 +2788,7 @@ class unpacker { } return struct_pack::errc::no_buffer_space; } - bool has_value; + bool has_value{}; if SP_UNLIKELY (!reader_.read((char *)&has_value, sizeof(bool))) { return struct_pack::errc::no_buffer_space; } @@ -2907,18 +2921,25 @@ class unpacker { return std::get(std::forward_as_tuple(ts...)); } + template + STRUCT_PACK_INLINE constexpr void for_each_helper(struct_pack::errc &code, + FieldType &field, + std::index_sequence, + Args &&...items) { + [[maybe_unused]] auto result = + (!set_value(code, field, + get_nth(items...)) && + ...); + } + template - STRUCT_PACK_INLINE constexpr decltype(auto) for_each(FieldType &field, - Args &&...items) { + STRUCT_PACK_INLINE constexpr struct_pack::errc for_each(FieldType &field, + Args &&...items) { struct_pack::errc code{}; - [&](std::index_sequence) CONSTEXPR_INLINE_LAMBDA { - [[maybe_unused]] auto result = - (!set_value( - code, field, get_nth(items...)) && - ...); - } - (std::make_index_sequence{}); + for_each_helper( + code, field, std::make_index_sequence(), items...); return code; } diff --git a/src/struct_pack/tests/test_pragma_pack_and_alignas_mix.cpp b/src/struct_pack/tests/test_pragma_pack_and_alignas_mix.cpp index 1d95fabfba..25c54241ba 100644 --- a/src/struct_pack/tests/test_pragma_pack_and_alignas_mix.cpp +++ b/src/struct_pack/tests/test_pragma_pack_and_alignas_mix.cpp @@ -325,14 +325,16 @@ TEST_CASE("testing mix and compatible nested") { auto result = struct_pack::deserialize< test_pragma_pack_and_alignas_and_compatible_mix::dummy_2_4_v2>(buffer); CHECK(result.has_value() == true); - CHECK(result == v2); + auto val=result.value(); + CHECK(val == v2); } { auto buffer = struct_pack::serialize(v2); auto result = struct_pack::deserialize< test_pragma_pack_and_alignas_and_compatible_mix::dummy_2_4_v1>(buffer); CHECK(result.has_value() == true); - CHECK(result == v1); + auto val=result.value(); + CHECK(val == v1); } }