-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjson_deserialise.unfinished.hpp
129 lines (106 loc) · 4.5 KB
/
json_deserialise.unfinished.hpp
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
template <typename Prototype>
struct AfterDeserialise : public Prototype {
using T = typename Prototype::Target;
const std::function<void(T&)> functor;
template <typename Functor, typename... Args>
AfterDeserialise(Functor&& f, Args&&... args)
: Prototype(args...), functor(std::forward<Functor>(f)) {}
inline void from_json(const Json& json) {
Prototype::from_json(json);
functor(this->template value<T>());
}
};
template <typename Prototype>
struct AfterSerialise : public Prototype {
using T = typename Prototype::Target;
const std::function<void(const T&)> functor;
template <typename Functor, typename... Args>
AfterSerialise(Functor&& f, Args&&... args)
: Prototype(args...), functor(std::forward<Functor>(f)) {}
inline Json to_json() const {
auto result = Base::to_json();
functor(this->template value<T>());
return result;
}
};
template <typename Prototype>
struct BeforeDeserialise : public Prototype {
using T = typename Prototype::Target;
const std::function<void(T&)> functor;
template <typename Functor, typename... Args>
BeforeDeserialise(Functor&& f, Args&&... args)
: Prototype(args...), functor(std::forward<Functor>(f)) {}
inline void from_json(const Json& json) {
functor(this->template value<T>());
Prototype::from_json(json);
}
};
template <typename Prototype>
struct BeforeSerialise : public Prototype {
using T = typename Prototype::Target;
const std::function<void(const T&)> functor;
template <typename Functor, typename... Args>
BeforeSerialise(Functor&& f, Args&&... args)
: Prototype(args...), functor(std::forward<Functor>(f)) {}
inline Json to_json() const {
functor(this->template value<T>());
return Prototype::to_json();
}
};
template <typename UnionType, auto TypeInfo, typename... MemberInfo>
struct Union : public DeserialisableBaseHelper<UnionType> {
using Target = UnionType;
using Base = DeserialisableBaseHelper<UnionType>;
};
template <typename Pointer, typename BaseType, typename DerivedTypes>
struct BasePointerDeserialise : public DeserialisableBaseHelper<Pointer> {
using Target = Pointer;
using Base = DeserialisableBaseHelper<Target>;
const std::function<int(const Json&)> deductor;
template <typename Deductor, typename... Args>
BasePointer(Deductor&& f, Args&&... args)
: Base(std::forward<Args>(args)...), deductor(std::forward<Deductor>(f)) {}
template <int N>
inline void assign_if_eq(int index, const typename Lib::JsonObject& obj) {
using Type = typename GetType<N, DerivedTypes>::Type;
if (N == index) {
auto ptr = new Type();
DeserialisableType<Type>(*ptr)->from_json(obj);
this->template value<Target>() = ptr;
}
}
void from_json(const Json& json) {
int index = deductor1(json);
if (index == -1)
throw std::ios_base::failure("Type Unmatch!");
(assign_if_eq<pack>(index, obj), ...);
}
};
template <typename Prototype, typename Guard, auto member_offset>
struct MemberLockGuard : public Prototype {
template <typename... Args>
MemberLockGuard(Args&&... args) : Prototype(args...) {}
inline void from_json(const Json& json) {
Guard guard(this->template value<T>().*member_offset);
Base::from_json(json);
}
inline Json to_json() const {
Guard guard(this->template value<T>().*member_offset);
return Base::to_json();
}
};
template <typename Prototype, typename Guard, typename Functor>
struct FetchLockGuard : public Prototype {
const std::function<Lock&(const T&)> functor;
template <typename... Args>
FetchLockGuard(Functor&& f, Args&&... args)
: Prototype(args...), functor(std::forward<Functor>(f)) {}
inline void from_json(const Json& json) {
Guard guard(functor(this->template value<T>()));
Base::from_json(json);
}
inline Json to_json() const {
Guard guard(functor(this->template value<T>()));
return Base::to_json();
}
};