Loading...
Searching...
No Matches
BoostVariant2Serialization.hpp
1#pragma once
3#include <score/serialization/JSONVisitor.hpp>
4#include <score/tools/Metadata.hpp>
5
6#include <ossia/detail/for_each.hpp>
7#include <ossia/detail/variant.hpp>
8
39template <typename T>
41{
43 : s{s_p}
44 , var{var_p}
45 {
46 }
47
49 const T& var;
50
51 bool done = false;
52
53 template <typename TheClass>
54 void operator()();
55};
56
57template <typename T>
58template <typename TheClass>
60{
61 // This trickery iterates over all the types in Args...
62 // A single type should be serialized, even if we cannot break.
63 if(done)
64 return;
65 if(auto res = ossia::get_if<TheClass>(&var))
66 {
67 s.stream() << *res;
68 done = true;
69 }
70}
71
72template <typename T>
74{
76 DataStream::Deserializer& s_p, quint64 which_p, T& var_p)
77 : s{s_p}
78 , which{which_p}
79 , var{var_p}
80 {
81 }
82
84 quint64 which;
85 T& var;
86
87 quint64 i = 0;
88 template <typename TheClass>
89 void operator()();
90};
91
92template <typename T>
93template <typename TheClass>
95{
96 // Here we iterate until we are on the correct type, and we deserialize it.
97 if(i++ != which)
98 return;
99
100 TheClass data;
101 s.stream() >> data;
102 var = std::move(data);
103}
104
105template <typename... Args>
106struct TSerializer<DataStream, ossia::variant<Args...>>
107{
108 using var_t = ossia::variant<Args...>;
109 static void readFrom(DataStream::Serializer& s, const var_t& var)
110 {
111 s.stream() << (quint64)var.index();
112
113 ossia::for_each_type<Args...>(OssiaVariantDataStreamSerializer<var_t>{s, var});
114
115 s.insertDelimiter();
116 }
117
118 static void writeTo(DataStream::Deserializer& s, var_t& var)
119 {
120 quint64 which;
121 s.stream() >> which;
122
123 ossia::for_each_type<Args...>(
125 s.checkDelimiter();
126 }
127};
128
129// This part is required because it isn't as straightforward to save variant
130// data
131// in JSON as it is to save it in a DataStream.
132// Basically, each variant member has an associated name that will be the
133// key in the JSON parent object. This name is defined by specializing
134// template<> class Metadata<Json_k, T>.
135// For instance:
136// template<> class Metadata<Json_k, score::Address>
137// { public: static constexpr const char * get() { return "Address"; } };
138// A JSON_METADATA macro is provided for this.
139
140// This allows easy store and retrieval under a familiar name
141
142// TODO add some ASSERT for the variant being set on debug mode. npos case
143// should not happen since we have the std::optionalVariant.
144
145template <typename T>
147{
149 : s{s_p}
150 , var{var_p}
151 {
152 }
154 const T& var;
155
156 bool done = false;
157
158 template <typename TheClass>
159 void operator()();
160};
161
162template <typename T>
163template <typename TheClass>
165{
166 if(done)
167 return;
168
169 if(auto res = ossia::get_if<TheClass>(&var))
170 {
171 s.obj[Metadata<Json_k, TheClass>::get()] = *res;
172 done = true;
173 }
174}
175
176template <typename T>
178{
180 : s{s_p}
181 , var{var_p}
182 {
183 }
185 T& var;
186
187 bool done = false;
188 template <typename TheClass>
189 void operator()();
190};
191
192template <typename T>
193template <typename TheClass>
195{
196 if(done)
197 return;
198
199 if(auto it = s.obj.tryGet(Metadata<Json_k, TheClass>::get()))
200 {
201 JSONWriter w{*it};
202 TheClass obj;
203 obj <<= JsonValue{w.base};
204 var = std::move(obj);
205 done = true;
206 }
207}
208
209template <typename... Args>
210struct TSerializer<JSONObject, ossia::variant<Args...>>
211{
212 using var_t = ossia::variant<Args...>;
213 static void readFrom(JSONObject::Serializer& s, const var_t& var)
214 {
215 s.stream.StartObject();
216 ossia::for_each_type<Args...>(OssiaVariantJSONSerializer<var_t>{s, var});
217 s.stream.EndObject();
218 }
219
220 static void writeTo(JSONObject::Deserializer& s, var_t& var)
221 {
222 if(s.base.MemberCount() == 0)
223 return;
224 ossia::for_each_type<Args...>(OssiaVariantJSONDeserializer<var_t>{s, var});
225 }
226};
Definition VisitorInterface.hpp:53
Definition DataStreamVisitor.hpp:27
void insertDelimiter()
insertDelimiter
Definition DataStreamVisitor.hpp:156
Definition DataStreamVisitor.hpp:202
Definition VisitorInterface.hpp:61
Definition JSONVisitor.hpp:52
Definition JSONVisitor.hpp:423
Definition JSONVisitor.hpp:372
Static metadata implementation.
Definition lib/score/tools/Metadata.hpp:36
Definition BoostVariant2Serialization.hpp:74
Definition BoostVariant2Serialization.hpp:41
Definition BoostVariant2Serialization.hpp:178
Definition BoostVariant2Serialization.hpp:147
Definition VisitorInterface.hpp:13