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 
39 template <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 
57 template <typename T>
58 template <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 
72 template <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 
92 template <typename T>
93 template <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 
105 template <typename... Args>
106 struct 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 
145 template <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 
162 template <typename T>
163 template <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 
176 template <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 
192 template <typename T>
193 template <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 
209 template <typename... Args>
210 struct 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
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