Created
March 26, 2019 16:39
-
-
Save ChemistAion/7d7a9b1a64e54def061acb48e498f985 to your computer and use it in GitHub Desktop.
cista playground on target_use_serialized_size branch with custom type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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