12 using TRawPtr = std::shared_ptr<void>;
13 TRawPtr Data =
nullptr;
15 enum class PointerType {
22constexpr bool is_pod_v = std::is_trivially_copyable_v<T> && std::is_standard_layout_v<T>;
24template<
typename T,
typename =
void>
30 std::is_trivial_v<T> &&
31 std::is_standard_layout_v<T>
32>> : std::false_type {};
38constexpr size_t sizeof_data() {
39 if constexpr (has_data_members_v<T>) {
46template<
typename T,
typename TAllocator>
47typename std::enable_if_t<is_pod_v<T>,
TBlob>
48SerializePodNear(T&& message, TAllocator& alloc)
50 constexpr uint32_t size = sizeof_data<T>();
52 TBlob::TRawPtr rawPtr =
nullptr;
54 if constexpr (size > 0) {
55 auto* data = alloc.Acquire(size);
56 new (data) T(std::move(message));
58 rawPtr = TBlob::TRawPtr(data, [&alloc](
void* ptr) {
63 return TBlob{std::move(rawPtr), size, TBlob::PointerType::Near};
66template<
typename T,
typename TAllocator>
67typename std::enable_if_t<!is_pod_v<T>,
TBlob>
68SerializeNonPodNear(T&& message, TAllocator& alloc)
70 T* obj =
new T(std::forward<T>(message));
72 auto rawPtr = TBlob::TRawPtr(obj, [](
void* ptr) {
73 delete reinterpret_cast<T*
>(ptr);
76 return TBlob{std::move(rawPtr),
sizeof(T), TBlob::PointerType::Near};
79template<
typename T,
typename TAllocator>
80TBlob SerializeNear(T&& message, TAllocator& alloc)
82 if constexpr (is_pod_v<T>) {
83 return SerializePodNear<T>(std::forward<T>(message), alloc);
85 return SerializeNonPodNear<T>(std::forward<T>(message), alloc);
90void SerializeToStream(
const T& obj, std::ostringstream& oss)
92 static_assert(
sizeof(T) == 0,
"Serialization not implemented for this type");
98 if constexpr (is_pod_v<T>) {
99 blob.Type = TBlob::PointerType::Far;
102 T* obj =
reinterpret_cast<T*
>(blob.Data.get());
103 std::ostringstream oss;
104 SerializeToStream(*obj, oss);
105 void* data = ::operator
new(oss.str().size());
106 std::memcpy(data, oss.str().data(), oss.str().size());
107 auto rawPtr = TBlob::TRawPtr(data, [](
void* ptr) {
108 ::operator
delete(ptr);
110 return TBlob{std::move(rawPtr),
static_cast<uint32_t
>(oss.str().size()), TBlob::PointerType::Far};
115auto DeserializeNear(
const TBlob& blob) -> std::conditional_t<sizeof_data<T>() == 0, T, T&> {
116 if constexpr (sizeof_data<T>() == 0) {
119 return *
reinterpret_cast<T*
>(blob.Data.get());
124void DeserializeFromStream(T& obj, std::istringstream& iss) {
125 static_assert(
sizeof(T) == 0,
"Deserialization not implemented for this type");
129auto DeserializeFar(
const TBlob& blob) -> std::conditional_t<is_pod_v<T> && (sizeof_data<T>()>0), T&, T> {
130 if constexpr (is_pod_v<T>) {
131 return DeserializeNear<T>(blob);
133 std::istringstream iss(std::string(
reinterpret_cast<const char*
>(blob.Data.get()), blob.Size));
135 DeserializeFromStream(obj, iss);
Definition messages.hpp:11
Definition messages.hpp:25