Skip to content

Commit

Permalink
add elastic size to get bytes of member (#51)
Browse files Browse the repository at this point in the history
  • Loading branch information
kcwl committed Mar 19, 2024
1 parent f19cac4 commit 4b917fe
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 48 deletions.
7 changes: 7 additions & 0 deletions include/elastic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "elastic/access.hpp"
#include "elastic/binary_archive.hpp"
#include "elastic/macro_expand.hpp"
#include "elastic/size.hpp"

namespace elastic
{
Expand All @@ -24,6 +25,12 @@ namespace elastic

return !ia.fail();
}

template<typename _Ty>
std::size_t size(const _Ty& t)
{
return element_size(t);
}
} // namespace elastic

#ifndef ELASTIC_ACCESS
Expand Down
34 changes: 3 additions & 31 deletions include/elastic/serialize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,9 @@
#include "access.hpp"
#include "reflect.hpp"
#include "type_traits.hpp"

#include "zig_zag.hpp"
#include <vector>

namespace
{
static constexpr int32_t zig_zag_bit = 7;

template <elastic::integer_t _Ty>
elastic::zig_zag_t<_Ty> zigzag_encode(_Ty value)
{
using value_type = elastic::zig_zag_t<_Ty>;

using remove_unsigned_type = elastic::remove_unsigned_t<_Ty>;

constexpr auto size = sizeof(_Ty) * 8 - 1;

return static_cast<remove_unsigned_type>(value) << 1 ^ static_cast<remove_unsigned_type>(value) >> size;
}

template <elastic::integer_t _Ty>
_Ty zigzag_decode(elastic::zig_zag_t<_Ty> value)
{
return static_cast<_Ty>((value >> 1) ^ (~(value & 1) + 1));
}

} // namespace

namespace elastic
{
namespace detail
Expand Down Expand Up @@ -80,18 +56,14 @@ namespace elastic
template <pod_t _Ty, typename _Archive>
_Ty deserialize(_Archive& ar)
{
_Ty t{};

constexpr auto N = reflect::tuple_size_v<_Ty>;

using Indices = std::make_index_sequence<N>;

auto func = []<std::size_t... I>(_Archive& ar, std::index_sequence<I...>)
auto func = []<std::size_t... I>(_Archive& ar, std::index_sequence<I...>) mutable
{ return _Ty{ deserialize<reflect::elemet_t<_Ty, I>>(ar)... }; };

t = func(ar, Indices{});

return t;
return std::move(func(ar, Indices{}));
}

template <sequence_t _Ty, typename _Archive>
Expand Down
63 changes: 63 additions & 0 deletions include/elastic/size.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#pragma once
#include "zig_zag.hpp"

namespace elastic
{
template <integer_t _Ty>
std::size_t element_size(const _Ty& t)
{
auto temp = zigzag_encode(t);
std::size_t size = 1;

while ((temp >>= zig_zag_bit) != 0)
size++;

return size;
}

template <float_point_t _Ty>
std::size_t element_size(const _Ty&)
{
return sizeof(_Ty);
}

template<sequence_t _Ty>
std::size_t element_size(const _Ty& t);

template<aggregate_class_t _Ty>
std::size_t element_size(const _Ty& t)
{
constexpr auto N = reflect::tuple_size_v<std::remove_cvref_t<_Ty>>;

auto func = [&]<std::size_t... I>(std::index_sequence<I...>)
{
return (element_size(reflect::get<I>(t)) + ...);
};

return func(std::make_index_sequence<N>{});
}

template <sequence_t _Ty>
std::size_t element_size(const _Ty& t)
{
using type = std::remove_cvref_t<_Ty>;

std::size_t size = 0;

using value_type = typename type::value_type;

if constexpr (sizeof(value_type) == 1)
{
size = t.size();
}
else
{
for (const auto& value : t)
{
size += element_size(value);
}
}

return size;
}
} // namespace elastic
3 changes: 3 additions & 0 deletions include/elastic/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,7 @@ namespace elastic
template <typename _Ty>
concept swap_t = requires(_Ty value) { value.swap(value); };

template<typename _Ty>
concept aggregate_class_t = class_t<std::remove_cvref_t<_Ty>> && std::is_aggregate_v<std::remove_cvref_t<_Ty>>;

} // namespace elastic
25 changes: 25 additions & 0 deletions include/elastic/zig_zag.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once
#include "type_traits.hpp"

namespace elastic
{
inline static constexpr int32_t zig_zag_bit = 7;

template <elastic::integer_t _Ty>
elastic::zig_zag_t<_Ty> zigzag_encode(_Ty value)
{
using value_type = elastic::zig_zag_t<_Ty>;

using remove_unsigned_type = elastic::remove_unsigned_t<_Ty>;

constexpr auto size = sizeof(_Ty) * 8 - 1;

return static_cast<remove_unsigned_type>(value) << 1 ^ static_cast<remove_unsigned_type>(value) >> size;
}

template <elastic::integer_t _Ty>
_Ty zigzag_decode(elastic::zig_zag_t<_Ty> value)
{
return static_cast<_Ty>((value >> 1) ^ (~(value & 1) + 1));
}
}
51 changes: 42 additions & 9 deletions test/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ struct animal
bool c;
};


TEST(io, elastic_type)
{
{
Expand All @@ -26,6 +25,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

char a_out{};

elastic::from_binary(a_out, buf);
Expand All @@ -40,6 +41,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

int8_t a_out{};

elastic::from_binary(a_out, buf);
Expand All @@ -54,6 +57,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

uint8_t a_out{};

elastic::from_binary(a_out, buf);
Expand All @@ -68,6 +73,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

int16_t a_out{};

elastic::from_binary(a_out, buf);
Expand All @@ -81,6 +88,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

uint16_t a_out{};

elastic::from_binary(a_out, buf);
Expand All @@ -94,6 +103,7 @@ TEST(io, elastic_type)
int32_t a_in = (std::numeric_limits<int32_t>::max)();

elastic::to_binary(a_in, buf);
EXPECT_TRUE(elastic::size(a_in) == buf.size());

int32_t a_out{};

Expand All @@ -108,6 +118,7 @@ TEST(io, elastic_type)
uint32_t a_in = (std::numeric_limits<uint32_t>::max)();

elastic::to_binary(a_in, buf);
EXPECT_TRUE(elastic::size(a_in) == buf.size());

uint32_t a_out{};

Expand All @@ -123,6 +134,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

int64_t a_out{};

elastic::from_binary(a_out, buf);
Expand All @@ -137,6 +150,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

uint64_t a_out{};

elastic::from_binary(a_out, buf);
Expand All @@ -147,10 +162,12 @@ TEST(io, elastic_type)
{
elastic::flex_buffer_t buf;

int64_t a_in = -10;
int64_t a_in = -10;

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

int64_t a_out{};

elastic::from_binary(a_out, buf);
Expand All @@ -169,6 +186,8 @@ TEST(io, elastic_type)

elastic::to_binary(color::red, buf);

EXPECT_TRUE(elastic::size(color::red) == buf.size());

color cr{};

elastic::from_binary(cr, buf);
Expand All @@ -183,6 +202,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == 12);

std::string a_out{};

elastic::from_binary(a_out, buf);
Expand All @@ -197,6 +218,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

bool a_out = true;

elastic::from_binary(a_out, buf);
Expand All @@ -212,6 +235,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == 5);

std::vector<std::byte> a_out{};

elastic::from_binary(a_out, buf);
Expand All @@ -221,18 +246,19 @@ TEST(io, elastic_type)

{
std::vector<person> pers{};
person per = { 1,"Lancy" };
person per = { 1, "Lancy" };

pers.push_back(per);
pers.push_back(per);
pers.push_back(per);


elastic::flex_buffer_t buf;

elastic::to_binary(pers, buf);

std::vector<person> pers_copy{};
EXPECT_TRUE(elastic::size(pers) == 18);

std::vector<person> pers_copy{};

elastic::from_binary(pers_copy, buf);

Expand All @@ -248,16 +274,18 @@ TEST(io, elastic_type)

{
std::vector<animal> animals{};
animals.push_back({ 1,'2',0 });
animals.push_back({ 2,'2',0 });
animals.push_back({ 3,'2',0 });
animals.push_back({ 1, '2', 0 });
animals.push_back({ 2, '2', 0 });
animals.push_back({ 3, '2', 0 });

std::vector<animal> animal_copys{};

elastic::flex_buffer_t buf;

elastic::to_binary(animals, buf);

EXPECT_TRUE(elastic::size(animals) == 9);

elastic::from_binary(animal_copys, buf);

auto size = animal_copys.size();
Expand All @@ -266,7 +294,8 @@ TEST(io, elastic_type)

for (std::size_t i = 0; i < size; ++i)
{
EXPECT_TRUE(animal_copys[i].a == animals[i].a && animal_copys[i].b == animals[i].b && animal_copys[i].c == animals[i].c);
EXPECT_TRUE(animal_copys[i].a == animals[i].a && animal_copys[i].b == animals[i].b &&
animal_copys[i].c == animals[i].c);
}
}

Expand All @@ -277,6 +306,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

double a_out;

elastic::from_binary(a_out, buf);
Expand All @@ -291,6 +322,8 @@ TEST(io, elastic_type)

elastic::to_binary(a_in, buf);

EXPECT_TRUE(elastic::size(a_in) == buf.size());

float a_out;

elastic::from_binary(a_out, buf);
Expand Down
Loading

0 comments on commit 4b917fe

Please sign in to comment.