Skip to content

Instantly share code, notes, and snippets.

@ChemistAion
Created March 26, 2019 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChemistAion/7d7a9b1a64e54def061acb48e498f985 to your computer and use it in GitHub Desktop.
Save ChemistAion/7d7a9b1a64e54def061acb48e498f985 to your computer and use it in GitHub Desktop.
cista playground on target_use_serialized_size branch with custom type
#include "doctest.h"
#include <cinttypes>
#include <memory>
#include <vector>
#include "cista.h"
using namespace cista;
using namespace cista::raw;
struct custom_struct {
using type = typename int;
std::vector<type> std_vector;
////////////////////////////////////////////////////////////////////////////////
struct metadata {
std::size_t count = 0;
std::size_t offset = 0;
} mutable metadata_;
};
template <>
static inline constexpr size_t cista::serialized_size<custom_struct>() {
return sizeof(custom_struct::metadata);
}
struct complex_struct {
vector<custom_struct> cista_vector;
};
template <typename Ctx>
void serialize(Ctx& ctx, custom_struct const* origin, offset_t const pos) {
auto const alignment = std::alignment_of_v<custom_struct::type>;
origin->metadata_.count = origin->std_vector.size();
origin->metadata_.offset = ctx.write(nullptr, 0, alignment) - pos;
// serialize metadata
ctx.write(pos, origin->metadata_);
// serialize the data
auto const size =
origin->std_vector.empty()
? NULLPTR_OFFSET
: (sizeof(custom_struct::type) * origin->metadata_.count);
ctx.write(origin->std_vector.data(), size, alignment);
}
custom_struct* unchecked_deserialize(deserialization_context const& ctx,
custom_struct* origin) {
auto stream = reinterpret_cast<std::uint8_t*>(origin);
auto metadata = reinterpret_cast<custom_struct::metadata*>(stream);
auto data = reinterpret_cast<custom_struct::type*>(stream + metadata->offset);
////////////////////////////////////////////////////////////////////////////////
using allocator = std::allocator<custom_struct>;
using allocator_traits = std::allocator_traits<allocator>;
allocator alloc;
auto result = allocator_traits::allocate(alloc, 1);
allocator_traits::construct(alloc, result);
result->std_vector.reserve(metadata->count);
result->std_vector.assign(data, data + metadata->count);
////////////////////////////////////////////////////////////////////////////////
return result;
}
template <>
custom_struct* cista::raw::unchecked_deserialize<custom_struct>(uint8_t* from, uint8_t* to) {
deserialization_context c{from, to};
auto origin = reinterpret_cast<custom_struct*>(from);
return unchecked_deserialize(c, origin);
}
template <>
void cista::raw::unchecked_deserialize<custom_struct>(deserialization_context const& c, vector<custom_struct>* el) {
el->el_ = c.deserialize<custom_struct*>(el->el_);
auto offset = reinterpret_cast<std::uint8_t*>(el->el_);
auto size = el->size();
while (size-- > 0)
{
auto element = reinterpret_cast<custom_struct*>(offset);
auto result = unchecked_deserialize(c, element);
offset += serialized_size<custom_struct>();
}
}
TEST_CASE("custom struct basic tests") {
custom_struct custom1;
custom_struct custom2;
custom_struct custom3;
custom1.std_vector = {1, 22, 333, 4444, 55555,
666666, 7777777, 88888888, 999999999};
custom2.std_vector = {-1, 1, -999999999, 999999999};
custom3.std_vector = {2, 3, 5, 7, 11, 13};
////////////////////////////////////////////////////////////////////////////////
{
byte_buf buf;
{
auto copy = custom1;
buf = serialize(copy);
}
{
auto const output = unchecked_deserialize<custom_struct>(buf);
CHECK(output->std_vector == custom1.std_vector);
}
{
auto copy = custom2;
buf = serialize(copy);
}
{
auto const output = unchecked_deserialize<custom_struct>(buf);
CHECK(output->std_vector == custom2.std_vector);
}
{
auto copy = custom3;
buf = serialize(copy);
}
{
auto const output = unchecked_deserialize<custom_struct>(buf);
CHECK(output->std_vector == custom3.std_vector);
}
}
////////////////////////////////////////////////////////////////////////////////
{
byte_buf buf;
{
auto copy1 = custom1;
auto copy2 = custom2;
auto copy3 = custom3;
complex_struct complex;
complex.cista_vector.push_back(copy1);
complex.cista_vector.push_back(copy2);
complex.cista_vector.push_back(copy3);
buf = serialize(complex);
}
auto const output = unchecked_deserialize<complex_struct>(buf);
}
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment