ZeroErr
Loading...
Searching...
No Matches
serialization.h
Go to the documentation of this file.
1#pragma once
3
5
6#include <cstdint>
7#include <cstring>
8#include <string>
9#include <type_traits>
10#include <vector>
11
13
14namespace zeroerr {
15
43struct IRObject {
44 IRObject() { memset(this, 0, sizeof(IRObject)); }
46 IRObject(const IRObject& other) { *this = other; }
47 IRObject(IRObject&& other) { *this = std::move(other); }
48 IRObject& operator=(const IRObject& other) {
49 std::memcpy(this, &other, sizeof(IRObject));
50 return *this;
51 }
53 std::memcpy(this, &other, sizeof(IRObject));
54 std::memset(&other, 0, sizeof(IRObject));
55 return *this;
56 }
57
59
60 union {
61 int64_t i;
62 double f;
63 char* s;
64 char ss[8];
65 IRObject* o; // first must be the number of elements
66 };
67 char others[7];
68 unsigned char type;
69
70 template <typename T>
71 typename std::enable_if<std::is_integral<T>::value, T>::type GetScalar() {
72 return static_cast<T>(i);
73 }
74
75 template <typename T>
76 typename std::enable_if<std::is_floating_point<T>::value, T>::type GetScalar() {
77 return static_cast<T>(f);
78 }
79
80 template <typename T>
81 typename std::enable_if<std::is_enum<T>::value, T>::type GetScalar() {
82 return GetScalar<typename std::underlying_type<T>::type>();
83 }
84
85 template <typename T>
86 typename std::enable_if<std::is_same<T, std::string>::value, T>::type GetScalar() {
87 if (type == Type::String)
88 return std::string(s);
89 else if (type == Type::ShortString)
90 return std::string(ss);
91 return "";
92 }
93
94 template <typename T>
95 typename std::enable_if<std::is_integral<T>::value, void>::type SetScalar(T val) {
96 i = static_cast<int64_t>(val);
98 }
99
100 template <typename T>
101 typename std::enable_if<std::is_floating_point<T>::value, void>::type SetScalar(T val) {
102 f = static_cast<double>(val);
104 }
105
106 template <typename T>
107 typename std::enable_if<std::is_enum<T>::value, void>::type SetScalar(T val) {
108 SetScalar<typename std::underlying_type<T>::type>(val);
109 }
110
111 template <typename T>
112 typename std::enable_if<std::is_same<T, std::string>::value, void>::type SetScalar(T val) {
113 size_t size = val.size();
114 if (size > 14) {
115 s = alloc_str(size);
116 strcpy(s, val.c_str());
118 } else {
119 strcpy(ss, val.c_str());
120 ss[size] = 0;
122 }
123 }
124
125 void SetScalar(const IRObject& obj) { *this = obj; }
126
127 struct Childrens {
128 int64_t size;
130 };
132 if (type != Type::Object) return {0, nullptr};
133 return {o->i, o + 1};
134 }
135
136 void SetChildren(IRObject* children) {
137 o = children - 1;
139 }
140
141 // ================================================================
142
143 template <typename T>
144 static
145 typename std::enable_if<std::is_integral<T>::value || std::is_floating_point<T>::value ||
146 std::is_same<T, std::string>::value || std::is_enum<T>::value,
148 FromCorpus(T val) {
149 IRObject obj;
150 obj.SetScalar(val);
151 return obj;
152 }
153
154 template <typename T>
155 static typename std::enable_if<
156 detail::is_container<T>::value && !std::is_same<T, std::string>::value, IRObject>::type
157 FromCorpus(const T& val) {
158 IRObject* children = alloc(val.size());
159 IRObject obj;
160 obj.SetChildren(children);
161
162 for (const auto& elem : val) {
163 *children++ = IRObject::FromCorpus(elem);
164 }
165 return obj;
166 }
167
168
169 template <class TupType, unsigned... I>
170 inline static void handle_tuple(const TupType& _tup, IRObject* children, detail::seq<I...>) {
171 int _[] = {((children + I)->SetScalar(FromCorpus(std::get<I>(_tup))), 0)...};
172 (void)_;
173 }
174
175 template <typename... Args>
176 static IRObject FromCorpus(const std::tuple<Args...>& val) {
177 unsigned size = sizeof...(Args);
178 IRObject obj;
179 IRObject* children = alloc(size);
180 obj.SetChildren(children);
181
182 handle_tuple(val, children, detail::gen_seq<sizeof...(Args)>{});
183 return obj;
184 }
185
186 template <typename T1, typename T2>
187 static IRObject FromCorpus(const std::pair<T1, T2>& val) {
188 IRObject obj;
189 IRObject* children = alloc(2);
190 obj.SetChildren(children);
191 children[0] = IRObject::FromCorpus(val.first);
192 children[1] = IRObject::FromCorpus(val.second);
193 return obj;
194 }
195
196 template <typename T>
197 static typename std::enable_if<std::is_integral<T>::value || std::is_enum<T>::value, T>::type
199 if (obj.type != IRObject::Int) {
200 throw std::runtime_error("Invalid type conversion.");
201 }
202 return obj.GetScalar<T>();
203 }
204
205 template <typename T>
206 static typename std::enable_if<std::is_floating_point<T>::value, T>::type ToCorpus(
207 IRObject obj) {
208 if (obj.type != IRObject::Float) {
209 throw std::runtime_error("Invalid type conversion.");
210 }
211 return obj.GetScalar<T>();
212 }
213
214 template <typename T>
215 static typename std::enable_if<std::is_same<T, std::string>::value, T>::type ToCorpus(
216 IRObject obj) {
217 if (obj.type != IRObject::String && obj.type != IRObject::ShortString) {
218 throw std::runtime_error("Invalid type conversion.");
219 }
220 return obj.GetScalar<T>();
221 }
222
223
224 template <typename TupType, unsigned... I>
225 static TupType parse_tuple(IRObject* children, detail::seq<I...>) {
226 return std::make_tuple(
227 ToCorpus<typename std::tuple_element<I, TupType>::type>(*(children + I))...);
228 }
229
230 template <typename T>
231 static typename std::enable_if<
232 detail::is_container<T>::value && !std::is_same<T, std::string>::value, T>::type
234 if (obj.type != IRObject::Object) {
235 throw std::runtime_error("Invalid type conversion.");
236 }
237
238 auto c = obj.GetChildren();
239
240 T val;
241 for (int i = 0; i < c.size; i++) {
242 val.insert(val.end(), ToCorpus<typename T::value_type>(c.children[i]));
243 }
244 return val;
245 }
246
247
248 template <typename T>
249 static typename std::enable_if<detail::is_specialization<T, std::tuple>::value, T>::type
251 if (obj.type != IRObject::Object || obj.GetChildren().size != std::tuple_size<T>::value) {
252 throw std::runtime_error("Invalid type conversion.");
253 }
254 return parse_tuple<T>(obj.o + 1, detail::gen_seq<std::tuple_size<T>::value>{});
255 }
256
257 template <typename T>
258 static typename std::enable_if<detail::is_specialization<T, std::pair>::value, T>::type
260 if (obj.type != IRObject::Object || obj.GetChildren().size != 2) {
261 throw std::runtime_error("Invalid type conversion.");
262 }
263 return std::make_pair(ToCorpus<typename T::first_type>(obj.GetChildren().children[0]),
264 ToCorpus<typename T::second_type>(obj.GetChildren().children[1]));
265 }
266
267
268 static char* alloc_str(size_t size);
269 static IRObject* alloc(size_t size);
270
271 // Serialize the object as a string.
272 static std::string ToString(IRObject obj);
273 static IRObject FromString(std::string str);
274
275 static std::vector<uint8_t> ToBinary(IRObject obj);
276 static IRObject FromBinary(std::vector<uint8_t> bin);
277};
278
279
280} // namespace zeroerr
281
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_POP
Definition config.h:268
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH
Definition config.h:220
Definition benchmark.cpp:17
Definition serialization.h:127
int64_t size
Definition serialization.h:128
IRObject * children
Definition serialization.h:129
Interface for serializable objects.
Definition serialization.h:43
static IRObject FromBinary(std::vector< uint8_t > bin)
Definition serialization.cpp:153
static std::enable_if< detail::is_container< T >::value &&!std::is_same< T, std::string >::value, T >::type ToCorpus(IRObject obj)
Definition serialization.h:233
static void handle_tuple(const TupType &_tup, IRObject *children, detail::seq< I... >)
Definition serialization.h:170
unsigned char type
Definition serialization.h:68
IRObject()
Definition serialization.h:44
void SetChildren(IRObject *children)
Definition serialization.h:136
static IRObject FromCorpus(const std::pair< T1, T2 > &val)
Definition serialization.h:187
IRObject & operator=(IRObject &&other)
Definition serialization.h:52
std::enable_if< std::is_enum< T >::value, void >::type SetScalar(T val)
Definition serialization.h:107
Childrens GetChildren()
Definition serialization.h:131
static TupType parse_tuple(IRObject *children, detail::seq< I... >)
Definition serialization.h:225
void SetScalar(const IRObject &obj)
Definition serialization.h:125
static std::string ToString(IRObject obj)
Definition serialization.cpp:135
static std::vector< uint8_t > ToBinary(IRObject obj)
Definition serialization.cpp:148
static std::enable_if< std::is_integral< T >::value||std::is_enum< T >::value, T >::type ToCorpus(IRObject obj)
Definition serialization.h:198
static std::enable_if< std::is_floating_point< T >::value, T >::type ToCorpus(IRObject obj)
Definition serialization.h:206
IRObject * o
Definition serialization.h:65
static IRObject * alloc(size_t size)
Definition serialization.cpp:7
std::enable_if< std::is_integral< T >::value, void >::type SetScalar(T val)
Definition serialization.h:95
static IRObject FromString(std::string str)
Definition serialization.cpp:141
IRObject(IRObject &&other)
Definition serialization.h:47
char others[7]
Definition serialization.h:67
std::enable_if< std::is_floating_point< T >::value, T >::type GetScalar()
Definition serialization.h:76
static std::enable_if< std::is_same< T, std::string >::value, T >::type ToCorpus(IRObject obj)
Definition serialization.h:215
std::enable_if< std::is_floating_point< T >::value, void >::type SetScalar(T val)
Definition serialization.h:101
static char * alloc_str(size_t size)
Definition serialization.cpp:13
~IRObject()
Definition serialization.h:45
char * s
Definition serialization.h:63
double f
Definition serialization.h:62
IRObject(const IRObject &other)
Definition serialization.h:46
std::enable_if< std::is_enum< T >::value, T >::type GetScalar()
Definition serialization.h:81
static std::enable_if< detail::is_container< T >::value &&!std::is_same< T, std::string >::value, IRObject >::type FromCorpus(const T &val)
Definition serialization.h:157
char ss[8]
Definition serialization.h:64
IRObject & operator=(const IRObject &other)
Definition serialization.h:48
int64_t i
Definition serialization.h:61
static std::enable_if< detail::is_specialization< T, std::pair >::value, T >::type ToCorpus(IRObject obj)
Definition serialization.h:259
std::enable_if< std::is_integral< T >::value, T >::type GetScalar()
Definition serialization.h:71
std::enable_if< std::is_same< T, std::string >::value, void >::type SetScalar(T val)
Definition serialization.h:112
static std::enable_if< detail::is_specialization< T, std::tuple >::value, T >::type ToCorpus(IRObject obj)
Definition serialization.h:250
static std::enable_if< std::is_integral< T >::value||std::is_floating_point< T >::value||std::is_same< T, std::string >::value||std::is_enum< T >::value, IRObject >::type FromCorpus(T val)
Definition serialization.h:148
static IRObject FromCorpus(const std::tuple< Args... > &val)
Definition serialization.h:176
std::enable_if< std::is_same< T, std::string >::value, T >::type GetScalar()
Definition serialization.h:86
Type
Definition serialization.h:58
@ Undefined
Definition serialization.h:58
@ ShortString
Definition serialization.h:58
@ Int
Definition serialization.h:58
@ String
Definition serialization.h:58
@ Float
Definition serialization.h:58
@ Object
Definition serialization.h:58
Definition typetraits.h:63
Definition typetraits.h:96
Definition typetraits.h:60