Skip to content

Commit

Permalink
[struct_pack] support int128/uint128, add doc & test
Browse files Browse the repository at this point in the history
  • Loading branch information
poor-circle committed Jul 6, 2023
1 parent 53c4c9a commit 5888fa0
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 32 deletions.
32 changes: 4 additions & 28 deletions include/ylt/struct_pack/struct_pack_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,6 @@ namespace detail {
#endif
}

#if __GNUC__ || __clang__
template <typename T>
constexpr inline bool is_integral128_v = std::is_same_v<__int128, T> | std::is_same_v<unsigned __int128, T>;
#endif

template <typename... T>
constexpr inline bool is_trivial_tuple<tuplet::tuple<T...>> = true;

Expand All @@ -255,7 +250,7 @@ constexpr auto get_types() {
if constexpr (std::is_fundamental_v<T> || std::is_enum_v<T> || varint_t<T> ||
std::is_same_v<std::string, T> || container<T> || optional<T> ||
unique_ptr<T> || variant<T> || expected<T> || array<T> ||
c_array<T> || std::is_same_v<std::monostate, T> || is_integral128_v<T>) {
c_array<T> || std::is_same_v<std::monostate, T>) {
#else
if constexpr (std::is_fundamental_v<T> || std::is_enum_v<T> || varint_t<T> ||
std::is_same_v<std::string, T> || container<T> || optional<T> ||
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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<char32_t, T> && 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<bool, T> && sizeof(bool)) {
Expand Down Expand Up @@ -529,15 +524,6 @@ consteval type_id get_type_id() {
else if constexpr (std::is_integral_v<T>) {
return get_integral_type<T>();
}
#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<unsigned __int128, T>) {
return type_id::uint128_t;
}
#endif
else if constexpr (std::is_floating_point_v<T>) {
return get_floating_point_type<T>();
}
Expand Down Expand Up @@ -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<type> || std::is_enum_v<type> || is_integral128_v<type>) {
else if constexpr (std::is_fundamental_v<type> || std::is_enum_v<type>) {
ret.total = sizeof(type);
}
#else
Expand Down Expand Up @@ -1720,15 +1706,9 @@ class packer {
else if constexpr (std::is_same_v<type, std::monostate>) {
// do nothing
}
#if __GNUC__ || __clang__
else if constexpr (std::is_fundamental_v<type> || std::is_enum_v<type> || is_integral128_v<type>) {
writer_.write((char *)&item, sizeof(type));
}
#else
else if constexpr (std::is_fundamental_v<type> || std::is_enum_v<type>) {
writer_.write((char *)&item, sizeof(type));
}
#endif
else if constexpr (detail::varint_t<type>) {
detail::serialize_varint(writer_, item);
}
Expand Down Expand Up @@ -2464,11 +2444,7 @@ class unpacker {
else if constexpr (std::is_same_v<type, std::monostate>) {
// do nothing
}
#if __GNUC__ || __clang__
else if constexpr (std::is_fundamental_v<type> || std::is_enum_v<type> || is_integral128_v<type>) {
#else
else if constexpr (std::is_fundamental_v<type> || std::is_enum_v<type>) {
#endif
if constexpr (NotSkip) {
if (!reader_.read((char *)&item, sizeof(type))) [[unlikely]] {
return struct_pack::errc::no_buffer_space;
Expand Down
23 changes: 23 additions & 0 deletions src/struct_pack/tests/test_serialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<test_int_128>{{i, j}, {-1 * i, j + UINT64_MAX}};
auto buffer = struct_pack::serialize(vec);
auto result = struct_pack::deserialize<std::vector<test_int_128>>(buffer);
CHECK(result == vec);
CHECK(struct_pack::detail::is_trivial_serializable<test_int_128>::value);
}

TEST_CASE("test uint128") {}
#endif

#if __cpp_lib_span >= 202002L

Expand Down
10 changes: 6 additions & 4 deletions website/docs/en/struct_pack/struct_pack_type_system.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down

0 comments on commit 5888fa0

Please sign in to comment.