Skip to content

Commit

Permalink
Removed explicit members since reflection of types avoids serializing…
Browse files Browse the repository at this point in the history
… padding.
  • Loading branch information
eyalz800 committed Dec 19, 2021
1 parent 50ffbb7 commit 9255270
Show file tree
Hide file tree
Showing 3 changed files with 0 additions and 226 deletions.
34 changes: 0 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,40 +208,6 @@ auto [data, in] = zpp::bits::data_in();
auto [data, out] = zpp::bits::data_out();
```
* If your object and its subobjects recursively can just be byte copied, i.e don't have references or pointers or non
trivially copyable subobjects (more accurately, your object fits into the bit cast constexpr requirements), then you don't need to specify the number of members and
serializing your object becomes a `memcpy` operation. Unless of course you define an explicit serialization function in which
case the members are serialized one by one separately.
```cpp
struct point
{
int x;
int y;
};
auto [data, out] = zpp::bits::data_out();
out(point{1337, 1338});
```
The above is serializable/deserializable without any modification by using a `memcpy` operation.
This has the advantage of better performance most of the times, but the disadvantage is that the format becomes less portable
due to potential padding bytes.

When using plain `zpp::bits::members` it does its best to detect if there is padding for your
type or not and decides this automatically, but to be more explicit, you can either define the explicit serialization function or
use `zpp::bits::explicit_members` and provide the number of members:
```cpp
struct requires_padding
{
using serialize = zpp::bits::explicit_members<2>;

std::byte x;
int y;
};
```
If you are using automatic member detection as per `ZPP_BITS_AUTODETECT_MEMBERS_MODE=1`, you may leave the
angle brackets empty as in `zpp::bits::members<>` or `zpp::bits::explicit_members<>`.

* Archives can be constructed from either one of the byte types:
```cpp
// Either one of these work with the below.
Expand Down
165 changes: 0 additions & 165 deletions test/src/test_byte_serializable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,38 +41,6 @@ struct members_integers_outside_auto
auto serialize(const members_integers_outside_auto &)
-> zpp::bits::members<>;

struct explicit_integers
{
using serialize = zpp::bits::explicit_members<2>;
int x;
int y;
};

struct explicit_integers_outside
{
int x;
int y;
};

auto serialize(const explicit_integers_outside &)
-> zpp::bits::explicit_members<2>;

struct explicit_integers_auto
{
using serialize = zpp::bits::explicit_members<>;
int x;
int y;
};

struct explicit_integers_outside_auto
{
int x;
int y;
};

auto serialize(const explicit_integers_outside_auto &)
-> zpp::bits::explicit_members<>;

struct ref
{
int & x;
Expand Down Expand Up @@ -128,8 +96,6 @@ constexpr void serialize(auto & archive,
static_assert(zpp::bits::concepts::byte_serializable<int[5]>);
static_assert(zpp::bits::concepts::byte_serializable<members_integers>);
static_assert(zpp::bits::concepts::byte_serializable<members_integers_outside>);
static_assert(zpp::bits::concepts::byte_serializable<explicit_integers>);
static_assert(zpp::bits::concepts::byte_serializable<explicit_integers_outside>);
static_assert(!zpp::bits::concepts::byte_serializable<ref>);
static_assert(!zpp::bits::concepts::byte_serializable<pointer>);
static_assert(!zpp::bits::concepts::byte_serializable<vector>);
Expand Down Expand Up @@ -157,8 +123,6 @@ static_assert(zpp::bits::concepts::byte_serializable<stdarray_array>);
static_assert(zpp::bits::concepts::byte_serializable<integers>);

#if ZPP_BITS_AUTODETECT_MEMBERS_MODE > 0
static_assert(zpp::bits::concepts::byte_serializable<explicit_integers_auto>);
static_assert(zpp::bits::concepts::byte_serializable<explicit_integers_outside_auto>);
static_assert(zpp::bits::concepts::byte_serializable<members_integers_auto>);
static_assert(zpp::bits::concepts::byte_serializable<members_integers_outside_auto>);
#endif
Expand Down Expand Up @@ -368,69 +332,6 @@ TEST(byte_serializable, members_requires_padding_outside)
EXPECT_EQ(s.i32, 0x1337);
}

struct explicit_requires_padding
{
using serialize = zpp::bits::explicit_members<2>;
std::byte b{};
std::int32_t i32{};
};

TEST(byte_serializable, explicit_requires_padding)
{
static_assert(!zpp::bits::concepts::byte_serializable<
explicit_requires_padding>);
static_assert(sizeof(requires_padding) ==
sizeof(explicit_requires_padding));
static_assert(sizeof(explicit_requires_padding) > 5);

auto [data, in, out] = zpp::bits::data_in_out();
out(explicit_requires_padding{std::byte{0x25}, 0x1337}).or_throw();

EXPECT_EQ(data.size(), std::size_t{5});
EXPECT_EQ(hexlify(data),
"25"
"37130000");

explicit_requires_padding s;
in(s).or_throw();
EXPECT_EQ(in.position(), std::size_t{5});
EXPECT_EQ(s.b, std::byte{0x25});
EXPECT_EQ(s.i32, 0x1337);
}

struct explicit_requires_padding_outside
{
std::byte b{};
std::int32_t i32{};
};

auto serialize(const explicit_requires_padding_outside &)
-> zpp::bits::explicit_members<2>;

TEST(byte_serializable, explicit_requires_padding_outside)
{
static_assert(!zpp::bits::concepts::byte_serializable<
explicit_requires_padding_outside>);
static_assert(sizeof(requires_padding) ==
sizeof(explicit_requires_padding_outside));
static_assert(sizeof(explicit_requires_padding_outside) > 5);

auto [data, in, out] = zpp::bits::data_in_out();
out(explicit_requires_padding_outside{std::byte{0x25}, 0x1337})
.or_throw();

EXPECT_EQ(data.size(), std::size_t{5});
EXPECT_EQ(hexlify(data),
"25"
"37130000");

explicit_requires_padding_outside s;
in(s).or_throw();
EXPECT_EQ(in.position(), std::size_t{5});
EXPECT_EQ(s.b, std::byte{0x25});
EXPECT_EQ(s.i32, 0x1337);
}

#if ZPP_BITS_AUTODETECT_MEMBERS_MODE > 0
struct members_requires_padding_auto
{
Expand Down Expand Up @@ -462,40 +363,6 @@ TEST(byte_serializable, members_requires_padding_auto)
EXPECT_EQ(s.i32, 0x1337);
}

struct explicit_requires_padding_auto
{
using serialize = zpp::bits::explicit_members<>;
std::byte b{};
std::int32_t i32{};
};

static_assert(sizeof(requires_padding) ==
sizeof(explicit_requires_padding_auto));

TEST(byte_serializable, explicit_requires_padding_auto)
{
static_assert(!zpp::bits::concepts::byte_serializable<
explicit_requires_padding_auto>);
static_assert(sizeof(requires_padding) ==
sizeof(explicit_requires_padding_auto));
static_assert(sizeof(explicit_requires_padding_auto) > 5);

auto [data, in, out] = zpp::bits::data_in_out();
out(explicit_requires_padding_auto{std::byte{0x25}, 0x1337})
.or_throw();

EXPECT_EQ(data.size(), std::size_t{5});
EXPECT_EQ(hexlify(data),
"25"
"37130000");

explicit_requires_padding_auto s;
in(s).or_throw();
EXPECT_EQ(in.position(), std::size_t{5});
EXPECT_EQ(s.b, std::byte{0x25});
EXPECT_EQ(s.i32, 0x1337);
}

struct members_requires_padding_outside_auto
{
std::byte b{};
Expand Down Expand Up @@ -529,38 +396,6 @@ TEST(byte_serializable, members_requires_padding_outside_auto)
EXPECT_EQ(s.i32, 0x1337);
}

struct explicit_requires_padding_outside_auto
{
std::byte b{};
std::int32_t i32{};
};

auto serialize(const explicit_requires_padding_outside_auto &)
-> zpp::bits::explicit_members<>;

TEST(byte_serializable, explicit_requires_padding_outside_auto)
{
static_assert(!zpp::bits::concepts::byte_serializable<
explicit_requires_padding_outside_auto>);
static_assert(sizeof(requires_padding) ==
sizeof(explicit_requires_padding_outside_auto));
static_assert(sizeof(explicit_requires_padding_outside_auto) > 5);

auto [data, in, out] = zpp::bits::data_in_out();
out(explicit_requires_padding_outside_auto{std::byte{0x25}, 0x1337})
.or_throw();

EXPECT_EQ(data.size(), std::size_t{5});
EXPECT_EQ(hexlify(data),
"25"
"37130000");

explicit_requires_padding_outside_auto s;
in(s).or_throw();
EXPECT_EQ(in.position(), std::size_t{5});
EXPECT_EQ(s.b, std::byte{0x25});
EXPECT_EQ(s.i32, 0x1337);
}
#endif // ZPP_BITS_AUTODETECT_MEMBERS_MODE > 0

} // namespace test_byte_serializable
27 changes: 0 additions & 27 deletions zpp_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@ struct members
constexpr static std::size_t value = Count;
};

template <std::size_t Count = std::numeric_limits<std::size_t>::max()>
struct explicit_members
{
constexpr static std::size_t value = Count;
};

namespace concepts
{
namespace detail
Expand Down Expand Up @@ -400,16 +394,6 @@ struct access
std::size_t>::max();
}) {
return type::serialize::value;
} else if constexpr (requires {
requires std::same_as<
typename type::serialize,
explicit_members<
type::serialize::value>>;
requires type::serialize::value !=
std::numeric_limits<
std::size_t>::max();
}) {
return type::serialize::value;
} else if constexpr (requires(Type && item) {
requires std::same_as<
decltype(serialize(item)),
Expand All @@ -421,17 +405,6 @@ struct access
std::size_t>::max();
}) {
return decltype(serialize(std::declval<type>()))::value;
} else if constexpr (requires(Type && item) {
requires std::same_as<
decltype(serialize(item)),
explicit_members<decltype(serialize(
item))::value>>;
requires decltype(serialize(
item))::value !=
std::numeric_limits<
std::size_t>::max();
}) {
return decltype(serialize(std::declval<type>()))::value;
#if ZPP_BITS_AUTODETECT_MEMBERS_MODE > 0
#if ZPP_BITS_AUTODETECT_MEMBERS_MODE == 1
// clang-format off
Expand Down

0 comments on commit 9255270

Please sign in to comment.