diff --git a/CMakeLists.txt b/CMakeLists.txt index 61c472847..11552676a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,5 +26,5 @@ include(cmake/install.cmake) include(cmake/config.cmake) # add project's source such as unit test, example & benchmark include(cmake/subdir.cmake) - +include(cmake/platform.cmake) diff --git a/cmake/platform.cmake b/cmake/platform.cmake new file mode 100644 index 000000000..0f07a651b --- /dev/null +++ b/cmake/platform.cmake @@ -0,0 +1,15 @@ +# --------------------- Gcc +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines") + #-ftree-slp-vectorize with coroutine cause link error. disable it util gcc fix. + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-tree-slp-vectorize") +endif() +# --------------------- Clang + +# --------------------- Msvc +# Resolves C1128 complained by MSVC: number of sections exceeded object file format limit: compile with /bigobj. +add_compile_options("$<$:/bigobj>") +# Resolves C4737 complained by MSVC: C4737: Unable to perform required tail call. Performance may be degraded. "Release-Type only" +if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") +add_compile_options("$<$:/EHa>") +endif() \ No newline at end of file diff --git a/include/ylt/struct_pack/reflection.hpp b/include/ylt/struct_pack/reflection.hpp index 8cb0ffc93..0f787b796 100644 --- a/include/ylt/struct_pack/reflection.hpp +++ b/include/ylt/struct_pack/reflection.hpp @@ -197,6 +197,9 @@ namespace detail { sizeof(std::tuple_size>); }; + template + concept user_defined_refl = std::is_same_v())),Type&>; + template concept tuple_size = requires(Type tuple) { sizeof(std::tuple_size>); @@ -329,6 +332,9 @@ namespace detail { else if constexpr (!pair && tuple && !is_trivial_tuple) { return false; } + else if constexpr (user_defined_refl) { + return false; + } else if constexpr (container || optional || variant || unique_ptr || expected || container_adapter || varint_t) { @@ -457,16 +463,171 @@ namespace detail { constexpr decltype(auto) STRUCT_PACK_INLINE visit_members(auto &&object, auto &&visitor) { using type = std::remove_cvref_t; + if constexpr (user_defined_refl) { + return visit_members_by_user_defined_refl(object,visitor); + } + else { + return visit_members_by_structure_binding(object,visitor); + } + } + + constexpr decltype(auto) STRUCT_PACK_INLINE visit_members_by_user_defined_refl(auto &&object, + auto &&visitor) { + using type = std::remove_cvref_t; + constexpr auto Count = decltype(STRUCT_PACK_FIELD_COUNT(object))::value; + + static_assert(Count <= MaxVisitMembers, "exceed max visit members"); + if constexpr (Count >= 0) { + if constexpr (Count==1) { return visitor(STRUCT_PACK_GET_0(object)); + } + else if constexpr (Count==2) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object)); + } + else if constexpr (Count==3) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object)); + } + else if constexpr (Count==4) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object)); + } + else if constexpr (Count==5) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object)); + } + else if constexpr (Count==6) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object)); + } + else if constexpr (Count==7) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object)); + } + else if constexpr (Count==8) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object)); + } + else if constexpr (Count==9) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object)); + } + else if constexpr (Count==10) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object)); + } + else if constexpr (Count==11) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object)); + } + else if constexpr (Count==12) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object)); + } + else if constexpr (Count==13) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object)); + } + else if constexpr (Count==14) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object)); + } + else if constexpr (Count==15) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object)); + } + else if constexpr (Count==16) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object)); + } + else if constexpr (Count==17) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object)); + } + else if constexpr (Count==18) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object)); + } + else if constexpr (Count==19) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object)); + } + else if constexpr (Count==20) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object)); + } + else if constexpr (Count==21) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object)); + } + else if constexpr (Count==22) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object)); + } + else if constexpr (Count==23) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object)); + } + else if constexpr (Count==24) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object)); + } + else if constexpr (Count==25) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object)); + } + else if constexpr (Count==26) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object)); + } + else if constexpr (Count==27) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object)); + } + else if constexpr (Count==28) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object)); + } + else if constexpr (Count==29) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object)); + } + else if constexpr (Count==30) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object)); + } + else if constexpr (Count==31) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object)); + } + else if constexpr (Count==32) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object)); + } + else if constexpr (Count==33) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object)); + } + else if constexpr (Count==34) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object)); + } + else if constexpr (Count==35) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object)); + } + else if constexpr (Count==36) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object)); + } + else if constexpr (Count==37) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object)); + } + else if constexpr (Count==38) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object)); + } + else if constexpr (Count==39) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object)); + } + else if constexpr (Count==40) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object)); + } + else if constexpr (Count==41) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object)); + } + else if constexpr (Count==42) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object)); + } + else if constexpr (Count==43) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object)); + } + else if constexpr (Count==44) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object)); + } + else if constexpr (Count==45) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object)); + } + else if constexpr (Count==46) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object)); + } + else if constexpr (Count==47) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object)); + } + else if constexpr (Count==48) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object)); + } + else if constexpr (Count==49) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object)); + } + else if constexpr (Count==50) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object)); + } + else if constexpr (Count==51) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object)); + } + else if constexpr (Count==52) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object)); + } + else if constexpr (Count==53) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object)); + } + else if constexpr (Count==54) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object)); + } + else if constexpr (Count==55) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object)); + } + else if constexpr (Count==56) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object)); + } + else if constexpr (Count==57) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object)); + } + else if constexpr (Count==58) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object)); + } + else if constexpr (Count==59) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object)); + } + else if constexpr (Count==60) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object),STRUCT_PACK_GET_59(object)); + } + else if constexpr (Count==61) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object),STRUCT_PACK_GET_59(object),STRUCT_PACK_GET_60(object)); + } + else if constexpr (Count==62) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object),STRUCT_PACK_GET_59(object),STRUCT_PACK_GET_60(object),STRUCT_PACK_GET_61(object)); + } + else if constexpr (Count==63) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object),STRUCT_PACK_GET_59(object),STRUCT_PACK_GET_60(object),STRUCT_PACK_GET_61(object),STRUCT_PACK_GET_62(object)); + } + else if constexpr (Count==64) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object),STRUCT_PACK_GET_59(object),STRUCT_PACK_GET_60(object),STRUCT_PACK_GET_61(object),STRUCT_PACK_GET_62(object),STRUCT_PACK_GET_63(object)); + } + } + else { + static_assert(!sizeof(type), "empty struct/class is not allowed!"); + } + } + constexpr decltype(auto) STRUCT_PACK_INLINE visit_members_by_structure_binding(auto &&object, + auto &&visitor) { + using type = std::remove_cvref_t; constexpr auto Count = struct_pack::members_count; if constexpr (Count == 0 && std::is_class_v && !std::is_same_v) { - static_assert(!sizeof(type), "empty struct/class is not allowed!"); + static_assert(!sizeof(type), "1. If the struct is empty, which is not allowed in struct_pack type system.\n" + "2. If the strut is not empty, it means struct_pack can't calculate your struct members' count. You can use macro STRUCT_PACK_REFL(Typename, field1, field2...)."); } static_assert(Count <= MaxVisitMembers, "exceed max visit members"); // If you see any structured binding error in the follow line, it // means struct_pack can't calculate your struct's members count - // correctly. You need to mark it manually. + // correctly. + // The best way is use macro STRUCT_PACK_REFL(Typename, field1, field2...) + // See the src/struct_pack/example/non_aggregated_type.cpp for more details. // + // You can also to mark it manually. // For example, there is a struct named Hello, // and it has 3 members. // @@ -1524,4 +1685,214 @@ namespace detail { } } // namespace detail } // namespace detail -} // namespace struct_pack \ No newline at end of file +} // namespace struct_pack + + +#define STRUCT_PACK_ARG_COUNT(...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_INTERNAL_ARG_COUNT(0, ##__VA_ARGS__,\ + 64, 63, 62, 61, 60, \ + 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \ + 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \ + 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \ + 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \ + 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \ + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) + +#define STRUCT_PACK_INTERNAL_ARG_COUNT(\ + _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, \ + _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \ + _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \ + _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \ + _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \ + _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \ + _60, _61, _62, _63, _64, N, ...) N + +#define STRUCT_PACK_CONCAT_(l, r) l ## r +#define STRUCT_PACK_CONCAT(l, r) STRUCT_PACK_CONCAT_(l, r) + +#define STRUCT_PACK_MARCO_EXPAND(...) __VA_ARGS__ + +#define STRUCT_PACK_DOARG0(s,f,o) +#define STRUCT_PACK_DOARG1(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG0(s,f,__VA_ARGS__)) s f(0,t) +#define STRUCT_PACK_DOARG2(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG1(s,f,__VA_ARGS__)) s f(1,t) +#define STRUCT_PACK_DOARG3(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG2(s,f,__VA_ARGS__)) s f(2,t) +#define STRUCT_PACK_DOARG4(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG3(s,f,__VA_ARGS__)) s f(3,t) +#define STRUCT_PACK_DOARG5(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG4(s,f,__VA_ARGS__)) s f(4,t) +#define STRUCT_PACK_DOARG6(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG5(s,f,__VA_ARGS__)) s f(5,t) +#define STRUCT_PACK_DOARG7(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG6(s,f,__VA_ARGS__)) s f(6,t) +#define STRUCT_PACK_DOARG8(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG7(s,f,__VA_ARGS__)) s f(7,t) +#define STRUCT_PACK_DOARG9(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG8(s,f,__VA_ARGS__)) s f(8,t) +#define STRUCT_PACK_DOARG10(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG9(s,f,__VA_ARGS__)) s f(9,t) +#define STRUCT_PACK_DOARG11(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG10(s,f,__VA_ARGS__)) s f(10,t) +#define STRUCT_PACK_DOARG12(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG11(s,f,__VA_ARGS__)) s f(11,t) +#define STRUCT_PACK_DOARG13(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG12(s,f,__VA_ARGS__)) s f(12,t) +#define STRUCT_PACK_DOARG14(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG13(s,f,__VA_ARGS__)) s f(13,t) +#define STRUCT_PACK_DOARG15(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG14(s,f,__VA_ARGS__)) s f(14,t) +#define STRUCT_PACK_DOARG16(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG15(s,f,__VA_ARGS__)) s f(15,t) +#define STRUCT_PACK_DOARG17(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG16(s,f,__VA_ARGS__)) s f(16,t) +#define STRUCT_PACK_DOARG18(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG17(s,f,__VA_ARGS__)) s f(17,t) +#define STRUCT_PACK_DOARG19(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG18(s,f,__VA_ARGS__)) s f(18,t) +#define STRUCT_PACK_DOARG20(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG19(s,f,__VA_ARGS__)) s f(19,t) +#define STRUCT_PACK_DOARG21(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG20(s,f,__VA_ARGS__)) s f(20,t) +#define STRUCT_PACK_DOARG22(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG21(s,f,__VA_ARGS__)) s f(21,t) +#define STRUCT_PACK_DOARG23(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG22(s,f,__VA_ARGS__)) s f(22,t) +#define STRUCT_PACK_DOARG24(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG23(s,f,__VA_ARGS__)) s f(23,t) +#define STRUCT_PACK_DOARG25(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG24(s,f,__VA_ARGS__)) s f(24,t) +#define STRUCT_PACK_DOARG26(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG25(s,f,__VA_ARGS__)) s f(25,t) +#define STRUCT_PACK_DOARG27(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG26(s,f,__VA_ARGS__)) s f(26,t) +#define STRUCT_PACK_DOARG28(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG27(s,f,__VA_ARGS__)) s f(27,t) +#define STRUCT_PACK_DOARG29(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG28(s,f,__VA_ARGS__)) s f(28,t) +#define STRUCT_PACK_DOARG30(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG29(s,f,__VA_ARGS__)) s f(29,t) +#define STRUCT_PACK_DOARG31(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG30(s,f,__VA_ARGS__)) s f(30,t) +#define STRUCT_PACK_DOARG32(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG31(s,f,__VA_ARGS__)) s f(31,t) +#define STRUCT_PACK_DOARG33(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG32(s,f,__VA_ARGS__)) s f(32,t) +#define STRUCT_PACK_DOARG34(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG33(s,f,__VA_ARGS__)) s f(33,t) +#define STRUCT_PACK_DOARG35(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG34(s,f,__VA_ARGS__)) s f(34,t) +#define STRUCT_PACK_DOARG36(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG35(s,f,__VA_ARGS__)) s f(35,t) +#define STRUCT_PACK_DOARG37(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG36(s,f,__VA_ARGS__)) s f(36,t) +#define STRUCT_PACK_DOARG38(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG37(s,f,__VA_ARGS__)) s f(37,t) +#define STRUCT_PACK_DOARG39(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG38(s,f,__VA_ARGS__)) s f(38,t) +#define STRUCT_PACK_DOARG40(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG39(s,f,__VA_ARGS__)) s f(39,t) +#define STRUCT_PACK_DOARG41(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG40(s,f,__VA_ARGS__)) s f(40,t) +#define STRUCT_PACK_DOARG42(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG41(s,f,__VA_ARGS__)) s f(41,t) +#define STRUCT_PACK_DOARG43(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG42(s,f,__VA_ARGS__)) s f(42,t) +#define STRUCT_PACK_DOARG44(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG43(s,f,__VA_ARGS__)) s f(43,t) +#define STRUCT_PACK_DOARG45(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG44(s,f,__VA_ARGS__)) s f(44,t) +#define STRUCT_PACK_DOARG46(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG45(s,f,__VA_ARGS__)) s f(45,t) +#define STRUCT_PACK_DOARG47(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG46(s,f,__VA_ARGS__)) s f(46,t) +#define STRUCT_PACK_DOARG48(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG47(s,f,__VA_ARGS__)) s f(47,t) +#define STRUCT_PACK_DOARG49(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG48(s,f,__VA_ARGS__)) s f(48,t) +#define STRUCT_PACK_DOARG50(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG49(s,f,__VA_ARGS__)) s f(49,t) +#define STRUCT_PACK_DOARG51(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG50(s,f,__VA_ARGS__)) s f(50,t) +#define STRUCT_PACK_DOARG52(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG51(s,f,__VA_ARGS__)) s f(51,t) +#define STRUCT_PACK_DOARG53(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG52(s,f,__VA_ARGS__)) s f(52,t) +#define STRUCT_PACK_DOARG54(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG53(s,f,__VA_ARGS__)) s f(53,t) +#define STRUCT_PACK_DOARG55(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG54(s,f,__VA_ARGS__)) s f(54,t) +#define STRUCT_PACK_DOARG56(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG55(s,f,__VA_ARGS__)) s f(55,t) +#define STRUCT_PACK_DOARG57(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG56(s,f,__VA_ARGS__)) s f(56,t) +#define STRUCT_PACK_DOARG58(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG57(s,f,__VA_ARGS__)) s f(57,t) +#define STRUCT_PACK_DOARG59(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG58(s,f,__VA_ARGS__)) s f(58,t) +#define STRUCT_PACK_DOARG60(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG59(s,f,__VA_ARGS__)) s f(59,t) +#define STRUCT_PACK_DOARG61(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG60(s,f,__VA_ARGS__)) s f(60,t) +#define STRUCT_PACK_DOARG62(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG61(s,f,__VA_ARGS__)) s f(61,t) +#define STRUCT_PACK_DOARG63(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG62(s,f,__VA_ARGS__)) s f(62,t) +#define STRUCT_PACK_DOARG64(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG63(s,f,__VA_ARGS__)) s f(63,t) + +#define STRUCT_PACK_MAKE_ARGS0(Type) +#define STRUCT_PACK_MAKE_ARGS1(Type) Type +#define STRUCT_PACK_MAKE_ARGS2(Type) STRUCT_PACK_MAKE_ARGS1(Type), Type +#define STRUCT_PACK_MAKE_ARGS3(Type) STRUCT_PACK_MAKE_ARGS2(Type), Type +#define STRUCT_PACK_MAKE_ARGS4(Type) STRUCT_PACK_MAKE_ARGS3(Type), Type +#define STRUCT_PACK_MAKE_ARGS5(Type) STRUCT_PACK_MAKE_ARGS4(Type), Type +#define STRUCT_PACK_MAKE_ARGS6(Type) STRUCT_PACK_MAKE_ARGS5(Type), Type +#define STRUCT_PACK_MAKE_ARGS7(Type) STRUCT_PACK_MAKE_ARGS6(Type), Type +#define STRUCT_PACK_MAKE_ARGS8(Type) STRUCT_PACK_MAKE_ARGS7(Type), Type +#define STRUCT_PACK_MAKE_ARGS9(Type) STRUCT_PACK_MAKE_ARGS8(Type), Type +#define STRUCT_PACK_MAKE_ARGS10(Type) STRUCT_PACK_MAKE_ARGS9(Type), Type +#define STRUCT_PACK_MAKE_ARGS11(Type) STRUCT_PACK_MAKE_ARGS10(Type), Type +#define STRUCT_PACK_MAKE_ARGS12(Type) STRUCT_PACK_MAKE_ARGS11(Type), Type +#define STRUCT_PACK_MAKE_ARGS13(Type) STRUCT_PACK_MAKE_ARGS12(Type), Type +#define STRUCT_PACK_MAKE_ARGS14(Type) STRUCT_PACK_MAKE_ARGS13(Type), Type +#define STRUCT_PACK_MAKE_ARGS15(Type) STRUCT_PACK_MAKE_ARGS14(Type), Type +#define STRUCT_PACK_MAKE_ARGS16(Type) STRUCT_PACK_MAKE_ARGS15(Type), Type +#define STRUCT_PACK_MAKE_ARGS17(Type) STRUCT_PACK_MAKE_ARGS16(Type), Type +#define STRUCT_PACK_MAKE_ARGS18(Type) STRUCT_PACK_MAKE_ARGS17(Type), Type +#define STRUCT_PACK_MAKE_ARGS19(Type) STRUCT_PACK_MAKE_ARGS18(Type), Type +#define STRUCT_PACK_MAKE_ARGS20(Type) STRUCT_PACK_MAKE_ARGS19(Type), Type +#define STRUCT_PACK_MAKE_ARGS21(Type) STRUCT_PACK_MAKE_ARGS20(Type), Type +#define STRUCT_PACK_MAKE_ARGS22(Type) STRUCT_PACK_MAKE_ARGS21(Type), Type +#define STRUCT_PACK_MAKE_ARGS23(Type) STRUCT_PACK_MAKE_ARGS22(Type), Type +#define STRUCT_PACK_MAKE_ARGS24(Type) STRUCT_PACK_MAKE_ARGS23(Type), Type +#define STRUCT_PACK_MAKE_ARGS25(Type) STRUCT_PACK_MAKE_ARGS24(Type), Type +#define STRUCT_PACK_MAKE_ARGS26(Type) STRUCT_PACK_MAKE_ARGS25(Type), Type +#define STRUCT_PACK_MAKE_ARGS27(Type) STRUCT_PACK_MAKE_ARGS26(Type), Type +#define STRUCT_PACK_MAKE_ARGS28(Type) STRUCT_PACK_MAKE_ARGS27(Type), Type +#define STRUCT_PACK_MAKE_ARGS29(Type) STRUCT_PACK_MAKE_ARGS28(Type), Type +#define STRUCT_PACK_MAKE_ARGS30(Type) STRUCT_PACK_MAKE_ARGS29(Type), Type +#define STRUCT_PACK_MAKE_ARGS31(Type) STRUCT_PACK_MAKE_ARGS30(Type), Type +#define STRUCT_PACK_MAKE_ARGS32(Type) STRUCT_PACK_MAKE_ARGS31(Type), Type +#define STRUCT_PACK_MAKE_ARGS33(Type) STRUCT_PACK_MAKE_ARGS32(Type), Type +#define STRUCT_PACK_MAKE_ARGS34(Type) STRUCT_PACK_MAKE_ARGS33(Type), Type +#define STRUCT_PACK_MAKE_ARGS35(Type) STRUCT_PACK_MAKE_ARGS34(Type), Type +#define STRUCT_PACK_MAKE_ARGS36(Type) STRUCT_PACK_MAKE_ARGS35(Type), Type +#define STRUCT_PACK_MAKE_ARGS37(Type) STRUCT_PACK_MAKE_ARGS36(Type), Type +#define STRUCT_PACK_MAKE_ARGS38(Type) STRUCT_PACK_MAKE_ARGS37(Type), Type +#define STRUCT_PACK_MAKE_ARGS39(Type) STRUCT_PACK_MAKE_ARGS38(Type), Type +#define STRUCT_PACK_MAKE_ARGS40(Type) STRUCT_PACK_MAKE_ARGS39(Type), Type +#define STRUCT_PACK_MAKE_ARGS41(Type) STRUCT_PACK_MAKE_ARGS40(Type), Type +#define STRUCT_PACK_MAKE_ARGS42(Type) STRUCT_PACK_MAKE_ARGS41(Type), Type +#define STRUCT_PACK_MAKE_ARGS43(Type) STRUCT_PACK_MAKE_ARGS42(Type), Type +#define STRUCT_PACK_MAKE_ARGS44(Type) STRUCT_PACK_MAKE_ARGS43(Type), Type +#define STRUCT_PACK_MAKE_ARGS45(Type) STRUCT_PACK_MAKE_ARGS44(Type), Type +#define STRUCT_PACK_MAKE_ARGS46(Type) STRUCT_PACK_MAKE_ARGS45(Type), Type +#define STRUCT_PACK_MAKE_ARGS47(Type) STRUCT_PACK_MAKE_ARGS46(Type), Type +#define STRUCT_PACK_MAKE_ARGS48(Type) STRUCT_PACK_MAKE_ARGS47(Type), Type +#define STRUCT_PACK_MAKE_ARGS49(Type) STRUCT_PACK_MAKE_ARGS48(Type), Type +#define STRUCT_PACK_MAKE_ARGS50(Type) STRUCT_PACK_MAKE_ARGS49(Type), Type +#define STRUCT_PACK_MAKE_ARGS51(Type) STRUCT_PACK_MAKE_ARGS50(Type), Type +#define STRUCT_PACK_MAKE_ARGS52(Type) STRUCT_PACK_MAKE_ARGS51(Type), Type +#define STRUCT_PACK_MAKE_ARGS53(Type) STRUCT_PACK_MAKE_ARGS52(Type), Type +#define STRUCT_PACK_MAKE_ARGS54(Type) STRUCT_PACK_MAKE_ARGS53(Type), Type +#define STRUCT_PACK_MAKE_ARGS55(Type) STRUCT_PACK_MAKE_ARGS54(Type), Type +#define STRUCT_PACK_MAKE_ARGS56(Type) STRUCT_PACK_MAKE_ARGS55(Type), Type +#define STRUCT_PACK_MAKE_ARGS57(Type) STRUCT_PACK_MAKE_ARGS56(Type), Type +#define STRUCT_PACK_MAKE_ARGS58(Type) STRUCT_PACK_MAKE_ARGS57(Type), Type +#define STRUCT_PACK_MAKE_ARGS59(Type) STRUCT_PACK_MAKE_ARGS58(Type), Type +#define STRUCT_PACK_MAKE_ARGS60(Type) STRUCT_PACK_MAKE_ARGS59(Type), Type +#define STRUCT_PACK_MAKE_ARGS61(Type) STRUCT_PACK_MAKE_ARGS60(Type), Type +#define STRUCT_PACK_MAKE_ARGS62(Type) STRUCT_PACK_MAKE_ARGS61(Type), Type +#define STRUCT_PACK_MAKE_ARGS63(Type) STRUCT_PACK_MAKE_ARGS62(Type), Type +#define STRUCT_PACK_MAKE_ARGS64(Type) STRUCT_PACK_MAKE_ARGS63(Type), Type + + +#define STRUCT_PACK_MAKE_ARGS(Type,Count) \ + STRUCT_PACK_CONCAT(STRUCT_PACK_MAKE_ARGS,Count)(Type) + +#define STRUCT_PACK_EXPAND_EACH_(sepatator,fun,...) \ + STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_CONCAT(STRUCT_PACK_DOARG,STRUCT_PACK_ARG_COUNT(__VA_ARGS__))(sepatator,fun,__VA_ARGS__)) +#define STRUCT_PACK_EXPAND_EACH(sepatator,fun,...) \ + STRUCT_PACK_EXPAND_EACH_(sepatator,fun,__VA_ARGS__) + +#define STRUCT_PACK_RETURN_ELEMENT(Idx, X) \ +if constexpr (Idx == I) {\ + return c.X;\ +}\ + +#define STRUCT_PACK_GET_INDEX(Idx, Type) \ +auto& STRUCT_PACK_GET_##Idx(Type& c) {\ + return STRUCT_PACK_GET()-1-Idx>(c);\ +}\ + +#define STRUCT_PACK_GET_INDEX_CONST(Idx, Type) \ +const auto& STRUCT_PACK_GET_##Idx(const Type& c) {\ + return STRUCT_PACK_GET()-1-Idx>(c);\ +}\ + +#define STRUCT_PACK_REFL(Type,...) \ +Type& STRUCT_PACK_REFL_FLAG(Type& t) {return t;} \ +template \ +constexpr std::size_t STRUCT_PACK_FIELD_COUNT_IMPL(); \ +template<> \ +constexpr std::size_t STRUCT_PACK_FIELD_COUNT_IMPL() {return STRUCT_PACK_ARG_COUNT(__VA_ARGS__);} \ +decltype(auto) STRUCT_PACK_FIELD_COUNT(const Type &){ \ + return std::integral_constant{}; \ +} \ +template auto& STRUCT_PACK_GET(Type& c) { \ + STRUCT_PACK_EXPAND_EACH(,STRUCT_PACK_RETURN_ELEMENT,__VA_ARGS__) \ + else { \ + static_assert(I < STRUCT_PACK_FIELD_COUNT_IMPL()); \ + } \ +} \ +template const auto& STRUCT_PACK_GET(const Type& c) { \ + STRUCT_PACK_EXPAND_EACH(,STRUCT_PACK_RETURN_ELEMENT,__VA_ARGS__) \ + else { \ + static_assert(I < STRUCT_PACK_FIELD_COUNT_IMPL()); \ + } \ +} \ +STRUCT_PACK_EXPAND_EACH(,STRUCT_PACK_GET_INDEX,STRUCT_PACK_MAKE_ARGS(Type,STRUCT_PACK_ARG_COUNT(__VA_ARGS__))) \ +STRUCT_PACK_EXPAND_EACH(,STRUCT_PACK_GET_INDEX_CONST,STRUCT_PACK_MAKE_ARGS(Type,STRUCT_PACK_ARG_COUNT(__VA_ARGS__))) \ + +#define STRUCT_PACK_FRIEND_DECL(Type) \ +template \ +friend auto& STRUCT_PACK_GET(Type& c); \ +template \ +friend const auto& STRUCT_PACK_GET(const Type& c); \ diff --git a/include/ylt/struct_pack/struct_pack_impl.hpp b/include/ylt/struct_pack/struct_pack_impl.hpp index d58332815..7087259f5 100644 --- a/include/ylt/struct_pack/struct_pack_impl.hpp +++ b/include/ylt/struct_pack/struct_pack_impl.hpp @@ -1229,8 +1229,12 @@ constexpr size_info inline calculate_one_size(const T &item) { } } else if constexpr (std::is_class_v) { - if constexpr (!pair && !is_trivial_tuple) - static_assert(std::is_aggregate_v>); + if constexpr (!pair && !is_trivial_tuple) { + if constexpr (!user_defined_refl) + static_assert(std::is_aggregate_v>, + "struct_pack only support aggregated type, or you should " + "add macro STRUCT_PACK_REFL(Type,field1,field2...)"); + } if constexpr (is_trivial_serializable::value) { ret.total = sizeof(type); } @@ -1803,7 +1807,11 @@ class packer { } else if constexpr (std::is_class_v) { if constexpr (!pair && !is_trivial_tuple) - static_assert(std::is_aggregate_v>); + if constexpr (!user_defined_refl) + static_assert( + std::is_aggregate_v>, + "struct_pack only support aggregated type, or you should " + "add macro STRUCT_PACK_REFL(Type,field1,field2...)"); if constexpr (is_trivial_serializable::value) { writer_.write((char *)&item, sizeof(type)); } @@ -2300,7 +2308,10 @@ class unpacker { t); } else if constexpr (std::is_class_v) { - static_assert(std::is_aggregate_v); + if constexpr (!user_defined_refl) + static_assert(std::is_aggregate_v>, + "struct_pack only support aggregated type, or you should " + "add macro STRUCT_PACK_REFL(Type,field1,field2...)"); err_code = visit_members(t, [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { static_assert(I < sizeof...(items), "out of range"); return for_each(field, items...); @@ -2659,7 +2670,11 @@ class unpacker { } else if constexpr (std::is_class_v) { if constexpr (!pair && !is_trivial_tuple) - static_assert(std::is_aggregate_v>); + if constexpr (!user_defined_refl) + static_assert( + std::is_aggregate_v>, + "struct_pack only support aggregated type, or you should " + "add macro STRUCT_PACK_REFL(Type,field1,field2...)"); if constexpr (is_trivial_serializable::value) { if constexpr (NotSkip) { if (!reader_.read((char *)&item, sizeof(type))) [[unlikely]] { diff --git a/src/struct_pack/examples/BUILD.bazel b/src/struct_pack/examples/BUILD.bazel index 36d0cb9c8..0cd5740f2 100644 --- a/src/struct_pack/examples/BUILD.bazel +++ b/src/struct_pack/examples/BUILD.bazel @@ -2,7 +2,7 @@ load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") cc_binary( name = "serialize_example", - srcs = ["serialize.cpp"], + srcs = ["basic_usage.cpp","main.cpp","non_aggregated_type.cpp"], copts = ["-std=c++20"], deps = [ "//:ylt" diff --git a/src/struct_pack/examples/CMakeLists.txt b/src/struct_pack/examples/CMakeLists.txt index 23243279a..3b8d34d87 100644 --- a/src/struct_pack/examples/CMakeLists.txt +++ b/src/struct_pack/examples/CMakeLists.txt @@ -18,4 +18,4 @@ else() # include_directories(include) # include_directories(include/ylt/thirdparty) endif() -add_executable(struct_pack_example serialize.cpp) \ No newline at end of file +add_executable(struct_pack_example basic_usage.cpp non_aggregated_type.cpp main.cpp) \ No newline at end of file diff --git a/src/struct_pack/examples/serialize.cpp b/src/struct_pack/examples/basic_usage.cpp similarity index 98% rename from src/struct_pack/examples/serialize.cpp rename to src/struct_pack/examples/basic_usage.cpp index 159483a67..6e148ba9b 100644 --- a/src/struct_pack/examples/serialize.cpp +++ b/src/struct_pack/examples/basic_usage.cpp @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include #include #include @@ -147,6 +146,4 @@ void basic_usage() { auto p4 = struct_pack::deserialize(ifs); assert(p4 == p); } -} - -int main() { basic_usage(); } +} \ No newline at end of file diff --git a/src/struct_pack/examples/main.cpp b/src/struct_pack/examples/main.cpp new file mode 100644 index 000000000..8adb941f7 --- /dev/null +++ b/src/struct_pack/examples/main.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023, Alibaba Group Holding Limited; + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +void basic_usage(); +void non_aggregated_type(); + +int main() { + basic_usage(); + non_aggregated_type(); + return 0; +} diff --git a/src/struct_pack/examples/non_aggregated_type.cpp b/src/struct_pack/examples/non_aggregated_type.cpp new file mode 100644 index 000000000..597d70d56 --- /dev/null +++ b/src/struct_pack/examples/non_aggregated_type.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2023, Alibaba Group Holding Limited; + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +// It's easy to use struct_pack, just include it! +#include + +// 1. make sure your type has a default constructor +// 2. add marco STRUCT_PACK_REFL(Type, field1, field2...) in the same namespace +namespace example { +class person : std::vector { + private: + std::string mess; + + public: + int age; + std::string name; + auto operator==(const person& rhs) const { + return age == rhs.age && name == rhs.name; + } + person() = default; + person(int age, const std::string& name) : age(age), name(name) {} +}; + +STRUCT_PACK_REFL(person, age, name); +} // namespace example + +// 3. if you want to use private field, add friend declartion marco + +namespace example2 { +class person { + private: + int age; + std::string name; + + public: + auto operator==(const person& rhs) const { + return age == rhs.age && name == rhs.name; + } + person() = default; + person(int age, const std::string& name) : age(age), name(name) {} + STRUCT_PACK_FRIEND_DECL(person); +}; +STRUCT_PACK_REFL(person, age, name); +} // namespace example2 + +// 4. you can also add function which return class member reference as +// struct_pack field. + +namespace example3 { +class person { + private: + int age_; + std::string name_; + + public: + auto operator==(const person& rhs) const { + return age_ == rhs.age_ && name_ == rhs.name_; + } + person() = default; + person(int age, const std::string& name) : age_(age), name_(name) {} + + int& age() { return age_; }; + const int& age() const { return age_; }; + std::string& name() { return name_; }; + const std::string& name() const { return name_; }; +}; +STRUCT_PACK_REFL(person, age(), name()); +} // namespace example3 + +// 5. Remember, the STURCT_PACK_REFL marco disable the trivial_serialize +// optimize. So don't use it for trivial type. +namespace example4 { +struct point { + int x, y, z; +}; +STRUCT_PACK_REFL(point, x, y, z); +struct point2 { + int x, y, z; +}; +} // namespace example4 + +// 6. example5::person ,example::person, example2::person, example3:person are +// same type in struct_pack type system. +namespace example5 { +struct person { + int age; + std::string name; + auto operator==(const person& rhs) const { + return age == rhs.age && name == rhs.name; + } +}; +} // namespace example5 + +//clang-format off +void non_aggregated_type() { + { + example::person p{20, "tom"}; + auto buffer = struct_pack::serialize(p); + auto p2 = struct_pack::deserialize(buffer); + assert(p2); + assert(p == p2.value()); + } + { + example2::person p{20, "tom"}; + auto buffer = struct_pack::serialize(p); + auto p2 = struct_pack::deserialize(buffer); + assert(p2); + assert(p == p2.value()); + } + { + example2::person p{20, "tom"}; + auto buffer = struct_pack::serialize(p); + auto p3 = struct_pack::deserialize(buffer); + assert(p3); + assert(p == p3.value()); + } + { + assert(struct_pack::get_type_code() != + struct_pack::get_type_code()); + } + { + assert(struct_pack::get_type_code() == + struct_pack::get_type_code()); + assert(struct_pack::get_type_code() == + struct_pack::get_type_code()); + assert(struct_pack::get_type_code() == + struct_pack::get_type_code()); + } +} \ No newline at end of file diff --git a/src/struct_pack/tests/CMakeLists.txt b/src/struct_pack/tests/CMakeLists.txt index 231168b88..d6f084eb2 100644 --- a/src/struct_pack/tests/CMakeLists.txt +++ b/src/struct_pack/tests/CMakeLists.txt @@ -11,6 +11,7 @@ add_executable(struct_pack_test test_varint.cpp test_stream.cpp test_compatible.cpp + test_non_aggregated_type.cpp main.cpp ) add_test(NAME struct_pack_test COMMAND struct_pack_test) diff --git a/src/struct_pack/tests/test_non_aggregated_type.cpp b/src/struct_pack/tests/test_non_aggregated_type.cpp new file mode 100644 index 000000000..457aabca4 --- /dev/null +++ b/src/struct_pack/tests/test_non_aggregated_type.cpp @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2023, Alibaba Group Holding Limited; + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "doctest.h" +#include "test_struct.hpp" + +// 1. make sure your type has a default constructor +// 2. add marco STRUCT_PACK_REFL(Type, field1, field2...) in the same namespace +namespace example { +class person : std::vector { + private: + std::string mess; + + public: + int age; + std::string name; + auto operator==(const person& rhs) const { + return age == rhs.age && name == rhs.name; + } + person() = default; + person(int age, const std::string& name) : age(age), name(name) {} +}; + +STRUCT_PACK_REFL(person, age, name); +} // namespace example + +// 3. if you want to use private field, add friend declartion marco + +namespace example2 { +class person { + private: + int age; + std::string name; + + public: + auto operator==(const person& rhs) const { + return age == rhs.age && name == rhs.name; + } + person() = default; + person(int age, const std::string& name) : age(age), name(name) {} + STRUCT_PACK_FRIEND_DECL(person); +}; +STRUCT_PACK_REFL(person, age, name); +} // namespace example2 + +// 4. you can also add function which return class member reference as +// struct_pack field. + +namespace example3 { +class person { + private: + std::string name_; + int age_; + + public: + auto operator==(const person& rhs) const { + return age_ == rhs.age_ && name_ == rhs.name_; + } + person() = default; + person(int age, const std::string& name) : age_(age), name_(name) {} + + int& age() { return age_; }; + const int& age() const { return age_; }; + std::string& name() { return name_; }; + const std::string& name() const { return name_; }; +}; +STRUCT_PACK_REFL(person, age(), name()); +} // namespace example3 + +// 5. Remember, the STURCT_PACK_REFL marco disable the trivial_serialize +// optimize. So don't use it for trivial type. +namespace example4 { +struct point { + int x, y, z; +}; +STRUCT_PACK_REFL(point, x, y, z); +struct point2 { + int x, y, z; +}; +} // namespace example4 + +// 6. example5::person ,example::person, example2::person, example3:person are +// same type in struct_pack type system. +namespace example5 { +struct person { + int age; + std::string name; + auto operator==(const person& rhs) const { + return age == rhs.age && name == rhs.name; + } +}; +} // namespace example5 + +namespace example6 { +class complicated_object { + Color color; + int a; + std::string b; + std::vector c; + std::list d; + std::deque e; + std::map f; + std::multimap g; + std::set h; + std::multiset i; + std::unordered_map j; + std::unordered_multimap k; + std::array m; + person n[2]; + std::pair o; + + public: + complicated_object() = default; + complicated_object(const Color& color, int a, const std::string& b, + const std::vector& c, + const std::list& d, const std::deque& e, + const std::map& f, + const std::multimap& g, + const std::set& h, + const std::multiset& i, + const std::unordered_map& j, + const std::unordered_multimap& k, + const std::array& m, const person (&n)[2], + const std::pair& o) + : color(color), + a(a), + b(b), + c(c), + d(d), + e(e), + f(f), + g(g), + h(h), + i(i), + j(j), + k(k), + m(m), + o(o) { + this->n[0] = n[0]; + this->n[1] = n[1]; + } + bool operator==(const complicated_object& o) const { + return color == o.color && a == o.a && b == o.b && c == o.c && d == o.d && + e == o.e && f == o.f && g == o.g && h == o.h && i == o.i && + j == o.j && k == o.k && m == o.m && n[0] == o.n[0] && + n[1] == o.n[1] && this->o == o.o; + } + STRUCT_PACK_FRIEND_DECL(complicated_object); +}; +STRUCT_PACK_REFL(complicated_object, a, b, c, d, e, f, g, h, i, j, k, m, n, o); +} // namespace example6 + +TEST_CASE("test non aggregated type") { + example::person p{20, "tom"}; + auto buffer = struct_pack::serialize(p); + auto p2 = struct_pack::deserialize(buffer); + CHECK(p2); + CHECK(p == p2.value()); +} +TEST_CASE("test non aggregated type with private field") { + example2::person p{20, "tom"}; + auto buffer = struct_pack::serialize(p); + auto p2 = struct_pack::deserialize(buffer); + CHECK(p2); + CHECK(p == p2.value()); +} +TEST_CASE("test non aggregated type with function field") { + example2::person p{20, "tom"}; + auto buffer = struct_pack::serialize(p); + auto p3 = struct_pack::deserialize(buffer); + CHECK(p3); + CHECK(p == p3.value()); +} +TEST_CASE("test disable trivial serialize optimize") { + CHECK(struct_pack::get_type_code() != + struct_pack::get_type_code()); +} +TEST_CASE("test same type with different reflection way") { + example5::person p{25, "Betty"}; + { + example::person p2{25, "Betty"}; + CHECK(struct_pack::get_type_code() == + struct_pack::get_type_code()); + { + auto buffer = struct_pack::serialize(p2); + auto result = struct_pack::deserialize(buffer); + CHECK(result); + CHECK(result.value() == p); + } + { + auto buffer = struct_pack::serialize(p); + auto result = struct_pack::deserialize(buffer); + CHECK(result); + CHECK(result.value() == p2); + } + } + { + example2::person p2{25, "Betty"}; + CHECK(struct_pack::get_type_code() == + struct_pack::get_type_code()); + { + auto buffer = struct_pack::serialize(p2); + auto result = struct_pack::deserialize(buffer); + CHECK(result); + CHECK(result.value() == p); + } + { + auto buffer = struct_pack::serialize(p); + auto result = struct_pack::deserialize(buffer); + CHECK(result); + CHECK(result.value() == p2); + } + } + { + example3::person p2{25, "Betty"}; + CHECK(struct_pack::get_type_code() == + struct_pack::get_type_code()); + { + auto buffer = struct_pack::serialize(p2); + auto result = struct_pack::deserialize(buffer); + CHECK(result); + CHECK(result.value() == p); + } + { + auto buffer = struct_pack::serialize(p); + auto result = struct_pack::deserialize(buffer); + CHECK(result); + CHECK(result.value() == p2); + } + } +} +TEST_CASE("test complicated_object") { + example6::complicated_object o{ + Color::red, + 42, + "hello", + {{20, "tom"}, {22, "jerry"}}, + {"hello", "world"}, + {1, 2}, + {{1, {20, "tom"}}}, + {{1, {20, "tom"}}, {1, {22, "jerry"}}}, + {"aa", "bb"}, + {1, 2}, + {{1, {20, "tom"}}, {1, {22, "jerry"}}}, + {{1, 2}, {1, 3}}, + {person{20, "tom"}, {22, "jerry"}}, + {person{20, "tom"}, {22, "jerry"}}, + std::make_pair("aa", person{20, "tom"}), + }; + auto buffer = struct_pack::serialize(o); + auto result = struct_pack::deserialize(buffer); + CHECK(result); + CHECK(result.value() == o); +} diff --git a/website/docs/en/struct_pack/struct_pack_intro.md b/website/docs/en/struct_pack/struct_pack_intro.md index e05a50094..47935e4de 100644 --- a/website/docs/en/struct_pack/struct_pack_intro.md +++ b/website/docs/en/struct_pack/struct_pack_intro.md @@ -1,6 +1,6 @@ # struct_pack Introduction -struct_pack is a serialization library featuring zero-cost abstraction as well as usability. In struct_pack, the serialization or deserialization of one complex structure could easily be done in a single line of code, without any DSL, macro, or template to be defined. struct_pack supports the serialization of C++ structures through compile-time reflection and its performance is significantly better than protobuf and msgpack (see the benchmark section for details). +struct_pack is a serialization library featuring zero-cost abstraction as well as usability. In struct_pack, the serialization or deserialization of one **aggregated** structure could easily be done in a single line of code, without any DSL, macro, or template to be defined. struct_pack also support use marco for custom reflection of non-aggregated struct. struct_pack supports the serialization of C++ structures through compile-time reflection and its performance is significantly better than protobuf and msgpack (see the benchmark section for details). Below, we show the basic usage of struct_pack with a simple object as an example. @@ -173,6 +173,83 @@ assert(nested2==nested1); ## custom support +### custom reflection + +Sometimes user need support non-aggregated type, or adjust the order of each field, which can be supported by macro function `STRUCT_PACK_REFL(typename, fieldname1, fieldname2 ...)`. + +```cpp +namespace test { +class person : std::vector { + private: + std::string mess; + + public: + int age; + std::string name; + auto operator==(const person& rhs) const { + return age == rhs.age && name == rhs.name; + } + person() = default; + person(int age, const std::string& name) : age(age), name(name) {} +}; +STRUCT_PACK_REFL(person, name, age); +} + +The first argument of `STRUCT_PACK_REFL(typename, fieldname1, fieldname2 ...)` is the name of the type reflected, the others are the field names. +The macro must be defined in the same namespace of the reflected type. +The macro allow struct_pack support non-aggregated type, allow user define constructor, derived from other type or add some field which don't serialize. +``` + +Sometimes, user want to serialize/deserialize some private fields, which can be supported by macro function `STRUCT_PACK_FRIEND_DECL(typename)`. +```cpp +namespace example2 { +class person { + private: + int age; + std::string name; + + public: + auto operator==(const person& rhs) const { + return age == rhs.age && name == rhs.name; + } + person() = default; + person(int age, const std::string& name) : age(age), name(name) {} + STRUCT_PACK_FRIEND_DECL(person); +}; +STRUCT_PACK_REFL(person, age, name); +} // namespace example2 +``` + +This macro must declared inside the struct, it regist struct_pack reflection function as friend function. + +User can even register member function in macro function `STRUCT_PACK_REFL`, which greatly expands the flexibility of struct_pack. + + +```cpp +namespace example3 { +class person { + private: + int age_; + std::string name_; + + public: + auto operator==(const person& rhs) const { + return age_ == rhs.age_ && name_ == rhs.name_; + } + person() = default; + person(int age, const std::string& name) : age_(age), name_(name) {} + + int& age() { return age_; }; + const int& age() const { return age_; }; + std::string& name() { return name_; }; + const std::string& name() const { return name_; }; +}; +STRUCT_PACK_REFL(person, age(), name()); +} // namespace example3 +``` +The member function registed must return a reference, and this function must have a const version overload & non-const overload. + + ### custom type In addition, struct_pack supports serialization and deserialization on custom containers, as below: diff --git a/website/docs/en/struct_pack/struct_pack_type_system.md b/website/docs/en/struct_pack/struct_pack_type_system.md index 8a710c675..755c238cf 100644 --- a/website/docs/en/struct_pack/struct_pack_type_system.md +++ b/website/docs/en/struct_pack/struct_pack_type_system.md @@ -218,6 +218,14 @@ struct person { ``` and ```cpp +struct person2 { + std::string name; + int age; +}; +STRUCT_PACK_REFL(person2,age,name) +``` +and +```cpp std::pair ``` and @@ -241,7 +249,7 @@ are different types with `person` in struct_pack. ### trivial struct -If there is a struct/class/std::pair/tuplet::tuple, and all the field of this type is a trivial type, then this type is a trivial struct in struct_pack. +If there is a struct/class/std::pair/tuplet::tuple, and all the field of this type is a trivial type, and the type isn't registed by macro `STRUCT_PACK_REFL`, then this type is a trivial struct in struct_pack. A trivial type is : 1. fundamental type. @@ -275,6 +283,19 @@ void test() { } ``` +Remeber, the type registed by macro `STRUCT_PACK_REFL` is not trivial struct. +For example: +```cpp +struct foo { + int a,b,c; +}; +struct bar { + int a,b,c; +}; +STRUCT_PACK_REFL(bar,a,b,c); +static_assert(struct_pack::get_type_code()!=struct_pack::get_type_code()); +``` + ## Compatible Type This refers to `struct_pack::compatible`. This is a special data type kind of identical to `std::optional` in cpp. In `struct_pack` it is dedicated for the forward/backward compatibility purpose. diff --git a/website/docs/zh/struct_pack/struct_pack_intro.md b/website/docs/zh/struct_pack/struct_pack_intro.md index f3520ed6e..f468f3648 100644 --- a/website/docs/zh/struct_pack/struct_pack_intro.md +++ b/website/docs/zh/struct_pack/struct_pack_intro.md @@ -1,6 +1,6 @@ # struct_pack简介 -struct_pack是一个以零成本抽象,高度易用为特色序列化库。通常情况下只需一行代码即可完成复杂结构体的序列化/反序列化。用户无需定义任何DSL,宏或模板代码,struct_pack可通过编译期反射自动支持对C++结构体的序列化。其综合性能比protobuf,msgpack大幅提升(详细可以看benchmark部分)。 +struct_pack是一个以零成本抽象,高度易用为特色序列化库。通常情况下只需一行代码即可完成复杂结构体的序列化/反序列化。对于聚合类型,用户无需定义任何DSL,宏或模板代码。struct_pack也支持使用宏来自定义非聚合类型的反射。struct_pack可通过编译期反射自动支持对C++结构体的序列化。其综合性能比protobuf,msgpack大幅提升(详细可以看benchmark部分)。 下面,我们以一个简单的对象为例展示struc_pack的基本用法。 @@ -168,6 +168,83 @@ assert(nested2==nested1); ## 自定义功能支持 +### 用户自定义反射 + +有时候用户需要支持非聚合的结构体,或者自定义各字段序列化的顺序,这些可以通过宏函数`STRUCT_PACK_REFL(typename, fieldname1, fieldname2 ...)`来支持。 + +```cpp +namespace test { +class person : std::vector { + private: + std::string mess; + + public: + int age; + std::string name; + auto operator==(const person& rhs) const { + return age == rhs.age && name == rhs.name; + } + person() = default; + person(int age, const std::string& name) : age(age), name(name) {} +}; +STRUCT_PACK_REFL(person, name, age); +} + +`STRUCT_PACK_REFL(typename, fieldname1, fieldname2 ...)`填入的第一个参数是需要反射的类型名,随后是若干个字段名,代表反射信息的各个字段。 +该宏必须定义在反射的类型所在的命名空间中。 +如果该类型不具有默认构造函数,则无法使用函数`struct_pack::deserialize`,不过你依然可以使用`struct_pack::deserialize_to`来实现反序列化。 +它使得struct_pack可以支持那些非聚合的结构体类型,允许用户自定义构造函数,继承其他类型,添加不序列化的字段等等。 +``` + +有时,用户需要序列化/反序列化那些private字段,这可以通过函数`STRUCT_PACK_FRIEND_DECL(typenmae)`;来支持。 +```cpp +namespace example2 { +class person { + private: + int age; + std::string name; + + public: + auto operator==(const person& rhs) const { + return age == rhs.age && name == rhs.name; + } + person() = default; + person(int age, const std::string& name) : age(age), name(name) {} + STRUCT_PACK_FRIEND_DECL(person); +}; +STRUCT_PACK_REFL(person, age, name); +} // namespace example2 +``` + +该宏必须声明在结构体内部,其原理是将struct_pack与反射有关的函数注册为友元函数。 + +用户甚至可以在`STRUCT_PACK_REFL`中注册成员函数,这极大的扩展了struct_pack的灵活性。 + +```cpp +namespace example3 { +class person { + private: + int age_; + std::string name_; + + public: + auto operator==(const person& rhs) const { + return age_ == rhs.age_ && name_ == rhs.name_; + } + person() = default; + person(int age, const std::string& name) : age_(age), name_(name) {} + + int& age() { return age_; }; + const int& age() const { return age_; }; + std::string& name() { return name_; }; + const std::string& name() const { return name_; }; +}; +STRUCT_PACK_REFL(person, age(), name()); +} // namespace example3 + +注册的成员函数必须返回一个引用,并且该函数具有常量和非常量的重载。 +``` + ### 自定义类型的序列化 struct_pack支持序列化自定义类型。 diff --git a/website/docs/zh/struct_pack/struct_pack_type_system.md b/website/docs/zh/struct_pack/struct_pack_type_system.md index 101e6befe..2b74f25e1 100644 --- a/website/docs/zh/struct_pack/struct_pack_type_system.md +++ b/website/docs/zh/struct_pack/struct_pack_type_system.md @@ -219,6 +219,13 @@ struct person { std::string name; }; ``` +```cpp +struct person2 { + std::string name; + int age; +}; +STRUCT_PACK_REFL(person2,age,name) +``` 和 ```cpp std::pair @@ -252,7 +259,7 @@ std::tuple ### 平凡结构体 -假如一个类型是`struct/class/std::pair/tuplet::tuple`,且其所有的成员字段都是平凡字段,则该类型被视为平凡结构体类型。 +假如一个类型是`struct/class/std::pair/tuplet::tuple`,且其所有的成员字段都是平凡字段,并且该类型未使用`STRUCT_PACK_REFL`宏注册,则该类型被视为平凡结构体类型。 平凡字段是下面几种类型中的一种: 1. 基本类型 @@ -286,6 +293,19 @@ void test() { } ``` +需要注意的是,通过`STRUCT_PACK_REFL`宏注册的类型一定不是平凡结构体。 +例如: +```cpp +struct foo { + int a,b,c; +}; +struct bar { + int a,b,c; +}; +STRUCT_PACK_REFL(bar,a,b,c); +static_assert(struct_pack::get_type_code()!=struct_pack::get_type_code()); +``` + ## 兼容类型