This repository was archived by the owner on Nov 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathJsonCast.inl
More file actions
138 lines (122 loc) · 3.22 KB
/
Copy pathJsonCast.inl
File metadata and controls
138 lines (122 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "JsonCast.h"
template <typename T>
void to_json(json& j, const T& obj)
{
j = meta::serialize(obj);
}
template <typename T>
void from_json(const json& j, T& obj)
{
meta::deserialize(obj, j);
}
namespace meta
{
/////////////////// SERIALIZATION
template <typename Class,
typename>
json serialize(const Class& obj)
{
json value;
meta::doForAllMembers<Class>(
[&obj, &value](auto& member)
{
auto& valueName = value[member.getName()];
if (member.canGetConstRef()) {
valueName = member.get(obj);
} else if (member.hasGetter()) {
valueName = member.getCopy(obj); // passing copy as const ref, it's okay
}
}
);
return value;
}
template <typename Class,
typename, typename>
json serialize(const Class& obj)
{
return serialize_basic(obj);
}
template <typename Class>
json serialize_basic(const Class& obj)
{
return json(obj);
}
// specialization for std::vector
template <typename T>
json serialize_basic(const std::vector<T>& obj)
{
json value;
int i = 0;
for (auto& elem : obj) {
value[i] = elem;
++i;
}
return value;
}
// specialization for std::unordered_map
template <typename K, typename V>
json serialize_basic(const std::unordered_map<K, V>& obj)
{
json value;
for (auto& pair : obj) {
value.emplace(castToString(pair.first), pair.second);
}
return value;
}
/////////////////// DESERIALIZATION
template <typename Class>
Class deserialize(const json& obj)
{
Class c;
deserialize(c, obj);
return c;
}
template <typename Class,
typename>
void deserialize(Class& obj, const json& object)
{
if (object.is_object()) {
meta::doForAllMembers<Class>(
[&obj, &object](auto& member)
{
auto& objName = object[member.getName()];
if (!objName.is_null()) {
using MemberT = meta::get_member_type<decltype(member)>;
if (member.hasSetter()) {
member.set(obj, objName.template get<MemberT>());
} else if (member.canGetRef()) {
member.getRef(obj) = objName.template get<MemberT>();
} else {
throw std::runtime_error("Error: can't deserialize member because it's read only");
}
}
}
);
} else {
throw std::runtime_error("Error: can't deserialize from Json::json to Class.");
}
}
template <typename Class,
typename, typename>
void deserialize(Class& obj, const json& object)
{
obj = object.get<Class>();
}
// specialization for std::vector
template <typename T>
void deserialize(std::vector<T>& obj, const json& object)
{
obj.reserve(object.size()); // vector.resize() works only for default constructible types
for (auto& elem : object) {
obj.push_back(elem); // push rvalue
}
}
// specialization for std::unodered_map
template <typename K, typename V>
void deserialize(std::unordered_map<K, V>& obj, const json& object)
{
for (auto it = object.begin(); it != object.end(); ++it) {
obj.emplace(fromString<K>(it.key()), it.value());
}
}
}