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