1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 Jochen Becher
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include "tag.h"
29 #include "baseclass.h"
30 #include "attribute.h"
31 #include "reference.h"
32 #include "access.h"
33 #include "typeregistry.h"
34 
35 #include "serialize_pointer.h"
36 #include "serialize_basic.h"
37 #include "serialize_container.h"
38 #include "serialize_enum.h"
39 
40 #include <type_traits>
41 
42 // qark is (Q)t(Ar)chiving(K)it
43 namespace qark {
44 
45 template<class Archive, class T>
46 inline Archive &operator<<(Archive &archive, const T &t)
47 {
48     save(archive, t, Parameters());
49     return archive;
50 }
51 
52 template<class Archive, class T>
53 inline Archive &operator>>(Archive &archive, T &t)
54 {
55     load(archive, t, Parameters());
56     return archive;
57 }
58 
59 template<class Archive, class T>
60 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(Archive &archive, T &t)
61 {
62     return archive << t;
63 }
64 
65 template<class Archive, class T>
66 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(Archive &archive, T &t)
67 {
68     return archive >> t;
69 }
70 
71 template<class Archive, class T>
72 inline Archive &operator<<(Archive &archive, T (*f)())
73 {
74     archive << f();
75     return archive;
76 }
77 
78 template<class Archive, class T>
79 inline Archive &operator>>(Archive &archive, T (*f)())
80 {
81     archive >> f();
82     return archive;
83 }
84 
85 template<class Archive, class T>
86 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(Archive &archive, T (*f)())
87 {
88     return archive << f;
89 }
90 
91 template<class Archive, class T>
92 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(Archive &archive, T (*f)())
93 {
94     return archive >> f;
95 }
96 
97 template<class Archive>
98 inline Archive &operator<<(Archive &archive, const Tag &tag)
99 {
100     archive.beginElement(tag);
101     return archive;
102 }
103 
104 template<class Archive>
105 inline Archive &operator>>(Archive &archive, const Tag &tag)
106 {
107     archive.append(tag);
108     return archive;
109 }
110 
111 template<class Archive>
112 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(
113         Archive &archive, const Tag &tag)
114 {
115     return archive << tag;
116 }
117 
118 template<class Archive>
119 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(
120         Archive &archive, const Tag &tag)
121 {
122     return archive >> tag;
123 }
124 
125 template<class Archive, class T>
126 inline Archive &operator<<(Archive &archive, const Object<T> &object)
127 {
128     archive.beginElement(object);
129     return archive;
130 }
131 
132 template<class Archive, class T>
133 inline Archive &operator>>(Archive &archive, const Object<T> &object)
134 {
135     archive.append(object);
136     return archive;
137 }
138 
139 template<class Archive, class T>
140 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(
141         Archive &archive, const Object<T> &object)
142 {
143     return archive << object;
144 }
145 
146 template<class Archive, class T>
147 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(
148         Archive &archive, const Object<T> &object)
149 {
150     return archive >> object;
151 }
152 
153 template<class Archive>
154 inline Archive &operator<<(Archive &archive, const End &end)
155 {
156     archive.endElement(end);
157     return archive;
158 }
159 
160 template<class Archive>
161 inline Archive &operator>>(Archive &archive, const End &end)
162 {
163     archive.append(end);
164     return archive;
165 }
166 
167 template<class Archive>
168 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(
169         Archive &archive, const End &end)
170 {
171     return archive << end;
172 }
173 
174 template<class Archive>
175 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(
176         Archive &archive, const End &end)
177 {
178     return archive >> end;
179 }
180 
181 template<class Archive, class T, class U>
182 Archive &operator<<(Archive &archive, const Base<T, U> &base)
183 {
184     archive.beginBase(base);
185     archive << base.base();
186     archive.endBase(base);
187     return archive;
188 }
189 
190 template<class Archive, class T, class U>
191 Archive &operator>>(Archive &archive, const Base<T, U> &base)
192 {
193     archive.append(base);
194     return archive;
195 }
196 
197 template<class Archive, class T, class U>
198 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(
199         Archive &archive, const Base<T, U> &base)
200 {
201     return archive << base;
202 }
203 
204 template<class Archive, class T, class U>
205 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(
206         Archive &archive, const Base<T, U> &base)
207 {
208     return archive >> base;
209 }
210 
211 template<class Archive, typename T>
212 Archive &operator<<(Archive &archive, const Attr<T> &attr)
213 {
214     archive.beginAttribute(attr);
215     save(archive, *attr.value(), attr.parameters());
216     archive.endAttribute(attr);
217     return archive;
218 }
219 
220 template<class Archive, typename T>
221 Archive &operator>>(Archive &archive, const Attr<T> &attr)
222 {
223     archive.append(attr);
224     return archive;
225 }
226 
227 template<class Archive, typename T>
228 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(
229         Archive &archive, const Attr<T> &attr)
230 {
231     return archive << attr;
232 }
233 
234 template<class Archive, typename T>
235 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(
236         Archive &archive, const Attr<T> &attr)
237 {
238     return archive >> attr;
239 }
240 
241 template<class Archive, class U, typename T>
242 typename std::enable_if<!std::is_abstract<U>::value, Archive &>::type
243 operator<<(Archive &archive, const GetterAttr<U, T> &attr)
244 {
245     if (!((attr.object().*(attr.getter()))() == (U().*(attr.getter()))())) {
246         archive.beginAttribute(attr);
247         save(archive, (attr.object().*(attr.getter()))(), attr.parameters());
248         archive.endAttribute(attr);
249     }
250     return archive;
251 }
252 
253 template<class Archive, class U, typename T>
254 typename std::enable_if<std::is_abstract<U>::value, Archive &>::type
255 operator<<(Archive &archive, const GetterAttr<U, T> &attr)
256 {
257     archive.beginAttribute(attr);
258     save(archive, (attr.object().*(attr.getter()))(), attr.parameters());
259     archive.endAttribute(attr);
260     return archive;
261 }
262 
263 template<class Archive, class U, typename T>
264 Archive &operator>>(Archive &archive, const SetterAttr<U, T> &attr)
265 {
266     archive.append(attr);
267     return archive;
268 }
269 
270 // TODO find possibility to avoid error message if T does not have an operator==
271 template<class Archive, class U, typename T, typename V>
272 typename std::enable_if<!std::is_abstract<U>::value, Archive &>::type
273 operator<<(Archive &archive, const GetterSetterAttr<U, T, V> &attr)
274 {
275     if (!((attr.object().*(attr.getter()))() == (U().*(attr.getter()))())) {
276         archive.beginAttribute(attr);
277         save(archive, (attr.object().*(attr.getter()))(), attr.parameters());
278         archive.endAttribute(attr);
279     }
280     return archive;
281 }
282 
283 // TODO Check for default values, e.g. using T()
284 template<class Archive, class U, typename T, typename V>
285 typename std::enable_if<std::is_abstract<U>::value, Archive &>::type
286 operator<<(Archive &archive, const GetterSetterAttr<U, T, V> &attr)
287 {
288     archive.beginAttribute(attr);
289     save(archive, (attr.object().*(attr.getter()))(), attr.parameters());
290     archive.endAttribute(attr);
291     return archive;
292 }
293 
294 template<class Archive, class U, typename T, typename V>
295 Archive &operator>>(Archive &archive, const GetterSetterAttr<U, T, V> &attr)
296 {
297     archive.append(attr);
298     return archive;
299 }
300 
301 template<class Archive, class U, typename T, typename V>
302 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(
303         Archive &archive, const GetterSetterAttr<U, T, V> &attr)
304 {
305     return archive << attr;
306 }
307 
308 template<class Archive, class U, typename T, typename V>
309 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(
310         Archive &archive, const GetterSetterAttr<U, T, V> &attr)
311 {
312     return archive >> attr;
313 }
314 
315 template<class Archive, class U, typename T>
316 Archive &operator<<(Archive &archive, const GetFuncAttr<U, T> &attr)
317 {
318     archive.beginAttribute(attr);
319     save(archive, ((*attr.getterFunc())(attr.object())), attr.parameters());
320     archive.endAttribute(attr);
321     return archive;
322 }
323 
324 template<class Archive, class U, typename T>
325 Archive &operator>>(Archive &archive, const SetFuncAttr<U, T> &attr)
326 {
327     archive.append(attr);
328     return archive;
329 }
330 
331 template<class Archive, class U, typename T, typename V>
332 Archive &operator<<(Archive &archive, const GetSetFuncAttr<U, T, V> &attr)
333 {
334     archive.beginAttribute(attr);
335     save(archive, ((*attr.getterFunc())(attr.object())), attr.parameters());
336     archive.endAttribute(attr);
337     return archive;
338 }
339 
340 template<class Archive, class U, typename T, typename V>
341 Archive &operator>>(Archive &archive, const GetSetFuncAttr<U, T, V> &attr)
342 {
343     archive.append(attr);
344     return archive;
345 }
346 
347 template<class Archive, class U, typename T, typename V>
348 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(
349         Archive &archive, const GetSetFuncAttr<U, T, V> &attr)
350 {
351     return archive << attr;
352 }
353 
354 template<class Archive, class U, typename T, typename V>
355 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(
356         Archive &archive, const GetSetFuncAttr<U, T, V> &attr)
357 {
358     return archive >> attr;
359 }
360 
361 template<class Archive, typename T>
362 Archive &operator<<(Archive &archive, const Ref<T *> &ref)
363 {
364     archive.beginReference(ref);
365     save(archive, *ref.value(), ref.parameters());
366     archive.endReference(ref);
367     return archive;
368 }
369 
370 template<class Archive, typename T>
371 Archive &operator<<(Archive &archive, const Ref<T * const> &ref)
372 {
373     archive.beginReference(ref);
374     save(archive, *ref.value(), ref.parameters());
375     archive.endReference(ref);
376     return archive;
377 }
378 
379 template<class Archive, typename T>
380 Archive &operator>>(Archive &archive, const Ref<T> &ref)
381 {
382     archive.append(ref);
383     return archive;
384 }
385 
386 template<class Archive, typename T>
387 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(
388         Archive &archive, const Ref<T *> &ref)
389 {
390     archive.beginReference(ref);
391     save(archive, *ref.value(), ref.parameters());
392     archive.endReference(ref);
393     return archive;
394 }
395 
396 template<class Archive, typename T>
397 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(
398         Archive &archive, const Ref<T> &ref)
399 {
400     return archive >> ref;
401 }
402 
403 template<class Archive, class U, typename T>
404 Archive &operator<<(Archive &archive, const GetterRef<U, T> &ref)
405 {
406     archive.beginReference(ref);
407     save(archive, (ref.object().*(ref.getter()))(), ref.parameters());
408     archive.endReference(ref);
409     return archive;
410 }
411 
412 template<class Archive, class U, typename T>
413 Archive &operator>>(Archive &archive, const SetterRef<U, T> &ref)
414 {
415     archive.append(ref);
416     return archive;
417 }
418 
419 template<class Archive, class U, typename T, typename V>
420 Archive &operator<<(Archive &archive, const GetterSetterRef<U, T, V> &ref)
421 {
422     archive.beginReference(ref);
423     save(archive, (ref.object().*(ref.getter()))(), ref.parameters());
424     archive.endReference(ref);
425     return archive;
426 }
427 
428 template<class Archive, class U, typename T, typename V>
429 Archive &operator>>(Archive &archive, const GetterSetterRef<U, T, V> &ref)
430 {
431     archive.append(ref);
432     return archive;
433 }
434 
435 template<class Archive, class U, typename T, typename V>
436 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(
437         Archive &archive, const GetterSetterRef<U, T, V> &ref)
438 {
439     return archive << ref;
440 }
441 
442 template<class Archive, class U, typename T, typename V>
443 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(
444         Archive &archive, const GetterSetterRef<U, T, V> &ref)
445 {
446     return archive >> ref;
447 }
448 
449 template<class Archive, class U, typename T>
450 Archive &operator<<(Archive &archive, const GetFuncRef<U, T> &ref)
451 {
452     archive.beginReference(ref);
453     save(archive, ref.getterFunc()(ref.object()), ref.parameters());
454     archive.endReference(ref);
455     return archive;
456 }
457 
458 template<class Archive, class U, typename T>
459 Archive &operator>>(Archive &archive, const SetFuncRef<U, T> &ref)
460 {
461     archive.append(ref);
462     return archive;
463 }
464 
465 template<class Archive, class U, typename T, typename V>
466 Archive &operator<<(Archive &archive, const GetSetFuncRef<U, T, V> &ref)
467 {
468     archive.beginReference(ref);
469     save(archive, ref.getterFunc()(ref.object()), ref.parameters());
470     archive.endReference(ref);
471     return archive;
472 }
473 
474 template<class Archive, class U, typename T, typename V>
475 Archive &operator>>(Archive &archive, const GetSetFuncRef<U, T, V> &ref)
476 {
477     archive.append(ref);
478     return archive;
479 }
480 
481 template<class Archive, class U, typename T, typename V>
482 typename std::enable_if<Archive::outArchive, Archive &>::type operator||(
483         Archive &archive, const GetSetFuncRef<U, T, V> &ref)
484 {
485     return archive << ref;
486 }
487 
488 template<class Archive, class U, typename T, typename V>
489 typename std::enable_if<Archive::inArchive, Archive &>::type operator||(
490         Archive &archive, const GetSetFuncRef<U, T, V> &ref)
491 {
492     return archive >> ref;
493 }
494 
495 } // namespace qark
496