From 9108fc3177f7ce3e5e9e7cc9085c94bc2ced399b Mon Sep 17 00:00:00 2001 From: aba_aba_da_duo_duo <49055103+982945902@users.noreply.github.com> Date: Thu, 29 Jun 2023 12:50:31 +0800 Subject: [PATCH 1/7] Update struct_pack_impl.hpp --- include/ylt/struct_pack/struct_pack_impl.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/ylt/struct_pack/struct_pack_impl.hpp b/include/ylt/struct_pack/struct_pack_impl.hpp index 1e889447d..4c8a0aa5a 100644 --- a/include/ylt/struct_pack/struct_pack_impl.hpp +++ b/include/ylt/struct_pack/struct_pack_impl.hpp @@ -508,6 +508,14 @@ consteval type_id get_type_id() { else if constexpr (std::is_integral_v) { return get_integral_type(); } +#if __GNUC__ && __clang__ + else if constexpr (std::is_same_v<__int128, T>) { + return type_id::int128_t; + } + else if constexpr (std::is_same_v) { + return type_id::uint128_t; + } +#endif else if constexpr (std::is_floating_point_v) { return get_floating_point_type(); } From ed48e3000a1fa1bc869b6b53e3320a64bdb21354 Mon Sep 17 00:00:00 2001 From: aba_aba_da_duo_duo <49055103+982945902@users.noreply.github.com> Date: Thu, 29 Jun 2023 15:34:39 +0800 Subject: [PATCH 2/7] Update struct_pack_impl.hpp --- include/ylt/struct_pack/struct_pack_impl.hpp | 32 ++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/include/ylt/struct_pack/struct_pack_impl.hpp b/include/ylt/struct_pack/struct_pack_impl.hpp index 4c8a0aa5a..3c95663b5 100644 --- a/include/ylt/struct_pack/struct_pack_impl.hpp +++ b/include/ylt/struct_pack/struct_pack_impl.hpp @@ -235,6 +235,11 @@ namespace detail { #endif } +#if __GNUC__ || __clang__ +template +constexpr inline bool is_integral128_v = std::is_same_v<__int128, T> | std::is_same_v; +#endif + template constexpr inline bool is_trivial_tuple> = true; @@ -246,10 +251,17 @@ template template constexpr auto get_types() { using T = std::remove_cvref_t; +#if __GNUC__ || __clang__ + if constexpr (std::is_fundamental_v || std::is_enum_v || varint_t || + std::is_same_v || container || optional || + unique_ptr || variant || expected || array || + c_array || std::is_same_v || is_integral128_v) { +#else if constexpr (std::is_fundamental_v || std::is_enum_v || varint_t || std::is_same_v || container || optional || unique_ptr || variant || expected || array || c_array || std::is_same_v) { +#endif return declval>(); } else if constexpr (tuple) { @@ -306,7 +318,7 @@ enum class type_id { uint8_t, int16_t, uint16_t, - int128_t, // TODO: support int128/uint128 + int128_t, // TODO: support int128/uint128 on msvc, now support on gcc clang uint128_t, bool_t, char_8_t, @@ -508,7 +520,7 @@ consteval type_id get_type_id() { else if constexpr (std::is_integral_v) { return get_integral_type(); } -#if __GNUC__ && __clang__ +#if __GNUC__ || __clang__ else if constexpr (std::is_same_v<__int128, T>) { return type_id::int128_t; } @@ -1154,9 +1166,15 @@ constexpr size_info inline calculate_one_size(const T &item) { size_info ret{.total = 0, .size_cnt = 0, .max_size = 0}; if constexpr (id == type_id::monostate_t) { } +#if __GNUC__ || __clang__ + else if constexpr (std::is_fundamental_v || std::is_enum_v || is_integral128_v) { + ret.total = sizeof(type); + } +#else else if constexpr (std::is_fundamental_v || std::is_enum_v) { ret.total = sizeof(type); } +#endif else if constexpr (detail::varint_t) { ret.total = detail::calculate_varint_size(item); } @@ -1692,9 +1710,15 @@ class packer { else if constexpr (std::is_same_v) { // do nothing } +#if __GNUC__ || __clang__ + else if constexpr (std::is_fundamental_v || std::is_enum_v || is_integral128_v) { + writer_.write((char *)&item, sizeof(type)); + } +#else else if constexpr (std::is_fundamental_v || std::is_enum_v) { writer_.write((char *)&item, sizeof(type)); } +#endif else if constexpr (detail::varint_t) { detail::serialize_varint(writer_, item); } @@ -2430,7 +2454,11 @@ class unpacker { else if constexpr (std::is_same_v) { // do nothing } +#if __GNUC__ || __clang__ + else if constexpr (std::is_fundamental_v || std::is_enum_v || is_integral128_v) { +#else else if constexpr (std::is_fundamental_v || std::is_enum_v) { +#endif if constexpr (NotSkip) { if (!reader_.read((char *)&item, sizeof(type))) [[unlikely]] { return struct_pack::errc::no_buffer_space; From 53c4c9a797121a1faf6f60fc035a03ab08f0f7d6 Mon Sep 17 00:00:00 2001 From: aba_aba_da_duo_duo <49055103+982945902@users.noreply.github.com> Date: Thu, 29 Jun 2023 15:50:41 +0800 Subject: [PATCH 3/7] Update struct_pack_impl.hpp --- include/ylt/struct_pack/struct_pack_impl.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/ylt/struct_pack/struct_pack_impl.hpp b/include/ylt/struct_pack/struct_pack_impl.hpp index 3c95663b5..6f01f937c 100644 --- a/include/ylt/struct_pack/struct_pack_impl.hpp +++ b/include/ylt/struct_pack/struct_pack_impl.hpp @@ -431,6 +431,15 @@ consteval type_id get_integral_type() { "sizeof(bool)!=1, which is not supported."); return type_id::bool_t; } +#if __GNUC__ || __clang__ + //-std=gnu++20 + else if constexpr (std::is_same_v<__int128, T>) { + return type_id::int128_t; + } + else if constexpr (std::is_same_v) { + return type_id::uint128_t; + } +#endif else { /* * Due to different data model, @@ -521,6 +530,7 @@ consteval type_id get_type_id() { return get_integral_type(); } #if __GNUC__ || __clang__ + //-std=c++20 else if constexpr (std::is_same_v<__int128, T>) { return type_id::int128_t; } From 5888fa0185fc2e2c93ae2b3e39c955355053aba5 Mon Sep 17 00:00:00 2001 From: "Zezheng.Li" Date: Thu, 6 Jul 2023 11:46:02 +0800 Subject: [PATCH 4/7] [struct_pack] support int128/uint128, add doc & test --- include/ylt/struct_pack/struct_pack_impl.hpp | 32 +++---------------- src/struct_pack/tests/test_serialize.cpp | 23 +++++++++++++ .../en/struct_pack/struct_pack_type_system.md | 10 +++--- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/include/ylt/struct_pack/struct_pack_impl.hpp b/include/ylt/struct_pack/struct_pack_impl.hpp index 6f01f937c..bd127dc47 100644 --- a/include/ylt/struct_pack/struct_pack_impl.hpp +++ b/include/ylt/struct_pack/struct_pack_impl.hpp @@ -235,11 +235,6 @@ namespace detail { #endif } -#if __GNUC__ || __clang__ -template -constexpr inline bool is_integral128_v = std::is_same_v<__int128, T> | std::is_same_v; -#endif - template constexpr inline bool is_trivial_tuple> = true; @@ -255,7 +250,7 @@ constexpr auto get_types() { if constexpr (std::is_fundamental_v || std::is_enum_v || varint_t || std::is_same_v || container || optional || unique_ptr || variant || expected || array || - c_array || std::is_same_v || is_integral128_v) { + c_array || std::is_same_v) { #else if constexpr (std::is_fundamental_v || std::is_enum_v || varint_t || std::is_same_v || container || optional || @@ -318,7 +313,7 @@ enum class type_id { uint8_t, int16_t, uint16_t, - int128_t, // TODO: support int128/uint128 on msvc, now support on gcc clang + int128_t, // Tips: We only support 128-bit integer on gcc clang uint128_t, bool_t, char_8_t, @@ -423,7 +418,7 @@ consteval type_id get_integral_type() { // char32_t's size maybe bigger than 32bits, which is not supported. else if constexpr (std::is_same_v && sizeof(char32_t) == 4) { static_assert(sizeof(char32_t) == 4, - "sizeof(char16_t)!=4, which is not supported."); + "sizeof(char32_t)!=4, which is not supported."); return type_id::char_32_t; } else if constexpr (std::is_same_v && sizeof(bool)) { @@ -529,15 +524,6 @@ consteval type_id get_type_id() { else if constexpr (std::is_integral_v) { return get_integral_type(); } -#if __GNUC__ || __clang__ - //-std=c++20 - else if constexpr (std::is_same_v<__int128, T>) { - return type_id::int128_t; - } - else if constexpr (std::is_same_v) { - return type_id::uint128_t; - } -#endif else if constexpr (std::is_floating_point_v) { return get_floating_point_type(); } @@ -1177,7 +1163,7 @@ constexpr size_info inline calculate_one_size(const T &item) { if constexpr (id == type_id::monostate_t) { } #if __GNUC__ || __clang__ - else if constexpr (std::is_fundamental_v || std::is_enum_v || is_integral128_v) { + else if constexpr (std::is_fundamental_v || std::is_enum_v) { ret.total = sizeof(type); } #else @@ -1720,15 +1706,9 @@ class packer { else if constexpr (std::is_same_v) { // do nothing } -#if __GNUC__ || __clang__ - else if constexpr (std::is_fundamental_v || std::is_enum_v || is_integral128_v) { - writer_.write((char *)&item, sizeof(type)); - } -#else else if constexpr (std::is_fundamental_v || std::is_enum_v) { writer_.write((char *)&item, sizeof(type)); } -#endif else if constexpr (detail::varint_t) { detail::serialize_varint(writer_, item); } @@ -2464,11 +2444,7 @@ class unpacker { else if constexpr (std::is_same_v) { // do nothing } -#if __GNUC__ || __clang__ - else if constexpr (std::is_fundamental_v || std::is_enum_v || is_integral128_v) { -#else else if constexpr (std::is_fundamental_v || std::is_enum_v) { -#endif if constexpr (NotSkip) { if (!reader_.read((char *)&item, sizeof(type))) [[unlikely]] { return struct_pack::errc::no_buffer_space; diff --git a/src/struct_pack/tests/test_serialize.cpp b/src/struct_pack/tests/test_serialize.cpp index 483038c2a..d0b931c7a 100644 --- a/src/struct_pack/tests/test_serialize.cpp +++ b/src/struct_pack/tests/test_serialize.cpp @@ -1029,6 +1029,29 @@ TEST_CASE("compatible convert to optional") { CHECK(b.value() == "hello world"); CHECK(a.value() == "hello world"); } +#if __GNUC__ || __clang__ +struct test_int_128 { + __int128_t x; + __uint128_t y; + bool operator==(const test_int_128 &) const = default; +}; + +TEST_CASE("test 128-bit int") { + __int128_t i = INT64_MAX; + i *= INT64_MAX; + CHECK(i > INT64_MAX); + __uint128_t j = UINT64_MAX; + j *= UINT64_MAX; + CHECK(j > UINT64_MAX); + auto vec = std::vector{{i, j}, {-1 * i, j + UINT64_MAX}}; + auto buffer = struct_pack::serialize(vec); + auto result = struct_pack::deserialize>(buffer); + CHECK(result == vec); + CHECK(struct_pack::detail::is_trivial_serializable::value); +} + +TEST_CASE("test uint128") {} +#endif #if __cpp_lib_span >= 202002L 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 c6cdf112c..aa2c4bba5 100644 --- a/website/docs/en/struct_pack/struct_pack_type_system.md +++ b/website/docs/en/struct_pack/struct_pack_type_system.md @@ -15,14 +15,16 @@ supported by `struct_pack`. | Type | Meaning | code | | ------------------------- | ----------------------------------------- | ------------------------------------------ | -| int8_t | Signed fixed-length 8-bit integer | complementary code | -| int16_t | Signed fixed-length 16-bit integer | complementary cod | -| int32_t | Signed fixed-length 32-bit integer | complementary cod | -| int64_t | Signed fixed-length 64-bit integer | complementary cod | +| int8_t | Signed fixed-length 8-bit integer | complement code | +| int16_t | Signed fixed-length 16-bit integer | complement code | +| int32_t | Signed fixed-length 32-bit integer | complement code | +| int64_t | Signed fixed-length 64-bit integer | complement code | +| int128_t (GCC/Clang only) | Signed fixed-length 64-bit integer | complement code | | uint8_t | Unsigned fixed-length 8-bit integer | Original Code | | uint16_t | Unsigned fixed-length 16-bit integer | Original Code | | uint32_t | Unsigned fixed-length 32-bit integer | Original Code | | uint64_t | Unsigned fixed-length 64-bit integer | Original Code | +| uint128_t (GCC/Clang only)| Unsigned fixed-length 64-bit integer | Original Code | | struct_pack::var_uint32_t | Unsigned variable-length 32-bit integer | `varint` variable length code | | struct_pack::var_uint64_t | Unsigned variable-length 64-bit integer | `varint` variable length code | | struct_pack::var_int32_t | Signed variable-length 32-bit integers | `varint`+`zigzag` variable length encoding | From f2ddb3e84f9a46b6f2ff6e20e3a7655190e76927 Mon Sep 17 00:00:00 2001 From: "Zezheng.Li" Date: Thu, 6 Jul 2023 12:26:08 +0800 Subject: [PATCH 5/7] fix --- include/ylt/struct_pack/struct_pack_impl.hpp | 35 +++++++++----------- src/struct_pack/tests/test_serialize.cpp | 1 - 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/include/ylt/struct_pack/struct_pack_impl.hpp b/include/ylt/struct_pack/struct_pack_impl.hpp index bd127dc47..915041382 100644 --- a/include/ylt/struct_pack/struct_pack_impl.hpp +++ b/include/ylt/struct_pack/struct_pack_impl.hpp @@ -246,17 +246,15 @@ template template constexpr auto get_types() { using T = std::remove_cvref_t; -#if __GNUC__ || __clang__ - if constexpr (std::is_fundamental_v || std::is_enum_v || varint_t || - std::is_same_v || container || optional || - unique_ptr || variant || expected || array || - c_array || std::is_same_v) { -#else if constexpr (std::is_fundamental_v || std::is_enum_v || varint_t || - std::is_same_v || container || optional || - unique_ptr || variant || expected || array || - c_array || std::is_same_v) { + string || container || optional || unique_ptr || + variant || expected || array || c_array || + std::is_same_v +#if __GNUC__ || __clang__ + || std::is_same_v<__int128, T> || + std::is_same_v #endif + ) { return declval>(); } else if constexpr (tuple) { @@ -300,7 +298,6 @@ template concept struct_pack_buffer = trivially_copyable_container && struct_pack_byte; // clang-format on - enum class type_id { // compatible template type compatible_t = 0, @@ -521,7 +518,8 @@ consteval type_id get_type_id() { else if constexpr (std::is_enum_v) { return get_integral_type>(); } - else if constexpr (std::is_integral_v) { + else if constexpr (std::is_integral_v || std::is_same_v<__int128, T> || + std::is_same_v) { return get_integral_type(); } else if constexpr (std::is_floating_point_v) { @@ -1162,15 +1160,10 @@ constexpr size_info inline calculate_one_size(const T &item) { size_info ret{.total = 0, .size_cnt = 0, .max_size = 0}; if constexpr (id == type_id::monostate_t) { } -#if __GNUC__ || __clang__ - else if constexpr (std::is_fundamental_v || std::is_enum_v) { + else if constexpr (std::is_fundamental_v || std::is_enum_v || + id == type_id::int128_t || id == type_id::uint128_t) { ret.total = sizeof(type); } -#else - else if constexpr (std::is_fundamental_v || std::is_enum_v) { - ret.total = sizeof(type); - } -#endif else if constexpr (detail::varint_t) { ret.total = detail::calculate_varint_size(item); } @@ -1706,7 +1699,8 @@ class packer { else if constexpr (std::is_same_v) { // do nothing } - else if constexpr (std::is_fundamental_v || std::is_enum_v) { + else if constexpr (std::is_fundamental_v || std::is_enum_v || + id == type_id::int128_t || id == type_id::uint128_t) { writer_.write((char *)&item, sizeof(type)); } else if constexpr (detail::varint_t) { @@ -2444,7 +2438,8 @@ class unpacker { else if constexpr (std::is_same_v) { // do nothing } - else if constexpr (std::is_fundamental_v || std::is_enum_v) { + else if constexpr (std::is_fundamental_v || std::is_enum_v || + id == type_id::int128_t || id == type_id::uint128_t) { if constexpr (NotSkip) { if (!reader_.read((char *)&item, sizeof(type))) [[unlikely]] { return struct_pack::errc::no_buffer_space; diff --git a/src/struct_pack/tests/test_serialize.cpp b/src/struct_pack/tests/test_serialize.cpp index d0b931c7a..669777941 100644 --- a/src/struct_pack/tests/test_serialize.cpp +++ b/src/struct_pack/tests/test_serialize.cpp @@ -1050,7 +1050,6 @@ TEST_CASE("test 128-bit int") { CHECK(struct_pack::detail::is_trivial_serializable::value); } -TEST_CASE("test uint128") {} #endif #if __cpp_lib_span >= 202002L From d2215fddcfe83c8bfae79cc142f3d0a6944927eb Mon Sep 17 00:00:00 2001 From: "Zezheng.Li" Date: Thu, 6 Jul 2023 13:52:16 +0800 Subject: [PATCH 6/7] fix trivial_serializable --- include/ylt/struct_pack/reflection.hpp | 6 +++++- include/ylt/struct_pack/struct_pack_impl.hpp | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/ylt/struct_pack/reflection.hpp b/include/ylt/struct_pack/reflection.hpp index b88147a3d..8cb0ffc93 100644 --- a/include/ylt/struct_pack/reflection.hpp +++ b/include/ylt/struct_pack/reflection.hpp @@ -311,7 +311,11 @@ namespace detail { if constexpr (is_compatible_v || trivial_view) { return ignore_compatible_field; } - else if constexpr (std::is_enum_v || std::is_fundamental_v) { + else if constexpr (std::is_enum_v || std::is_fundamental_v +#if __GNUC__ || __clang__ + || std::is_same_v<__int128,T> || std::is_same_v +#endif + ) { return true; } else if constexpr (array) { diff --git a/include/ylt/struct_pack/struct_pack_impl.hpp b/include/ylt/struct_pack/struct_pack_impl.hpp index 915041382..bb0f966e0 100644 --- a/include/ylt/struct_pack/struct_pack_impl.hpp +++ b/include/ylt/struct_pack/struct_pack_impl.hpp @@ -1907,7 +1907,7 @@ class packer { friend constexpr serialize_buffer_size get_needed_size(const T &t); writer &writer_; const serialize_buffer_size &info; -}; +}; // namespace detail template From 19a7146e92b2c4299664c6be3096a3f727a11050 Mon Sep 17 00:00:00 2001 From: "Zezheng.Li" Date: Thu, 6 Jul 2023 14:03:39 +0800 Subject: [PATCH 7/7] fix msvc --- include/ylt/struct_pack/struct_pack_impl.hpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/include/ylt/struct_pack/struct_pack_impl.hpp b/include/ylt/struct_pack/struct_pack_impl.hpp index bb0f966e0..d58332815 100644 --- a/include/ylt/struct_pack/struct_pack_impl.hpp +++ b/include/ylt/struct_pack/struct_pack_impl.hpp @@ -518,8 +518,12 @@ consteval type_id get_type_id() { else if constexpr (std::is_enum_v) { return get_integral_type>(); } - else if constexpr (std::is_integral_v || std::is_same_v<__int128, T> || - std::is_same_v) { + else if constexpr (std::is_integral_v +#if __GNUC__ || __CLANG__ + || std::is_same_v<__int128, T> || + std::is_same_v +#endif + ) { return get_integral_type(); } else if constexpr (std::is_floating_point_v) { @@ -574,7 +578,7 @@ consteval type_id get_type_id() { else { static_assert(!sizeof(T), "not supported type"); } -} +} // namespace detail template consteval decltype(auto) get_size_literal() {