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