ModelEditor: Introduce newest version of qtserialization framework

This change unfortunately contains many single changes because it is an
update of the 3rd party component:

* Introduce new Parameter class for better serialization of containers
and other future enhancements
* Delete dead code
* Introduce user data in base archive class
* Fix minor source code issues and typos in comments
* Remove unused and conceptionally broken support of forward refernces
* Fix a memory leak in QXmlInArchive
* prefer load()/save() methods over stream operators
* throw exception on unsuported forward references in QXmlOutArchive
* refactor serialization of pointer types into own header
* remove unneeded specialisation for serialization of free functions
* check for default value of serialization using a getter

Change-Id: Ic197a92b00b22b85dab4a1b88c431cf4da8b3c3b
Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
Jochen Becher
2015-10-09 21:12:53 +02:00
parent f4628dcc8c
commit 0d309fc8c0
18 changed files with 731 additions and 375 deletions

View File

@@ -55,12 +55,24 @@ void save(Archive &archive, const T &t)
Access<Archive, T>::save(archive, t); Access<Archive, T>::save(archive, t);
} }
template<class Archive, class T>
void save(Archive &archive, const T &t, const Parameters &)
{
save(archive, t);
}
template<class Archive, class T> template<class Archive, class T>
void load(Archive &archive, T &t) void load(Archive &archive, T &t)
{ {
Access<Archive, T>::load(archive, t); Access<Archive, T>::load(archive, t);
} }
template<class Archive, class T>
void load(Archive &archive, T &t, const Parameters &)
{
load(archive, t);
}
template<class Archive, class T> template<class Archive, class T>
void serialize(Archive &archive, T &t) void serialize(Archive &archive, T &t)
{ {
@@ -92,30 +104,9 @@ void serialize_helper(Archive &archive, T &t)
static inline void serialize(Archive &archive, TYPE &); \ static inline void serialize(Archive &archive, TYPE &); \
}; };
#if 0
#define QARK_ACCESS_SPECIALIZE_LOAD_SAVE(INARCHIVE, OUTARCHIVE, TYPE) \
template<> class Access<INARCHIVE, TYPE> { public: static inline void load(INARCHIVE &archive, TYPE &); void serialize(INARCHIVE &, TYPE &); }; \
template<> class Access<OUTARCHIVE, TYPE> { public: static inline void save(OUTARCHIVE &archive, const TYPE &); void serialize(OUTARCHIVE &, TYPE &); }; \
void Access<INARCHIVE, TYPE>::serialize(INARCHIVE &, TYPE &) { } \
void Access<OUTARCHIVE, TYPE>::serialize(OUTARCHIVE &, TYPE &) { } \
template class Access<INARCHIVE, TYPE>; \
template class Access<OUTARCHIVE, TYPE>;
#endif
#define QARK_ACCESS_SPECIALIZE(INARCHIVE, OUTARCHIVE, TYPE) \ #define QARK_ACCESS_SPECIALIZE(INARCHIVE, OUTARCHIVE, TYPE) \
template class Access<INARCHIVE, TYPE>; \ template class Access<INARCHIVE, TYPE>; \
template class Access<OUTARCHIVE, TYPE>; template class Access<OUTARCHIVE, TYPE>;
#if 0
#define QARK_SPECIALIZE_SERIALIZE(INARCHIVE, OUTARCHIVE, TYPE) \
QARK_ACCESS_SPECIALIZE(INARCHIVE, OUTARCHIVE, TYPE); \
template void serialize<INARCHIVE, TYPE>(INARCHIVE &, TYPE &); \
template void serialize<OUTARCHIVE, TYPE>(OUTARCHIVE &, TYPE &);
#define QARK_SPECIALIZE_LOAD_SAVE(INARCHIVE, OUTARCHIVE, TYPE) \
template void load<INARCHIVE, TYPE>(INARCHIVE &, TYPE &); \
template void save<OUTARCHIVE, TYPE>(OUTARCHIVE &, const TYPE &);
#endif
#endif // QARK_ACCESS_H #endif // QARK_ACCESS_H

View File

@@ -33,6 +33,10 @@
#include "flag.h" #include "flag.h"
#include <QVariant>
#include <QString>
#include <QHash>
namespace qark { namespace qark {
class ArchiveBasics class ArchiveBasics
@@ -48,8 +52,40 @@ public:
bool takeFlag(const Flag &flag) { bool f = (_flags & flag.getMask()) != 0; _flags &= ~flag.getMask(); return f; } bool takeFlag(const Flag &flag) { bool f = (_flags & flag.getMask()) != 0; _flags &= ~flag.getMask(); return f; }
bool hasUserData(const QString &key)
{
return _user_data.contains(key);
}
template<typename T>
T getUserData(const QString &key)
{
return _user_data.value(key).value<T>();
}
template<typename T>
T getUserData(const QString &key, const T &default_value)
{
// gcc 4.8.2 fails to compile if the following 2 statements are written in one expression
//return _user_data.value(key, data).value<T>();
QVariant v = _user_data.value(key, default_value);
return v.value<T>();
}
template<class T>
void setUserData(const QString &key, const T &data)
{
_user_data.insert(key, data);
}
void removeUserData(const QString &key)
{
_user_data.remove(key);
}
private: private:
Flag::mask_type _flags; Flag::mask_type _flags;
QHash<QString, QVariant> _user_data;
}; };
} }

View File

@@ -31,6 +31,8 @@
#ifndef QARK_ATTRIBUTE_H #ifndef QARK_ATTRIBUTE_H
#define QARK_ATTRIBUTE_H #define QARK_ATTRIBUTE_H
#include "parameters.h"
#include <QString> #include <QString>
namespace qark { namespace qark {
@@ -38,19 +40,29 @@ namespace qark {
template<typename T> template<typename T>
class Attr { class Attr {
public: public:
explicit Attr(const QString &qualified_name, T *value) Attr(const QString &qualified_name, T *value)
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_value(value) _value(value)
{ {
} }
Attr(const QString &qualified_name, T *value, const Parameters &parameters)
: _qualified_name(qualified_name),
_value(value),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
T *getValue() const { return _value; } T *getValue() const { return _value; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
T *_value; T *_value;
Parameters _parameters;
}; };
template<typename T> template<typename T>
@@ -59,33 +71,56 @@ Attr<T * const> attr(const QString &qualified_name, T * const &value)
return Attr<T * const>(qualified_name, &value); return Attr<T * const>(qualified_name, &value);
} }
template<typename T>
Attr<T * const> attr(const QString &qualified_name, T * const &value, const Parameters &parameters)
{
return Attr<T * const>(qualified_name, &value, parameters);
}
template<typename T> template<typename T>
Attr<T> attr(const QString &qualified_name, T &value) Attr<T> attr(const QString &qualified_name, T &value)
{ {
return Attr<T>(qualified_name, &value); return Attr<T>(qualified_name, &value);
} }
template<typename T>
Attr<T> attr(const QString &qualified_name, T &value, const Parameters &parameters)
{
return Attr<T>(qualified_name, &value, parameters);
}
template<class U, typename T> template<class U, typename T>
class GetterAttr { class GetterAttr {
public: public:
explicit GetterAttr(const QString &qualified_name, const U &u, T (U::*getter)() const) GetterAttr(const QString &qualified_name, const U &u, T (U::*getter)() const)
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_getter(getter) _getter(getter)
{ {
} }
GetterAttr(const QString &qualified_name, const U &u, T (U::*getter)() const, const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_getter(getter),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
const U &getObject() const { return _u; } const U &getObject() const { return _u; }
T (U::*getGetter() const)() const { return _getter; } T (U::*getGetter() const)() const { return _getter; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
const U &_u; const U &_u;
T (U::*_getter)() const; T (U::*_getter)() const;
Parameters _parameters;
}; };
template<class U, typename T> template<class U, typename T>
@@ -94,27 +129,44 @@ GetterAttr<U, T> attr(const QString &qualified_name, const U &u, T (U::*getter)(
return GetterAttr<U, T>(qualified_name, u, getter); return GetterAttr<U, T>(qualified_name, u, getter);
} }
template<class U, typename T>
GetterAttr<U, T> attr(const QString &qualified_name, const U &u, T (U::*getter)() const, const Parameters &parameters)
{
return GetterAttr<U, T>(qualified_name, u, getter, parameters);
}
template<class U, typename T> template<class U, typename T>
class SetterAttr { class SetterAttr {
public: public:
explicit SetterAttr(const QString &qualified_name, U &u, void (U::*setter)(T)) SetterAttr(const QString &qualified_name, U &u, void (U::*setter)(T))
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_setter(setter) _setter(setter)
{ {
} }
SetterAttr(const QString &qualified_name, U &u, void (U::*setter)(T), const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_setter(setter),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
U &getObject() const { return _u; } U &getObject() const { return _u; }
void (U::*getSetter() const)(T) { return _setter; } void (U::*getSetter() const)(T) { return _setter; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
U &_u; U &_u;
void (U::*_setter)(T); void (U::*_setter)(T);
Parameters _parameters;
}; };
template<class U, typename T> template<class U, typename T>
@@ -123,11 +175,17 @@ SetterAttr<U, T> attr(const QString &qualified_name, U &u, void (U::*setter)(T))
return SetterAttr<U, T>(qualified_name, u, setter); return SetterAttr<U, T>(qualified_name, u, setter);
} }
template<class U, typename T>
SetterAttr<U, T> attr(const QString &qualified_name, U &u, void (U::*setter)(T), const Parameters &parameters)
{
return SetterAttr<U, T>(qualified_name, u, setter, parameters);
}
template<class U, typename T, typename V> template<class U, typename T, typename V>
class GetterSetterAttr { class GetterSetterAttr {
public: public:
explicit GetterSetterAttr(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V)) GetterSetterAttr(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V))
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_getter(getter), _getter(getter),
@@ -135,6 +193,15 @@ public:
{ {
} }
GetterSetterAttr(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V), const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_getter(getter),
_setter(setter),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
U &getObject() const { return _u; } U &getObject() const { return _u; }
@@ -143,11 +210,14 @@ public:
void (U::*getSetter() const)(V) { return _setter; } void (U::*getSetter() const)(V) { return _setter; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
U &_u; U &_u;
T (U::*_getter)() const; T (U::*_getter)() const;
void (U::*_setter)(V); void (U::*_setter)(V);
Parameters _parameters;
}; };
template<class U, typename T, typename V> template<class U, typename T, typename V>
@@ -156,27 +226,44 @@ GetterSetterAttr<U, T, V> attr(const QString &qualified_name, U &u, T (U::*gette
return GetterSetterAttr<U, T, V>(qualified_name, u, getter, setter); return GetterSetterAttr<U, T, V>(qualified_name, u, getter, setter);
} }
template<class U, typename T, typename V>
GetterSetterAttr<U, T, V> attr(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V), const Parameters &parameters)
{
return GetterSetterAttr<U, T, V>(qualified_name, u, getter, setter, parameters);
}
template<class U, typename T> template<class U, typename T>
class GetFuncAttr { class GetFuncAttr {
public: public:
explicit GetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &)) GetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &))
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_get_func(get_func) _get_func(get_func)
{ {
} }
GetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &), const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_get_func(get_func),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
U &getObject() const { return _u; } U &getObject() const { return _u; }
T (*getGetFunc() const)(const U &) { return _get_func; } T (*getGetFunc() const)(const U &) { return _get_func; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
U &_u; U &_u;
T (*_get_func)(const U &); T (*_get_func)(const U &);
Parameters _parameters;
}; };
template<class U, typename T> template<class U, typename T>
@@ -185,27 +272,44 @@ GetFuncAttr<U, T> attr(const QString &qualified_name, const U &u, T (*get_func)(
return GetFuncAttr<U, T>(qualified_name, u, get_func); return GetFuncAttr<U, T>(qualified_name, u, get_func);
} }
template<class U, typename T>
GetFuncAttr<U, T> attr(const QString &qualified_name, const U &u, T (*get_func)(const U &), const Parameters &parameters)
{
return GetFuncAttr<U, T>(qualified_name, u, get_func, parameters);
}
template<class U, typename T> template<class U, typename T>
class SetFuncAttr { class SetFuncAttr {
public: public:
explicit SetFuncAttr(const QString &qualified_name, U &u, void (*set_func)(U &, T)) SetFuncAttr(const QString &qualified_name, U &u, void (*set_func)(U &, T))
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_set_func(set_func) _set_func(set_func)
{ {
} }
SetFuncAttr(const QString &qualified_name, U &u, void (*set_func)(U &, T), const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_set_func(set_func),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
U &getObject() const { return _u; } U &getObject() const { return _u; }
void (*getSetFunc() const)(U &, T) { return _set_func; } void (*getSetFunc() const)(U &, T) { return _set_func; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
U &_u; U &_u;
void (*_set_func)(U &, T); void (*_set_func)(U &, T);
Parameters _parameters;
}; };
template<class U, typename T> template<class U, typename T>
@@ -214,11 +318,17 @@ SetFuncAttr<U, T> attr(const QString &qualified_name, U &u, void (*set_func)(U &
return SetFuncAttr<U, T>(qualified_name, u, set_func); return SetFuncAttr<U, T>(qualified_name, u, set_func);
} }
template<class U, typename T>
SetFuncAttr<U, T> attr(const QString &qualified_name, U &u, void (*set_func)(U &, T), const Parameters &parameters)
{
return SetFuncAttr<U, T>(qualified_name, u, set_func, parameters);
}
template<class U, typename T, typename V> template<class U, typename T, typename V>
class GetSetFuncAttr { class GetSetFuncAttr {
public: public:
explicit GetSetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V)) GetSetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V))
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_get_func(get_func), _get_func(get_func),
@@ -226,6 +336,15 @@ public:
{ {
} }
GetSetFuncAttr(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V), const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_get_func(get_func),
_set_func(set_func),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
U &getObject() const { return _u; } U &getObject() const { return _u; }
@@ -234,11 +353,14 @@ public:
void (*getSetFunc() const)(U &, V) { return _set_func; } void (*getSetFunc() const)(U &, V) { return _set_func; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
U &_u; U &_u;
T (*_get_func)(const U &); T (*_get_func)(const U &);
void (*_set_func)(U &, V); void (*_set_func)(U &, V);
Parameters _parameters;
}; };
template<class U, typename T, typename V> template<class U, typename T, typename V>
@@ -247,6 +369,12 @@ GetSetFuncAttr<U, T, V> attr(const QString &qualified_name, U &u, T (*get_func)(
return GetSetFuncAttr<U, T, V>(qualified_name, u, get_func, set_func); return GetSetFuncAttr<U, T, V>(qualified_name, u, get_func, set_func);
} }
template<class U, typename T, typename V>
GetSetFuncAttr<U, T, V> attr(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V), const Parameters &parameters)
{
return GetSetFuncAttr<U, T, V>(qualified_name, u, get_func, set_func, parameters);
}
} }
#endif // QARK_ATTRIBUTE_H #endif // QARK_ATTRIBUTE_H

View File

@@ -32,6 +32,7 @@
#define QARK_BASECLASS_H #define QARK_BASECLASS_H
#include "typeregistry.h" #include "typeregistry.h"
#include "parameters.h"
#include <QString> #include <QString>
@@ -41,21 +42,31 @@ namespace qark {
template<class BASE, class DERIVED> template<class BASE, class DERIVED>
class Base { class Base {
public: public:
explicit Base(const QString &qualified_name, DERIVED &obj) Base(const QString &qualified_name, DERIVED &obj)
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_base(obj) _base(obj)
{ {
} }
Base(const QString &qualified_name, DERIVED &obj, const Parameters &parameters)
: _qualified_name(qualified_name),
_base(obj),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
const BASE &getBase() const { return _base; } const BASE &getBase() const { return _base; }
BASE &getBase() { return _base; } BASE &getBase() { return _base; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
BASE &_base; BASE &_base;
Parameters _parameters;
}; };
template<class BASE, class DERIVED> template<class BASE, class DERIVED>
@@ -64,18 +75,36 @@ Base<BASE, DERIVED> base(const QString &qualified_name, DERIVED &obj)
return Base<BASE, DERIVED>(qualified_name, obj); return Base<BASE, DERIVED>(qualified_name, obj);
} }
template<class BASE, class DERIVED>
Base<BASE, DERIVED> base(const QString &qualified_name, DERIVED &obj, const Parameters &parameters)
{
return Base<BASE, DERIVED>(qualified_name, obj, parameters);
}
template<class BASE, class DERIVED> template<class BASE, class DERIVED>
Base<BASE, DERIVED> base(const QString &qualified_name, DERIVED *&obj) Base<BASE, DERIVED> base(const QString &qualified_name, DERIVED *&obj)
{ {
return Base<BASE, DERIVED>(qualified_name, *obj); return Base<BASE, DERIVED>(qualified_name, *obj);
} }
template<class BASE, class DERIVED>
Base<BASE, DERIVED> base(const QString &qualified_name, DERIVED *&obj, const Parameters &parameters)
{
return Base<BASE, DERIVED>(qualified_name, *obj, parameters);
}
template<class BASE, class DERIVED> template<class BASE, class DERIVED>
Base<BASE, DERIVED> base(DERIVED &obj) Base<BASE, DERIVED> base(DERIVED &obj)
{ {
return Base<BASE, DERIVED>(QString(QStringLiteral("base-%1")).arg(get_type_uid<BASE>()), obj); return Base<BASE, DERIVED>(QString(QStringLiteral("base-%1")).arg(get_type_uid<BASE>()), obj);
} }
template<class BASE, class DERIVED>
Base<BASE, DERIVED> base(DERIVED &obj, const Parameters &parameters)
{
return Base<BASE, DERIVED>(QString(QStringLiteral("base-%1")).arg(get_type_uid<BASE>()), obj, parameters);
}
} }
#endif // QARK_BASECLASS_H #endif // QARK_BASECLASS_H

View File

@@ -28,8 +28,8 @@
** **
****************************************************************************/ ****************************************************************************/
#ifndef QMT_FRIEND_ACCESS_H #ifndef QARK_FRIEND_ACCESS_H
#define QMT_FRIEND_ACCESS_H #define QARK_FRIEND_ACCESS_H
#define QARK_FRIEND_ACCESS \ #define QARK_FRIEND_ACCESS \
template<class Archive, class T> \ template<class Archive, class T> \

View File

@@ -0,0 +1,71 @@
/***************************************************************************
**
** Copyright (C) 2015 Jochen Becher
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef QARK_PARAMETER_H
#define QARK_PARAMETER_H
#include "flag.h"
namespace qark {
class Parameters
{
public:
Parameters()
: _flags(0)
{
}
Parameters(const Flag &flag)
: _flags(flag.getMask())
{
}
public:
void setFlag(const Flag &flag) { _flags |= flag.getMask(); }
void clearFlag(const Flag &flag) { _flags &= ~flag.getMask(); }
bool hasFlag(const Flag &flag) const { return (_flags & flag.getMask()) != 0; }
bool takeFlag(const Flag &flag) { bool f = (_flags & flag.getMask()) != 0; _flags &= ~flag.getMask(); return f; }
private:
Flag::mask_type _flags;
};
}
#endif // QARK_PARAMETER_H

View File

@@ -75,7 +75,7 @@ private:
typedef QList<Node *> children_type; typedef QList<Node *> children_type;
public: public:
virtual ~Node() { } virtual ~Node() { qDeleteAll(_children); }
const children_type &getChildren() const { return _children; } const children_type &getChildren() const { return _children; }
@@ -83,8 +83,6 @@ private:
virtual void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); } virtual void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
virtual void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
void append(Node *node) { _children.push_back(node); } void append(Node *node) { _children.push_back(node); }
private: private:
@@ -237,8 +235,6 @@ private:
void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); } void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
Ref<T> &getReference() { return _ref; } Ref<T> &getReference() { return _ref; }
private: private:
@@ -256,8 +252,6 @@ private:
void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); } void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
SetterRef<U, T> &getReference() { return _ref; } SetterRef<U, T> &getReference() { return _ref; }
private: private:
@@ -275,8 +269,6 @@ private:
void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); } void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
GetterSetterRef<U, T, V> &getReference() { return _ref; } GetterSetterRef<U, T, V> &getReference() { return _ref; }
private: private:
@@ -294,8 +286,6 @@ private:
void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); } void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
SetFuncRef<U, T> &getReference() { return _ref; } SetFuncRef<U, T> &getReference() { return _ref; }
private: private:
@@ -313,35 +303,23 @@ private:
void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); } void accept(QXmlInArchive &visitor, const XmlTag &tag) { visitor.visit(this, tag); }
void acceptForwardRef(QXmlInArchive &visitor, const impl::ObjectId &id) { visitor.visitForwardRef(this, id); }
GetSetFuncRef<U, T, V> &getReference() { return _ref; } GetSetFuncRef<U, T, V> &getReference() { return _ref; }
private: private:
GetSetFuncRef<U, T, V> _ref; GetSetFuncRef<U, T, V> _ref;
}; };
struct ForwardReference {
ForwardReference(Node *node, const impl::ObjectId &id) : _node(node), _id(id) { }
Node *_node;
impl::ObjectId _id;
};
public: public:
explicit QXmlInArchive(QXmlStreamReader &stream) explicit QXmlInArchive(QXmlStreamReader &stream)
: _stream(stream), : _stream(stream),
_end_tag_was_read(false), _end_tag_was_read(false),
_root_node(0),
_current_ref_node(0) _current_ref_node(0)
{ {
} }
~QXmlInArchive() ~QXmlInArchive()
{ {
foreach(const ForwardReference &forward_ref, _forward_references) {
forward_ref._node->acceptForwardRef(*this, forward_ref._id);
}
} }
public: public:
@@ -387,9 +365,7 @@ public:
void append(const Tag &tag) void append(const Tag &tag)
{ {
TagNode *node = new TagNode(tag); TagNode *node = new TagNode(tag);
if (_node_stack.empty()) { if (!_node_stack.empty()) {
_root_node = node;
} else {
_node_stack.top()->append(node); _node_stack.top()->append(node);
} }
_node_stack.push(node); _node_stack.push(node);
@@ -399,9 +375,7 @@ public:
void append(const Object<T> &object) void append(const Object<T> &object)
{ {
ObjectNode<T> *node = new ObjectNode<T>(object); ObjectNode<T> *node = new ObjectNode<T>(object);
if (_node_stack.empty()) { if (!_node_stack.empty()) {
_root_node = node;
} else {
_node_stack.top()->append(node); _node_stack.top()->append(node);
} }
_node_stack.push(node); _node_stack.push(node);
@@ -409,13 +383,14 @@ public:
void append(const End &) void append(const End &)
{ {
_node_stack.pop(); Node *node = _node_stack.pop();
if (_node_stack.empty()) { if (_node_stack.empty()) {
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (xml_tag._tag_name != _root_node->getQualifiedName() || xml_tag._end_tag) { if (xml_tag._tag_name != node->getQualifiedName() || xml_tag._end_tag) {
throw FileFormatException(); throw FileFormatException();
} }
_root_node->accept(*this, xml_tag); node->accept(*this, xml_tag);
delete node;
} }
} }
@@ -587,12 +562,7 @@ public:
if (_loading_ref_map.hasObject(id)) { if (_loading_ref_map.hasObject(id)) {
p = _loading_ref_map.getObject<T *>(id); p = _loading_ref_map.getObject<T *>(id);
} else { } else {
if (_current_ref_node == 0) { throw UnexpectedForwardReference();
throw UnexpectedForwardReference();
}
_forward_references.append(ForwardReference(_current_ref_node, id));
// node is eaten, also used as flag for forward references
_current_ref_node = 0;
} }
} }
@@ -634,11 +604,6 @@ private:
throw FileFormatException(); throw FileFormatException();
} }
void visitForwardRef(Node *, const impl::ObjectId &)
{
throw UnexpectedForwardReference();
}
void visit(TagNode *node, const XmlTag &) void visit(TagNode *node, const XmlTag &)
{ {
readChildren(node); readChildren(node);
@@ -656,7 +621,7 @@ private:
template<class T, class U> template<class T, class U>
void visit(BaseNode<T, U> *node, const XmlTag &) void visit(BaseNode<T, U> *node, const XmlTag &)
{ {
(*this) >> node->getBase().getBase(); load(*this, node->getBase().getBase(), node->getBase().getParameters());
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (!xml_tag._end_tag || xml_tag._tag_name != node->getBase().getQualifiedName()) { if (!xml_tag._end_tag || xml_tag._tag_name != node->getBase().getQualifiedName()) {
throw FileFormatException(); throw FileFormatException();
@@ -666,7 +631,7 @@ private:
template<class T> template<class T>
void visit(AttrNode<T> *node, const XmlTag &) void visit(AttrNode<T> *node, const XmlTag &)
{ {
(*this) >> *node->getAttribute().getValue(); load(*this, *node->getAttribute().getValue(), node->getAttribute().getParameters());
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) { if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
throw FileFormatException(); throw FileFormatException();
@@ -677,7 +642,7 @@ private:
void visit(SetterAttrNode<U, T> *node, const XmlTag &) void visit(SetterAttrNode<U, T> *node, const XmlTag &)
{ {
T value; T value;
(*this) >> value; load(*this, value, node->getAttribute().getParameters());
(node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value); (node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value);
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) { if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
@@ -689,7 +654,7 @@ private:
void visit(SetterAttrNode<U, const T &> *node, const XmlTag &) void visit(SetterAttrNode<U, const T &> *node, const XmlTag &)
{ {
T value; T value;
(*this) >> value; load(*this, value, node->getAttribute().getParameters());
(node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value); (node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value);
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) { if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
@@ -701,7 +666,7 @@ private:
void visit(GetterSetterAttrNode<U, T, V> *node, const XmlTag &) void visit(GetterSetterAttrNode<U, T, V> *node, const XmlTag &)
{ {
V value; V value;
(*this) >> value; load(*this, value, node->getAttribute().getParameters());
(node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value); (node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value);
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) { if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
@@ -713,7 +678,7 @@ private:
void visit(GetterSetterAttrNode<U, T, const V &> *node, const XmlTag &) void visit(GetterSetterAttrNode<U, T, const V &> *node, const XmlTag &)
{ {
V value; V value;
(*this) >> value; load(*this, value, node->getAttribute().getParameters());
(node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value); (node->getAttribute().getObject().*(node->getAttribute().getSetter()))(value);
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) { if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
@@ -725,7 +690,7 @@ private:
void visit(SetFuncAttrNode<U, T> *node, const XmlTag &) void visit(SetFuncAttrNode<U, T> *node, const XmlTag &)
{ {
T value; T value;
(*this) >> value; load(*this, value, node->getAttribute().getParameters());
(node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value); (node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value);
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) { if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
@@ -737,7 +702,7 @@ private:
void visit(SetFuncAttrNode<U, const T &> *node, const XmlTag &) void visit(SetFuncAttrNode<U, const T &> *node, const XmlTag &)
{ {
T value; T value;
(*this) >> value; load(*this, value, node->getAttribute().getParameters());
(node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value); (node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value);
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) { if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
@@ -749,7 +714,7 @@ private:
void visit(GetSetFuncAttrNode<U, T, V> *node, const XmlTag &) void visit(GetSetFuncAttrNode<U, T, V> *node, const XmlTag &)
{ {
V value; V value;
(*this) >> value; load(*this, value, node->getAttribute().getParameters());
(node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value); (node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value);
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) { if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
@@ -761,7 +726,7 @@ private:
void visit(GetSetFuncAttrNode<U, T, const V &> *node, const XmlTag &) void visit(GetSetFuncAttrNode<U, T, const V &> *node, const XmlTag &)
{ {
V value; V value;
(*this) >> value; load(*this, value, node->getAttribute().getParameters());
(node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value); (node->getAttribute().getSetFunc())(node->getAttribute().getObject(), value);
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) { if (!xml_tag._end_tag || xml_tag._tag_name != node->getAttribute().getQualifiedName()) {
@@ -774,8 +739,8 @@ private:
{ {
_current_ref_node = node; _current_ref_node = node;
T value = T(); T value = T();
(*this) >> value; load(*this, value, node->getReference().getParameters());
if (_current_ref_node != 0) { // ref node was not eaten by forward reference if (_current_ref_node != 0) { // ref node was not consumed by forward reference
*node->getReference().getValue() = value; *node->getReference().getValue() = value;
_current_ref_node = 0; _current_ref_node = 0;
} }
@@ -785,23 +750,13 @@ private:
} }
} }
template<typename T>
void visitForwardRef(RefNode<T> *node, const impl::ObjectId &id)
{
if (!_loading_ref_map.hasObject(id)) {
throw UnexpectedForwardReference();
}
T value = _loading_ref_map.getObject<T>(id);
*(node->getReference().getValue()) = value;
}
template<class U, typename T> template<class U, typename T>
void visit(SetterRefNode<U, T> *node, const XmlTag &) void visit(SetterRefNode<U, T> *node, const XmlTag &)
{ {
_current_ref_node = node; _current_ref_node = node;
T value; T value;
(*this) >> value; load(*this, value, node->getReference().getParameters());
if (_current_ref_node != 0) { // ref node was not eaten by forward reference if (_current_ref_node != 0) { // ref node was not consumed by forward reference
(node->getReference().getObject().*(node->getReference().getSetter()))(value); (node->getReference().getObject().*(node->getReference().getSetter()))(value);
_current_ref_node = 0; _current_ref_node = 0;
} }
@@ -816,8 +771,8 @@ private:
{ {
_current_ref_node = node; _current_ref_node = node;
T value; T value;
(*this) >> value; load(*this, value, node->getReference().getParameters());
if (_current_ref_node != 0) { // ref node was not eaten by forward reference if (_current_ref_node != 0) { // ref node was not consumed by forward reference
(node->getReference().getObject().*(node->getReference().getSetter()))(value); (node->getReference().getObject().*(node->getReference().getSetter()))(value);
_current_ref_node = 0; _current_ref_node = 0;
} }
@@ -827,33 +782,13 @@ private:
} }
} }
template<class U, typename T>
void visitForwardRef(SetterRefNode<U, T> *node, const impl::ObjectId &id)
{
if (!_loading_ref_map.hasObject(id)) {
throw UnexpectedForwardReference();
}
T value = _loading_ref_map.getObject<T>(id);
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
}
template<class U, typename T>
void visitForwardRef(SetterRefNode<U, T const &> *node, const impl::ObjectId &id)
{
if (!_loading_ref_map.hasObject(id)) {
throw UnexpectedForwardReference();
}
T value = _loading_ref_map.getObject<T>(id);
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
}
template<class U, typename T, typename V> template<class U, typename T, typename V>
void visit(GetterSetterRefNode<U, T, V> *node, const XmlTag &) void visit(GetterSetterRefNode<U, T, V> *node, const XmlTag &)
{ {
_current_ref_node = node; _current_ref_node = node;
V value; V value;
(*this) >> value; load(*this, value, node->getReference().getParameters());
if (_current_ref_node != 0) { // ref node was not eaten by forward reference if (_current_ref_node != 0) { // ref node was not consumed by forward reference
(node->getReference().getObject().*(node->getReference().getSetter()))(value); (node->getReference().getObject().*(node->getReference().getSetter()))(value);
_current_ref_node = 0; _current_ref_node = 0;
} }
@@ -868,8 +803,8 @@ private:
{ {
_current_ref_node = node; _current_ref_node = node;
V value; V value;
(*this) >> value; load(*this, value, node->getReference().getParameters());
if (_current_ref_node != 0) { // ref node was not eaten by forward reference if (_current_ref_node != 0) { // ref node was not consumed by forward reference
(node->getReference().getObject().*(node->getReference().getSetter()))(value); (node->getReference().getObject().*(node->getReference().getSetter()))(value);
_current_ref_node = 0; _current_ref_node = 0;
} }
@@ -879,34 +814,14 @@ private:
} }
} }
template<class U, typename T, typename V>
void visitForwardRef(GetterSetterRefNode<U, T, V> *node, const impl::ObjectId &id)
{
if (!_loading_ref_map.hasObject(id)) {
throw UnexpectedForwardReference();
}
V value = _loading_ref_map.getObject<V>(id);
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
}
template<class U, typename T, typename V>
void visitForwardRef(GetterSetterRefNode<U, T, V const &> *node, const impl::ObjectId &id)
{
if (!_loading_ref_map.hasObject(id)) {
throw UnexpectedForwardReference();
}
V value = _loading_ref_map.getObject<V>(id);
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
}
template<class U, typename T> template<class U, typename T>
void visit(SetFuncRefNode<U, T> *node, const XmlTag &) void visit(SetFuncRefNode<U, T> *node, const XmlTag &)
{ {
_current_ref_node = node; _current_ref_node = node;
T value; T value;
(*this) >> value; load(*this, value, node->getReference().getParameters());
if (_current_ref_node != 0) { // ref node was not eaten by forward reference if (_current_ref_node != 0) { // ref node was not consumed by forward reference
(node->getReference().getObject().*(node->getReference().getSetter()))(value); (node->getReference().getSetFunc())(node->getReference().getObject(), value);
_current_ref_node = 0; _current_ref_node = 0;
} }
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
@@ -920,9 +835,9 @@ private:
{ {
_current_ref_node = node; _current_ref_node = node;
T value; T value;
(*this) >> value; load(*this, value, node->getReference().getParameters());
if (_current_ref_node != 0) { // ref node was not eaten by forward reference if (_current_ref_node != 0) { // ref node was not consumed by forward reference
(node->getReference().getObject().*(node->getReference().getSetter()))(value); (node->getReference().getSetFunc())(node->getReference().getObject(), value);
_current_ref_node = 0; _current_ref_node = 0;
} }
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
@@ -931,34 +846,14 @@ private:
} }
} }
template<class U, typename T>
void visitForwardRef(SetFuncRefNode<U, T> *node, const impl::ObjectId &id)
{
if (!_loading_ref_map.hasObject(id)) {
throw UnexpectedForwardReference();
}
T value = _loading_ref_map.getObject<T>(id);
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
}
template<class U, typename T>
void visitForwardRef(SetFuncRefNode<U, T const &> *node, const impl::ObjectId &id)
{
if (!_loading_ref_map.hasObject(id)) {
throw UnexpectedForwardReference();
}
T value = _loading_ref_map.getObject<T>(id);
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
}
template<class U, typename T, typename V> template<class U, typename T, typename V>
void visit(GetSetFuncRefNode<U, T, V> *node, const XmlTag &) void visit(GetSetFuncRefNode<U, T, V> *node, const XmlTag &)
{ {
_current_ref_node = node; _current_ref_node = node;
V value; V value;
(*this) >> value; load(*this, value, node->getReference().getParameters());
if (_current_ref_node != 0) { // ref node was not eaten by forward reference if (_current_ref_node != 0) { // ref node was not consumed by forward reference
(node->getReference().getObject().*(node->getReference().getSetter()))(value); (node->getReference().getSetFunc())(node->getReference().getObject(), value);
_current_ref_node = 0; _current_ref_node = 0;
} }
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
@@ -972,9 +867,9 @@ private:
{ {
_current_ref_node = node; _current_ref_node = node;
V value; V value;
(*this) >> value; load(*this, value, node->getReference().getParameters());
if (_current_ref_node != 0) { // ref node was not eaten by forward reference if (_current_ref_node != 0) { // ref node was not consumed by forward reference
(node->getReference().getObject().*(node->getReference().getSetter()))(value); (node->getReference().getSetFunc())(node->getReference().getObject(), value);
_current_ref_node = 0; _current_ref_node = 0;
} }
XmlTag xml_tag = readTag(); XmlTag xml_tag = readTag();
@@ -983,26 +878,6 @@ private:
} }
} }
template<class U, typename T, typename V>
void visitForwardRef(GetSetFuncRefNode<U, T, V> *node, const impl::ObjectId &id)
{
if (!_loading_ref_map.hasObject(id)) {
throw UnexpectedForwardReference();
}
V value = _loading_ref_map.getObject<V>(id);
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
}
template<class U, typename T, typename V>
void visitForwardRef(GetSetFuncRefNode<U, T, V const &> *node, const impl::ObjectId &id)
{
if (!_loading_ref_map.hasObject(id)) {
throw UnexpectedForwardReference();
}
V value = _loading_ref_map.getObject<V>(id);
(node->getReference().getObject().*(node->getReference().getSetter()))(value);
}
private: private:
inline XmlTag readTag(); inline XmlTag readTag();
@@ -1012,11 +887,9 @@ private:
private: private:
QXmlStreamReader &_stream; QXmlStreamReader &_stream;
bool _end_tag_was_read; bool _end_tag_was_read;
Node *_root_node;
QStack<Node *> _node_stack; QStack<Node *> _node_stack;
impl::LoadingRefMap _loading_ref_map; impl::LoadingRefMap _loading_ref_map;
Node *_current_ref_node; Node *_current_ref_node;
QList<ForwardReference> _forward_references;
}; };

View File

@@ -49,8 +49,13 @@ class QXmlOutArchive :
{ {
public: public:
class UnsupportedForwardReference :
public std::exception
{
};
class DanglingReferences : class DanglingReferences :
public std::exception public std::exception
{ {
}; };
@@ -58,6 +63,7 @@ public:
static const bool out_archive = true; static const bool out_archive = true;
public: public:
QXmlOutArchive(QXmlStreamWriter &stream) QXmlOutArchive(QXmlStreamWriter &stream)
: _stream(stream), : _stream(stream),
_next_pointer_is_reference(false) _next_pointer_is_reference(false)
@@ -76,6 +82,9 @@ public:
template<typename T> template<typename T>
void write(T *p) void write(T *p)
{ {
if (!_saving_ref_map.hasDefinedRef(p)) {
throw UnsupportedForwardReference();
}
write(_saving_ref_map.getRef(p).get()); write(_saving_ref_map.getRef(p).get());
} }

View File

@@ -31,6 +31,8 @@
#ifndef QARK_REFERENCE_H #ifndef QARK_REFERENCE_H
#define QARK_REFERENCE_H #define QARK_REFERENCE_H
#include "parameters.h"
#include <QString> #include <QString>
namespace qark { namespace qark {
@@ -38,19 +40,29 @@ namespace qark {
template<typename T> template<typename T>
class Ref { class Ref {
public: public:
explicit Ref(const QString &qualified_name, T *value) Ref(const QString &qualified_name, T *value)
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_value(value) _value(value)
{ {
} }
Ref(const QString &qualified_name, T *value, const Parameters &parameters)
: _qualified_name(qualified_name),
_value(value),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
T *getValue() const { return _value; } T *getValue() const { return _value; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
T *_value; T *_value;
Parameters _parameters;
}; };
template<typename T> template<typename T>
@@ -59,32 +71,56 @@ Ref<T * const> ref(const QString &qualified_name, T * const &value)
return Ref<T * const>(qualified_name, &value); return Ref<T * const>(qualified_name, &value);
} }
template<typename T>
Ref<T * const> ref(const QString &qualified_name, T * const &value, const Parameters &parameters)
{
return Ref<T * const>(qualified_name, &value, parameters);
}
template<typename T> template<typename T>
Ref<T *> ref(const QString &qualified_name, T *&value) Ref<T *> ref(const QString &qualified_name, T *&value)
{ {
return Ref<T *>(qualified_name, &value); return Ref<T *>(qualified_name, &value);
} }
template<typename T>
Ref<T *> ref(const QString &qualified_name, T *&value, const Parameters &parameters)
{
return Ref<T *>(qualified_name, &value, parameters);
}
template<class U, typename T> template<class U, typename T>
class GetterRef { class GetterRef {
public: public:
explicit GetterRef(const QString &qualified_name, const U &u, T (U::*getter)() const) GetterRef(const QString &qualified_name, const U &u, T (U::*getter)() const)
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_getter(getter) _getter(getter)
{ {
} }
GetterRef(const QString &qualified_name, const U &u, T (U::*getter)() const, const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_getter(getter),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
const U &getObject() const { return _u; } const U &getObject() const { return _u; }
T (U::*getGetter() const)() const { return _getter; } T (U::*getGetter() const)() const { return _getter; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
const U &_u; const U &_u;
T (U::*_getter)() const; T (U::*_getter)() const;
Parameters _parameters;
}; };
template<class U, typename T> template<class U, typename T>
@@ -93,27 +129,44 @@ GetterRef<U, T *> ref(const QString &qualified_name, const U &u, T *(U::*getter)
return GetterRef<U, T *>(qualified_name, u, getter); return GetterRef<U, T *>(qualified_name, u, getter);
} }
template<class U, typename T>
GetterRef<U, T *> ref(const QString &qualified_name, const U &u, T *(U::*getter)() const, const Parameters &parameters)
{
return GetterRef<U, T *>(qualified_name, u, getter, parameters);
}
template<class U, typename T> template<class U, typename T>
class SetterRef { class SetterRef {
public: public:
explicit SetterRef(const QString &qualified_name, U &u, void (U::*setter)(T)) SetterRef(const QString &qualified_name, U &u, void (U::*setter)(T))
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_setter(setter) _setter(setter)
{ {
} }
SetterRef(const QString &qualified_name, U &u, void (U::*setter)(T), const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_setter(setter),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
U &getObject() const { return _u; } U &getObject() const { return _u; }
void (U::*getSetter() const)(T) { return _setter; } void (U::*getSetter() const)(T) { return _setter; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
U &_u; U &_u;
void (U::*_setter)(T); void (U::*_setter)(T);
Parameters _parameters;
}; };
template<class U, class T> template<class U, class T>
@@ -122,16 +175,29 @@ SetterRef<U, T *> ref(const QString &qualified_name, U &u, void (U::*setter)(T *
return SetterRef<U, T *>(qualified_name, u, setter); return SetterRef<U, T *>(qualified_name, u, setter);
} }
template<class U, class T>
SetterRef<U, T *> ref(const QString &qualified_name, U &u, void (U::*setter)(T *), const Parameters &parameters)
{
return SetterRef<U, T *>(qualified_name, u, setter, parameters);
}
template<class U, class T> template<class U, class T>
SetterRef<U, T * const &> ref(const QString &qualified_name, U &u, void (U::*setter)(T * const &)) SetterRef<U, T * const &> ref(const QString &qualified_name, U &u, void (U::*setter)(T * const &))
{ {
return SetterRef<U, T * const &>(qualified_name, u, setter); return SetterRef<U, T * const &>(qualified_name, u, setter);
} }
template<class U, class T>
SetterRef<U, T * const &> ref(const QString &qualified_name, U &u, void (U::*setter)(T * const &), const Parameters &parameters)
{
return SetterRef<U, T * const &>(qualified_name, u, setter, parameters);
}
template<class U, typename T, typename V> template<class U, typename T, typename V>
class GetterSetterRef { class GetterSetterRef {
public: public:
explicit GetterSetterRef(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V)) GetterSetterRef(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V))
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_getter(getter), _getter(getter),
@@ -139,6 +205,15 @@ public:
{ {
} }
GetterSetterRef(const QString &qualified_name, U &u, T (U::*getter)() const, void (U::*setter)(V), const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_getter(getter),
_setter(setter),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
U &getObject() const { return _u; } U &getObject() const { return _u; }
@@ -147,11 +222,14 @@ public:
void (U::*getSetter() const)(V) { return _setter; } void (U::*getSetter() const)(V) { return _setter; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
U &_u; U &_u;
T (U::*_getter)() const; T (U::*_getter)() const;
void (U::*_setter)(V); void (U::*_setter)(V);
Parameters _parameters;
}; };
template<class U, typename T, typename V> template<class U, typename T, typename V>
@@ -160,32 +238,56 @@ GetterSetterRef<U, T *, V *> ref(const QString &qualified_name, U &u, T *(U::*ge
return GetterSetterRef<U, T *, V *>(qualified_name, u, getter, setter); return GetterSetterRef<U, T *, V *>(qualified_name, u, getter, setter);
} }
template<class U, typename T, typename V>
GetterSetterRef<U, T *, V *> ref(const QString &qualified_name, U &u, T *(U::*getter)() const, void (U::*setter)(V *), const Parameters &parameters)
{
return GetterSetterRef<U, T *, V *>(qualified_name, u, getter, setter, parameters);
}
template<class U, typename T, typename V> template<class U, typename T, typename V>
GetterSetterRef<U, T *, V * const &> ref(const QString &qualified_name, U &u, T *(U::*getter)() const, void (U::*setter)(V * const &)) GetterSetterRef<U, T *, V * const &> ref(const QString &qualified_name, U &u, T *(U::*getter)() const, void (U::*setter)(V * const &))
{ {
return GetterSetterRef<U, T *, V * const &>(qualified_name, u, getter, setter); return GetterSetterRef<U, T *, V * const &>(qualified_name, u, getter, setter);
} }
template<class U, typename T, typename V>
GetterSetterRef<U, T *, V * const &> ref(const QString &qualified_name, U &u, T *(U::*getter)() const, void (U::*setter)(V * const &), const Parameters &parameters)
{
return GetterSetterRef<U, T *, V * const &>(qualified_name, u, getter, setter, parameters);
}
template<class U, typename T> template<class U, typename T>
class GetFuncRef { class GetFuncRef {
public: public:
explicit GetFuncRef(const QString &qualified_name, const U &u, T (*get_func)(const U &)) GetFuncRef(const QString &qualified_name, const U &u, T (*get_func)(const U &))
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_get_func(get_func) _get_func(get_func)
{ {
} }
GetFuncRef(const QString &qualified_name, const U &u, T (*get_func)(const U &), const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_get_func(get_func),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
const U &getObject() const { return _u; } const U &getObject() const { return _u; }
T (*getGetFunc() const)(const U &) { return _get_func; } T (*getGetFunc() const)(const U &) { return _get_func; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
const U &_u; const U &_u;
T (*_get_func)(const U &); T (*_get_func)(const U &);
Parameters _parameters;
}; };
template<class U, typename T> template<class U, typename T>
@@ -194,27 +296,44 @@ GetFuncRef<U, T *> ref(const QString &qualified_name, const U &u, T *(*get_func)
return GetFuncRef<U, T *>(qualified_name, u, get_func); return GetFuncRef<U, T *>(qualified_name, u, get_func);
} }
template<class U, typename T>
GetFuncRef<U, T *> ref(const QString &qualified_name, const U &u, T *(*get_func)(const U &), const Parameters &parameters)
{
return GetFuncRef<U, T *>(qualified_name, u, get_func, parameters);
}
template<class U, typename T> template<class U, typename T>
class SetFuncRef { class SetFuncRef {
public: public:
explicit SetFuncRef(const QString &qualified_name, U &u, void (*set_func)(U &, T)) SetFuncRef(const QString &qualified_name, U &u, void (*set_func)(U &, T))
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_set_func(set_func) _set_func(set_func)
{ {
} }
SetFuncRef(const QString &qualified_name, U &u, void (*set_func)(U &, T), const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_set_func(set_func),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
U &getObject() const { return _u; } U &getObject() const { return _u; }
void (*getSetFunc() const)(U &, T) { return _set_func; } void (*getSetFunc() const)(U &, T) { return _set_func; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
U &_u; U &_u;
void (*_set_func)(U &, T); void (*_set_func)(U &, T);
Parameters _parameters;
}; };
template<class U, class T> template<class U, class T>
@@ -223,16 +342,29 @@ SetFuncRef<U, T *> ref(const QString &qualified_name, U &u, void (*set_func)(U &
return SetFuncRef<U, T *>(qualified_name, u, set_func); return SetFuncRef<U, T *>(qualified_name, u, set_func);
} }
template<class U, class T>
SetFuncRef<U, T *> ref(const QString &qualified_name, U &u, void (*set_func)(U &, T *), const Parameters &parameters)
{
return SetFuncRef<U, T *>(qualified_name, u, set_func, parameters);
}
template<class U, class T> template<class U, class T>
SetFuncRef<U, T * const &> ref(const QString &qualified_name, U &u, void (*set_func)(U &, T * const &)) SetFuncRef<U, T * const &> ref(const QString &qualified_name, U &u, void (*set_func)(U &, T * const &))
{ {
return SetFuncRef<U, T * const &>(qualified_name, u, set_func); return SetFuncRef<U, T * const &>(qualified_name, u, set_func);
} }
template<class U, class T>
SetFuncRef<U, T * const &> ref(const QString &qualified_name, U &u, void (*set_func)(U &, T * const &), const Parameters &parameters)
{
return SetFuncRef<U, T * const &>(qualified_name, u, set_func, parameters);
}
template<class U, typename T, typename V> template<class U, typename T, typename V>
class GetSetFuncRef { class GetSetFuncRef {
public: public:
explicit GetSetFuncRef(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V)) GetSetFuncRef(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V))
: _qualified_name(qualified_name), : _qualified_name(qualified_name),
_u(u), _u(u),
_get_func(get_func), _get_func(get_func),
@@ -240,6 +372,15 @@ public:
{ {
} }
GetSetFuncRef(const QString &qualified_name, U &u, T (*get_func)(const U &), void (*set_func)(U &, V), const Parameters &parameters)
: _qualified_name(qualified_name),
_u(u),
_get_func(get_func),
_set_func(set_func),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
U &getObject() const { return _u; } U &getObject() const { return _u; }
@@ -248,11 +389,14 @@ public:
void (*getSetFunc() const)(U &, V) { return _set_func; } void (*getSetFunc() const)(U &, V) { return _set_func; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
U &_u; U &_u;
T (*_get_func)(const U &); T (*_get_func)(const U &);
void (*_set_func)(U &, V); void (*_set_func)(U &, V);
Parameters _parameters;
}; };
template<class U, typename T, typename V> template<class U, typename T, typename V>
@@ -261,12 +405,24 @@ GetSetFuncRef<U, T *, V *> ref(const QString &qualified_name, U &u, T *(*get_fun
return GetSetFuncRef<U, T *, V *>(qualified_name, u, get_func, set_func); return GetSetFuncRef<U, T *, V *>(qualified_name, u, get_func, set_func);
} }
template<class U, typename T, typename V>
GetSetFuncRef<U, T *, V *> ref(const QString &qualified_name, U &u, T *(*get_func)(const U &), void (*set_func)(U &, V *), const Parameters &parameters)
{
return GetSetFuncRef<U, T *, V *>(qualified_name, u, get_func, set_func, parameters);
}
template<class U, typename T, typename V> template<class U, typename T, typename V>
GetSetFuncRef<U, T *, V * const &> ref(const QString &qualified_name, U &u, T *(*get_func)(const U &), void (*set_func)(U &, V * const &)) GetSetFuncRef<U, T *, V * const &> ref(const QString &qualified_name, U &u, T *(*get_func)(const U &), void (*set_func)(U &, V * const &))
{ {
return GetSetFuncRef<U, T *, V * const &>(qualified_name, u, get_func, set_func); return GetSetFuncRef<U, T *, V * const &>(qualified_name, u, get_func, set_func);
} }
template<class U, typename T, typename V>
GetSetFuncRef<U, T *, V * const &> ref(const QString &qualified_name, U &u, T *(*get_func)(const U &), void (*set_func)(U &, V * const &), const Parameters &parameters)
{
return GetSetFuncRef<U, T *, V * const &>(qualified_name, u, get_func, set_func, parameters);
}
} }
#endif // QARK_REFERENCE_H #endif // QARK_REFERENCE_H

View File

@@ -38,6 +38,7 @@
#include "access.h" #include "access.h"
#include "typeregistry.h" #include "typeregistry.h"
#include "serialize_pointer.h"
#include "serialize_basic.h" #include "serialize_basic.h"
#include "serialize_container.h" #include "serialize_container.h"
#include "serialize_enum.h" #include "serialize_enum.h"
@@ -51,102 +52,27 @@ namespace qark {
template<class Archive, class T> template<class Archive, class T>
inline Archive &operator<<(Archive &archive, const T &t) inline Archive &operator<<(Archive &archive, const T &t)
{ {
save(archive, t); save(archive, t, Parameters());
return archive; return archive;
} }
template<class Archive, class T> template<class Archive, class T>
inline Archive &operator>>(Archive &archive, T &t) inline Archive &operator>>(Archive &archive, T &t)
{ {
load(archive, t); load(archive, t, Parameters());
return archive; return archive;
} }
template<class Archive, class T> template<class Archive, class T>
typename std::enable_if<Archive::out_archive, Archive &>::type operator||(Archive &archive, T &t) typename std::enable_if<Archive::out_archive, Archive &>::type operator||(Archive &archive, T &t)
{ {
save(archive, (const T &) t); return archive << t;
return archive;
} }
template<class Archive, class T> template<class Archive, class T>
typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive &archive, T &t) typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive &archive, T &t)
{ {
load(archive, t); return archive >> t;
return archive;
}
template<class Archive, class T>
inline Archive &operator<<(Archive &archive, T *p)
{
if (p) {
if (archive.isReference(p)) {
archive.beginPointer();
archive.write(p);
archive.endPointer();
} else {
if (typeid(*p) == typeid(T)) {
archive.beginInstance();
registry::save_pointer<Archive, T, T>(archive, p);
archive.endInstance();
} else {
archive.beginInstance(get_type_uid(*p));
//typename registry::TypeRegistry<Archive, typename qark::non_const<T>::type>::type_info type_data
// = get_type_info<Archive, typename qark::non_const<T>::type>(*p);
typename registry::TypeRegistry<Archive, T>::type_info type_data = get_type_info<Archive, T>(*p);
if (type_data.save_func == 0) {
throw unregistered_type();
} else {
type_data.save_func(archive, p);
}
archive.endInstance();
}
}
} else {
archive.beginNullPointer();
archive.endNullPointer();
}
return archive;
}
template<class Archive, class T>
inline Archive &operator>>(Archive &archive, T *&p)
{
typename Archive::ReferenceTag ref_tag = archive.readReferenceTag();
switch (ref_tag.kind) {
case Archive::NULLPOINTER:
p = 0;
break;
case Archive::POINTER:
archive.read(p);
break;
case Archive::INSTANCE:
if (ref_tag.type_name.isEmpty()) {
registry::load_non_virtual_pointer<Archive,T>(archive, p);
} else {
typename registry::TypeRegistry<Archive, T>::type_info type_data = get_type_info<Archive, T>(ref_tag.type_name);
if (type_data.load_func == 0) {
throw unregistered_type();
} else {
type_data.load_func(archive, p);
}
}
break;
}
archive.readReferenceEndTag(ref_tag.kind);
return archive;
}
template<class Archive, class T>
typename std::enable_if<Archive::out_archive, Archive &>::type operator||(Archive &archive, T *&p)
{
return archive << p;
}
template<class Archive, class T>
typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive &archive, T *&p)
{
return archive >> p;
} }
template<class Archive, class T> template<class Archive, class T>
@@ -175,32 +101,6 @@ typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive
return archive >> f; return archive >> f;
} }
template<class Archive>
inline Archive &operator<<(Archive &archive, void (*f)(Archive &))
{
f(archive);
return archive;
}
template<class Archive>
inline Archive &operator>>(Archive &archive, void (*f)(Archive &))
{
f(archive);
return archive;
}
template<class Archive>
typename std::enable_if<Archive::out_archive, Archive &>::type operator||(Archive &archive, void (*f)(Archive &))
{
return archive << f;
}
template<class Archive>
typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive &archive, void (*f)(Archive &))
{
return archive >> f;
}
template<class Archive> template<class Archive>
inline Archive &operator<<(Archive &archive, const Tag &tag) inline Archive &operator<<(Archive &archive, const Tag &tag)
{ {
@@ -311,7 +211,7 @@ template<class Archive, typename T>
Archive &operator<<(Archive &archive, const Attr<T> &attr) Archive &operator<<(Archive &archive, const Attr<T> &attr)
{ {
archive.beginAttribute(attr); archive.beginAttribute(attr);
archive << *attr.getValue(); save(archive, *attr.getValue(), attr.getParameters());
archive.endAttribute(attr); archive.endAttribute(attr);
return archive; return archive;
} }
@@ -336,10 +236,23 @@ typename std::enable_if<Archive::in_archive, Archive &>::type operator||(Archive
} }
template<class Archive, class U, typename T> template<class Archive, class U, typename T>
Archive &operator<<(Archive &archive, const GetterAttr<U, T> &attr) typename std::enable_if<!std::is_abstract<U>::value, Archive &>::type
operator<<(Archive &archive, const GetterAttr<U, T> &attr)
{
if (!((attr.getObject().*(attr.getGetter()))() == (U().*(attr.getGetter()))())) {
archive.beginAttribute(attr);
save(archive, (attr.getObject().*(attr.getGetter()))(), attr.getParameters());
archive.endAttribute(attr);
}
return archive;
}
template<class Archive, class U, typename T>
typename std::enable_if<std::is_abstract<U>::value, Archive &>::type
operator<<(Archive &archive, const GetterAttr<U, T> &attr)
{ {
archive.beginAttribute(attr); archive.beginAttribute(attr);
archive << (attr.getObject().*(attr.getGetter()))(); save(archive, (attr.getObject().*(attr.getGetter()))(), attr.getParameters());
archive.endAttribute(attr); archive.endAttribute(attr);
return archive; return archive;
} }
@@ -358,7 +271,7 @@ operator<<(Archive &archive, const GetterSetterAttr<U, T, V> &attr)
{ {
if (!((attr.getObject().*(attr.getGetter()))() == (U().*(attr.getGetter()))())) { if (!((attr.getObject().*(attr.getGetter()))() == (U().*(attr.getGetter()))())) {
archive.beginAttribute(attr); archive.beginAttribute(attr);
archive << (attr.getObject().*(attr.getGetter()))(); save(archive, (attr.getObject().*(attr.getGetter()))(), attr.getParameters());
archive.endAttribute(attr); archive.endAttribute(attr);
} }
return archive; return archive;
@@ -370,7 +283,7 @@ typename std::enable_if<std::is_abstract<U>::value, Archive &>::type
operator<<(Archive &archive, const GetterSetterAttr<U, T, V> &attr) operator<<(Archive &archive, const GetterSetterAttr<U, T, V> &attr)
{ {
archive.beginAttribute(attr); archive.beginAttribute(attr);
archive << (attr.getObject().*(attr.getGetter()))(); save(archive, (attr.getObject().*(attr.getGetter()))(), attr.getParameters());
archive.endAttribute(attr); archive.endAttribute(attr);
return archive; return archive;
} }
@@ -398,7 +311,7 @@ template<class Archive, class U, typename T>
Archive &operator<<(Archive &archive, const GetFuncAttr<U, T> &attr) Archive &operator<<(Archive &archive, const GetFuncAttr<U, T> &attr)
{ {
archive.beginAttribute(attr); archive.beginAttribute(attr);
archive << ((*attr.getGetFunc())(attr.getObject())); save(archive, ((*attr.getGetFunc())(attr.getObject())), attr.getParameters());
archive.endAttribute(attr); archive.endAttribute(attr);
return archive; return archive;
} }
@@ -414,7 +327,7 @@ template<class Archive, class U, typename T, typename V>
Archive &operator<<(Archive &archive, const GetSetFuncAttr<U, T, V> &attr) Archive &operator<<(Archive &archive, const GetSetFuncAttr<U, T, V> &attr)
{ {
archive.beginAttribute(attr); archive.beginAttribute(attr);
archive << ((*attr.getGetFunc())(attr.getObject())); save(archive, ((*attr.getGetFunc())(attr.getObject())), attr.getParameters());
archive.endAttribute(attr); archive.endAttribute(attr);
return archive; return archive;
} }
@@ -442,7 +355,7 @@ template<class Archive, typename T>
Archive &operator<<(Archive &archive, const Ref<T *> &ref) Archive &operator<<(Archive &archive, const Ref<T *> &ref)
{ {
archive.beginReference(ref); archive.beginReference(ref);
archive << *ref.getValue(); save(archive, *ref.getValue(), ref.getParameters());
archive.endReference(ref); archive.endReference(ref);
return archive; return archive;
} }
@@ -451,7 +364,7 @@ template<class Archive, typename T>
Archive &operator<<(Archive &archive, const Ref<T * const> &ref) Archive &operator<<(Archive &archive, const Ref<T * const> &ref)
{ {
archive.beginReference(ref); archive.beginReference(ref);
archive << *ref.getValue(); save(archive, *ref.getValue(), ref.getParameters());
archive.endReference(ref); archive.endReference(ref);
return archive; return archive;
} }
@@ -467,7 +380,7 @@ template<class Archive, typename T>
typename std::enable_if<Archive::out_archive, Archive &>::type operator||(Archive &archive, const Ref<T *> &ref) typename std::enable_if<Archive::out_archive, Archive &>::type operator||(Archive &archive, const Ref<T *> &ref)
{ {
archive.beginReference(ref); archive.beginReference(ref);
archive << *ref.getValue(); save(archive, *ref.getValue(), ref.getParameters());
archive.endReference(ref); archive.endReference(ref);
return archive; return archive;
} }
@@ -482,7 +395,7 @@ template<class Archive, class U, typename T>
Archive &operator<<(Archive &archive, const GetterRef<U, T> &ref) Archive &operator<<(Archive &archive, const GetterRef<U, T> &ref)
{ {
archive.beginReference(ref); archive.beginReference(ref);
archive << (ref.getObject().*(ref.getGetter()))(); save(archive, (ref.getObject().*(ref.getGetter()))(), ref.getParameters());
archive.endReference(ref); archive.endReference(ref);
return archive; return archive;
} }
@@ -498,7 +411,7 @@ template<class Archive, class U, typename T, typename V>
Archive &operator<<(Archive &archive, const GetterSetterRef<U, T, V> &ref) Archive &operator<<(Archive &archive, const GetterSetterRef<U, T, V> &ref)
{ {
archive.beginReference(ref); archive.beginReference(ref);
archive << (ref.getObject().*(ref.getGetter()))(); save(archive, (ref.getObject().*(ref.getGetter()))(), ref.getParameters());
archive.endReference(ref); archive.endReference(ref);
return archive; return archive;
} }
@@ -526,7 +439,7 @@ template<class Archive, class U, typename T>
Archive &operator<<(Archive &archive, const GetFuncRef<U, T> &ref) Archive &operator<<(Archive &archive, const GetFuncRef<U, T> &ref)
{ {
archive.beginReference(ref); archive.beginReference(ref);
archive << ref.getGetFunc()(ref.getObject()); save(archive, ref.getGetFunc()(ref.getObject()), ref.getParameters());
archive.endReference(ref); archive.endReference(ref);
return archive; return archive;
} }
@@ -542,7 +455,7 @@ template<class Archive, class U, typename T, typename V>
Archive &operator<<(Archive &archive, const GetSetFuncRef<U, T, V> &ref) Archive &operator<<(Archive &archive, const GetSetFuncRef<U, T, V> &ref)
{ {
archive.beginReference(ref); archive.beginReference(ref);
archive << ref.getGetFunc()(ref.getObject()); save(archive, ref.getGetFunc()(ref.getObject()), ref.getParameters());
archive.endReference(ref); archive.endReference(ref);
return archive; return archive;
} }

View File

@@ -31,6 +31,7 @@
#ifndef QARK_SERIALIZE_BASIC_H #ifndef QARK_SERIALIZE_BASIC_H
#define QARK_SERIALIZE_BASIC_H #define QARK_SERIALIZE_BASIC_H
#include "parameters.h"
#include "qstringparser/qstringparser.h" #include "qstringparser/qstringparser.h"
#include <QString> #include <QString>
@@ -42,12 +43,12 @@
#define QARK_BASIC_SAVELOAD(TYPE) \ #define QARK_BASIC_SAVELOAD(TYPE) \
template<class Archive> \ template<class Archive> \
inline void save(Archive &archive, TYPE v) \ inline void save(Archive &archive, TYPE v, const Parameters &) \
{ \ { \
archive.write(v); \ archive.write(v); \
} \ } \
template<class Archive> \ template<class Archive> \
inline void load(Archive &archive, TYPE &v) \ inline void load(Archive &archive, TYPE &v, const Parameters &) \
{ \ { \
archive.read(&v); \ archive.read(&v); \
} }
@@ -79,13 +80,13 @@ QARK_BASIC_SAVELOAD(QString)
// QPointF // QPointF
template<class Archive> template<class Archive>
inline void save(Archive &archive, const QPointF &point) inline void save(Archive &archive, const QPointF &point, const Parameters &)
{ {
archive.write(QString(QStringLiteral("x:%1;y:%2")).arg(point.x()).arg(point.y())); archive.write(QString(QStringLiteral("x:%1;y:%2")).arg(point.x()).arg(point.y()));
} }
template<class Archive> template<class Archive>
inline void load(Archive &archive, QPointF &point) inline void load(Archive &archive, QPointF &point, const Parameters &)
{ {
QString s; QString s;
archive.read(&s); archive.read(&s);
@@ -98,13 +99,13 @@ inline void load(Archive &archive, QPointF &point)
// QRectF // QRectF
template<class Archive> template<class Archive>
inline void save(Archive &archive, const QRectF &rect) inline void save(Archive &archive, const QRectF &rect, const Parameters &)
{ {
archive.write(QString(QStringLiteral("x:%1;y:%2;w:%3;h:%4")).arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height())); archive.write(QString(QStringLiteral("x:%1;y:%2;w:%3;h:%4")).arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height()));
} }
template<class Archive> template<class Archive>
inline void load(Archive &archive, QRectF &point) inline void load(Archive &archive, QRectF &point, const Parameters &)
{ {
QString s; QString s;
archive.read(&s); archive.read(&s);
@@ -117,13 +118,13 @@ inline void load(Archive &archive, QRectF &point)
// QDateTime // QDateTime
template<class Archive> template<class Archive>
inline void save(Archive &archive, const QDateTime &date_time) inline void save(Archive &archive, const QDateTime &date_time, const Parameters &)
{ {
archive << date_time.toMSecsSinceEpoch(); archive << date_time.toMSecsSinceEpoch();
} }
template<class Archive> template<class Archive>
inline void load(Archive &archive, QDateTime &date_time) inline void load(Archive &archive, QDateTime &date_time, const Parameters &)
{ {
qint64 t; qint64 t;
archive >> t; archive >> t;

View File

@@ -31,31 +31,22 @@
#ifndef QARK_SERIALIZE_CONTAINER_H #ifndef QARK_SERIALIZE_CONTAINER_H
#define QARK_SERIALIZE_CONTAINER_H #define QARK_SERIALIZE_CONTAINER_H
#include "flag.h" #include "parameters.h"
#include <QList> #include <QList>
#include <QHash> #include <QHash>
namespace qark { namespace qark {
namespace impl { static Flag ENFORCE_REFERENCED_ITEMS;
static Flag container_item_ref_flag;
}
template<class Archive>
inline void ref_item(Archive &archive)
{
archive.setFlag(impl::container_item_ref_flag);
}
// QList // QList
template<class Archive, class T> template<class Archive, class T>
inline void save(Archive &archive, const QList<T> &list) inline void save(Archive &archive, const QList<T> &list, const Parameters &)
{ {
archive << tag("qlist"); archive << tag("qlist");
archive.clearFlag(impl::container_item_ref_flag);
foreach (const T &t, list) { foreach (const T &t, list) {
archive << attr(QStringLiteral("item"), t); archive << attr(QStringLiteral("item"), t);
} }
@@ -63,10 +54,10 @@ inline void save(Archive &archive, const QList<T> &list)
} }
template<class Archive, class T> template<class Archive, class T>
inline void save(Archive &archive, const QList<T *> &list) inline void save(Archive &archive, const QList<T *> &list, const Parameters &parameters)
{ {
archive << tag("qlist"); archive << tag("qlist");
if (archive.takeFlag(impl::container_item_ref_flag)) { if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
foreach (const T *t, list) { foreach (const T *t, list) {
archive << ref(QStringLiteral("item"), t); archive << ref(QStringLiteral("item"), t);
} }
@@ -79,7 +70,7 @@ inline void save(Archive &archive, const QList<T *> &list)
} }
template<class Archive, class T> template<class Archive, class T>
inline void load(Archive &archive, QList<T> &list) inline void load(Archive &archive, QList<T> &list, const Parameters &)
{ {
archive >> tag(QStringLiteral("qlist")); archive >> tag(QStringLiteral("qlist"));
archive >> attr<QList<T>, const T &>(QStringLiteral("item"), list, &QList<T>::append); archive >> attr<QList<T>, const T &>(QStringLiteral("item"), list, &QList<T>::append);
@@ -87,10 +78,10 @@ inline void load(Archive &archive, QList<T> &list)
} }
template<class Archive, class T> template<class Archive, class T>
inline void load(Archive &archive, QList<T *> &list) inline void load(Archive &archive, QList<T *> &list, const Parameters &parameters)
{ {
archive >> tag(QStringLiteral("qlist")); archive >> tag(QStringLiteral("qlist"));
if (archive.takeFlag(impl::container_item_ref_flag)) { if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
// why does the following line not compile but the line below selects the correct function? // why does the following line not compile but the line below selects the correct function?
//archive >> ref<QList<T *>, T * const &>("item", list, &QList<T *>::append); //archive >> ref<QList<T *>, T * const &>("item", list, &QList<T *>::append);
archive >> ref(QStringLiteral("item"), list, &QList<T *>::append); archive >> ref(QStringLiteral("item"), list, &QList<T *>::append);
@@ -104,10 +95,9 @@ inline void load(Archive &archive, QList<T *> &list)
// QSet // QSet
template<class Archive, class T> template<class Archive, class T>
inline void save(Archive &archive, const QSet<T> &set) inline void save(Archive &archive, const QSet<T> &set, const Parameters &)
{ {
archive << tag("qset"); archive << tag("qset");
archive.clearFlag(impl::container_item_ref_flag);
foreach (const T &t, set) { foreach (const T &t, set) {
archive << attr(QStringLiteral("item"), t); archive << attr(QStringLiteral("item"), t);
} }
@@ -115,10 +105,10 @@ inline void save(Archive &archive, const QSet<T> &set)
} }
template<class Archive, class T> template<class Archive, class T>
inline void save(Archive &archive, const QSet<T *> &set) inline void save(Archive &archive, const QSet<T *> &set, const Parameters &parameters)
{ {
archive << tag("qset"); archive << tag("qset");
if (archive.takeFlag(impl::container_item_ref_flag)) { if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
foreach (const T *t, set) { foreach (const T *t, set) {
archive << ref(QStringLiteral("item"), t); archive << ref(QStringLiteral("item"), t);
} }
@@ -140,7 +130,7 @@ void insertIntoSet(QSet<T> &set, const T &t) {
} }
template<class Archive, class T> template<class Archive, class T>
inline void load(Archive &archive, QSet<T> &set) inline void load(Archive &archive, QSet<T> &set, const Parameters &)
{ {
archive >> tag(QStringLiteral("qset")); archive >> tag(QStringLiteral("qset"));
archive >> attr<QSet<T>, const T &>(QStringLiteral("item"), set, &impl::insertIntoSet<T>); archive >> attr<QSet<T>, const T &>(QStringLiteral("item"), set, &impl::insertIntoSet<T>);
@@ -148,10 +138,10 @@ inline void load(Archive &archive, QSet<T> &set)
} }
template<class Archive, class T> template<class Archive, class T>
inline void load(Archive &archive, QSet<T *> &set) inline void load(Archive &archive, QSet<T *> &set, const Parameters &parameters)
{ {
archive >> tag(QStringLiteral("qset")); archive >> tag(QStringLiteral("qset"));
if (archive.takeFlag(impl::container_item_ref_flag)) { if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
archive >> ref(QStringLiteral("item"), set, &impl::insertIntoSet<T *>); archive >> ref(QStringLiteral("item"), set, &impl::insertIntoSet<T *>);
} else { } else {
archive >> attr<QSet<T *>, T * const &>(QStringLiteral("item"), set, &impl::insertIntoSet<T *>); archive >> attr<QSet<T *>, T * const &>(QStringLiteral("item"), set, &impl::insertIntoSet<T *>);
@@ -177,7 +167,7 @@ public:
} }
template<class Archive, class KEY, class VALUE> template<class Archive, class KEY, class VALUE>
inline void save(Archive &archive, const impl::KeyValuePair<KEY, VALUE> &pair) inline void save(Archive &archive, const impl::KeyValuePair<KEY, VALUE> &pair, const Parameters &)
{ {
archive << tag(QStringLiteral("pair")) archive << tag(QStringLiteral("pair"))
<< attr(QStringLiteral("key"), pair._key) << attr(QStringLiteral("key"), pair._key)
@@ -186,7 +176,7 @@ inline void save(Archive &archive, const impl::KeyValuePair<KEY, VALUE> &pair)
} }
template<class Archive, class KEY, class VALUE> template<class Archive, class KEY, class VALUE>
inline void load(Archive &archive, impl::KeyValuePair<KEY, VALUE> &pair) inline void load(Archive &archive, impl::KeyValuePair<KEY, VALUE> &pair, const Parameters &)
{ {
archive >> tag(QStringLiteral("pair")) archive >> tag(QStringLiteral("pair"))
>> attr(QStringLiteral("key"), pair._key) >> attr(QStringLiteral("key"), pair._key)
@@ -195,7 +185,7 @@ inline void load(Archive &archive, impl::KeyValuePair<KEY, VALUE> &pair)
} }
template<class Archive, class KEY, class VALUE> template<class Archive, class KEY, class VALUE>
inline void save(Archive &archive, const QHash<KEY, VALUE> &hash) inline void save(Archive &archive, const QHash<KEY, VALUE> &hash, const Parameters &)
{ {
archive << tag(QStringLiteral("qhash")); archive << tag(QStringLiteral("qhash"));
for (typename QHash<KEY, VALUE>::const_iterator it = hash.begin(); it != hash.end(); ++it) { for (typename QHash<KEY, VALUE>::const_iterator it = hash.begin(); it != hash.end(); ++it) {
@@ -216,7 +206,7 @@ inline void keyValuePairInsert(QHash<KEY, VALUE> &hash, const KeyValuePair<KEY,
} }
template<class Archive, class KEY, class VALUE> template<class Archive, class KEY, class VALUE>
inline void load(Archive &archive, QHash<KEY, VALUE> &hash) inline void load(Archive &archive, QHash<KEY, VALUE> &hash, const Parameters &)
{ {
archive >> tag(QStringLiteral("qhash")); archive >> tag(QStringLiteral("qhash"));
archive >> attr(QStringLiteral("item"), hash, &impl::keyValuePairInsert<KEY, VALUE>); archive >> attr(QStringLiteral("item"), hash, &impl::keyValuePairInsert<KEY, VALUE>);

View File

@@ -31,6 +31,8 @@
#ifndef QARK_SERIALIZE_ENUM_H #ifndef QARK_SERIALIZE_ENUM_H
#define QARK_SERIALIZE_ENUM_H #define QARK_SERIALIZE_ENUM_H
#include "parameters.h"
#include <type_traits> #include <type_traits>
namespace qark { namespace qark {
@@ -38,13 +40,13 @@ namespace qark {
#if 0 // ambigous with default implementation in access.h #if 0 // ambigous with default implementation in access.h
template<class Archive, typename T> template<class Archive, typename T>
inline typename std::enable_if<std::is_enum<T>::value, void>::type save(Archive &archive, const T &value) inline typename std::enable_if<std::is_enum<T>::value, void>::type save(Archive &archive, const T &value, const Parameters &)
{ {
archive.write((int) value); archive.write((int) value);
} }
template<class Archive, typename T> template<class Archive, typename T>
inline typename std::enable_if<std::is_enum<T>::value, void>::type load(Archive &archive, T &value) inline typename std::enable_if<std::is_enum<T>::value, void>::type load(Archive &archive, T &value, const Parameters &)
{ {
int i = 0; int i = 0;
archive.read(&i); archive.read(&i);
@@ -55,12 +57,12 @@ inline typename std::enable_if<std::is_enum<T>::value, void>::type load(Archive
#define QARK_SERIALIZE_ENUM(ENUM) \ #define QARK_SERIALIZE_ENUM(ENUM) \
template<class Archive> \ template<class Archive> \
inline void save(Archive &archive, const ENUM &e) \ inline void save(Archive &archive, const ENUM &e, const Parameters &) \
{ \ { \
archive.write((int) e); \ archive.write((int) e); \
} \ } \
template<class Archive> \ template<class Archive> \
inline void load(Archive &archive, ENUM &e) \ inline void load(Archive &archive, ENUM &e, const Parameters &) \
{ \ { \
int i = 0; \ int i = 0; \
archive.read(&i); \ archive.read(&i); \
@@ -68,13 +70,13 @@ inline typename std::enable_if<std::is_enum<T>::value, void>::type load(Archive
} }
template<class Archive, typename T> template<class Archive, typename T>
inline void save(Archive &archive, const QFlags<T> &flags) inline void save(Archive &archive, const QFlags<T> &flags, const Parameters &)
{ {
archive.write((typename QFlags<T>::Int) flags); archive.write((typename QFlags<T>::Int) flags);
} }
template<class Archive, typename T> template<class Archive, typename T>
inline void load(Archive &archive, QFlags<T> &flags) inline void load(Archive &archive, QFlags<T> &flags, const Parameters &)
{ {
typename QFlags<T>::Int i = 0; typename QFlags<T>::Int i = 0;
archive.read(&i); archive.read(&i);

View File

@@ -0,0 +1,98 @@
/***************************************************************************
**
** Copyright (C) 2015 Jochen Becher
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef QARK_SERIALIZE_POINTER_H
#define QARK_SERIALIZE_POINTER_H
#include "typeregistry.h"
namespace qark {
template<class Archive, class T>
inline void save(Archive &archive, T *p, const Parameters &)
{
if (p) {
if (archive.isReference(p)) {
archive.beginPointer();
archive.write(p);
archive.endPointer();
} else {
if (typeid(*p) == typeid(T)) {
archive.beginInstance();
registry::save_pointer<Archive, T, T>(archive, p);
archive.endInstance();
} else {
archive.beginInstance(get_type_uid(*p));
typename registry::TypeRegistry<Archive, T>::type_info type_data = get_type_info<Archive, T>(*p);
if (type_data.save_func == 0) {
throw unregistered_type();
} else {
type_data.save_func(archive, p);
}
archive.endInstance();
}
}
} else {
archive.beginNullPointer();
archive.endNullPointer();
}
}
template<class Archive, class T>
void load(Archive &archive, T *&p, const Parameters &)
{
typename Archive::ReferenceTag ref_tag = archive.readReferenceTag();
switch (ref_tag.kind) {
case Archive::NULLPOINTER:
p = 0;
break;
case Archive::POINTER:
archive.read(p);
break;
case Archive::INSTANCE:
if (ref_tag.type_name.isEmpty()) {
registry::load_non_virtual_pointer<Archive,T>(archive, p);
} else {
typename registry::TypeRegistry<Archive, T>::type_info type_data = get_type_info<Archive, T>(ref_tag.type_name);
if (type_data.load_func == 0) {
throw unregistered_type();
} else {
type_data.load_func(archive, p);
}
}
break;
}
archive.readReferenceEndTag(ref_tag.kind);
}
}
#endif // QARK_SERIALIZE_POINTER_H

View File

@@ -32,6 +32,7 @@
#define QARK_TAG_H #define QARK_TAG_H
#include "typeregistry.h" #include "typeregistry.h"
#include "parameters.h"
#include <QString> #include <QString>
@@ -45,10 +46,19 @@ public:
{ {
} }
Tag(const QString &qualified_name, const Parameters &parameters)
: _qualified_name(qualified_name),
_parameters(parameters)
{
}
const QString &getQualifiedName() const { return _qualified_name; } const QString &getQualifiedName() const { return _qualified_name; }
Parameters getParameters() const { return _parameters; }
private: private:
QString _qualified_name; QString _qualified_name;
Parameters _parameters;
}; };
@@ -57,12 +67,18 @@ class Object :
public Tag public Tag
{ {
public: public:
explicit Object(const QString &qualified_name, T *object) Object(const QString &qualified_name, T *object)
: Tag(qualified_name), : Tag(qualified_name),
_object(object) _object(object)
{ {
} }
Object(const QString &qualified_name, T *object, const Parameters &parameters)
: Tag(qualified_name, parameters),
_object(object)
{
}
T *getObject() const { return _object; } T *getObject() const { return _object; }
private: private:
@@ -75,28 +91,61 @@ inline Tag tag(const QString &qualified_name)
return Tag(qualified_name); return Tag(qualified_name);
} }
inline Tag tag(const QString &qualified_name, const Parameters &parameters)
{
return Tag(qualified_name, parameters);
}
inline Tag tag(const char *qualified_name) inline Tag tag(const char *qualified_name)
{ {
return Tag(QLatin1String(qualified_name)); return Tag(QLatin1String(qualified_name));
} }
inline Tag tag(const char *qualified_name, const Parameters &parameters)
{
return Tag(QLatin1String(qualified_name), parameters);
}
template<class T> template<class T>
inline Object<T> tag(T &object) inline Object<T> tag(T &object)
{ {
return Object<T>(get_type_uid<T>(), &object); return Object<T>(get_type_uid<T>(), &object);
} }
template<class T>
inline Object<T> tag(T &object, const Parameters &parameters)
{
return Object<T>(get_type_uid<T>(), &object, parameters);
}
template<class T> template<class T>
inline Object<T> tag(const QString &qualified_name, T &object) inline Object<T> tag(const QString &qualified_name, T &object)
{ {
return Object<T>(qualified_name, &object); return Object<T>(qualified_name, &object);
} }
template<class T>
inline Object<T> tag(const QString &qualified_name, T &object, const Parameters &parameters)
{
return Object<T>(qualified_name, &object, parameters);
}
class End { class End {
public: public:
explicit End() { } explicit End()
{
}
explicit End(const Parameters &parameters)
: _parameters(parameters)
{
}
Parameters getParameters() const { return _parameters; }
private:
Parameters _parameters;
}; };
inline End end() inline End end()
@@ -104,6 +153,10 @@ inline End end()
return End(); return End();
} }
inline End end(const Parameters &parameters)
{
return End(parameters);
}
} }

View File

@@ -31,6 +31,8 @@
#ifndef QARK_TYPEREGISTRY_H #ifndef QARK_TYPEREGISTRY_H
#define QARK_TYPEREGISTRY_H #define QARK_TYPEREGISTRY_H
#include "parameters.h"
#include "qmt/infrastructure/qmtassert.h" #include "qmt/infrastructure/qmtassert.h"
#include <exception> #include <exception>
@@ -219,7 +221,7 @@ template<class Archive, class BASE, class DERIVED>
Archive &save_pointer(Archive &ar, BASE * const &p) Archive &save_pointer(Archive &ar, BASE * const &p)
{ {
DERIVED &t = dynamic_cast<DERIVED &>(*p); DERIVED &t = dynamic_cast<DERIVED &>(*p);
ar << t; save(ar, t, Parameters());
return ar; return ar;
} }
@@ -227,7 +229,7 @@ template<class Archive, class BASE, class DERIVED>
Archive &load_pointer(Archive &ar, BASE *&p) Archive &load_pointer(Archive &ar, BASE *&p)
{ {
DERIVED *t = new DERIVED(); DERIVED *t = new DERIVED();
ar >> *t; load(ar, *t, Parameters());
p = t; p = t;
return ar; return ar;
} }
@@ -324,13 +326,13 @@ typename registry::TypeRegistry<Archive,T>::type_info get_type_info(const QStrin
#define QARK_REGISTER_DERIVED_CLASS(INARCHIVE, OUTARCHIVE, DERIVED, BASE) \ #define QARK_REGISTER_DERIVED_CLASS(INARCHIVE, OUTARCHIVE, DERIVED, BASE) \
template<> \ template<> \
int qark::registry::DerivedTypeRegistry<INARCHIVE,BASE,DERIVED>::__static_init = \ int qark::registry::DerivedTypeRegistry<INARCHIVE,BASE,DERIVED>::__static_init = \
qark::registry::DerivedTypeRegistry<INARCHIVE, BASE, DERIVED>::__init(0, qark::registry::load_pointer<INARCHIVE, BASE, DERIVED>); \ qark::registry::DerivedTypeRegistry<INARCHIVE, BASE, DERIVED>::__init(0, qark::registry::load_pointer<INARCHIVE, BASE, DERIVED>); \
template<> \ template<> \
int qark::registry::DerivedTypeRegistry<OUTARCHIVE, BASE, DERIVED>::__static_init = \ int qark::registry::DerivedTypeRegistry<OUTARCHIVE, BASE, DERIVED>::__static_init = \
qark::registry::DerivedTypeRegistry<OUTARCHIVE, BASE, DERIVED>::__init(qark::registry::save_pointer<OUTARCHIVE, BASE, DERIVED>, 0); \ qark::registry::DerivedTypeRegistry<OUTARCHIVE, BASE, DERIVED>::__init(qark::registry::save_pointer<OUTARCHIVE, BASE, DERIVED>, 0); \
template<> \ template<> \
int qark::registry::DerivedTypeRegistry<OUTARCHIVE, typename std::add_const<BASE>::type, typename std::add_const<DERIVED>::type>::__static_init = \ int qark::registry::DerivedTypeRegistry<OUTARCHIVE, typename std::add_const<BASE>::type, typename std::add_const<DERIVED>::type>::__static_init = \
qark::registry::DerivedTypeRegistry<OUTARCHIVE, typename std::add_const<BASE>::type, typename std::add_const<DERIVED>::type>:: \ qark::registry::DerivedTypeRegistry<OUTARCHIVE, typename std::add_const<BASE>::type, typename std::add_const<DERIVED>::type>:: \
__init(qark::registry::save_pointer<OUTARCHIVE, typename std::add_const<BASE>::type, typename std::add_const<DERIVED>::type>, 0); __init(qark::registry::save_pointer<OUTARCHIVE, typename std::add_const<BASE>::type, typename std::add_const<DERIVED>::type>, 0);
#endif // QARK_TYPEREGISTRY_H #endif // QARK_TYPEREGISTRY_H

View File

@@ -6,6 +6,7 @@ HEADERS += \
$$PWD/inc/qark/baseclass.h \ $$PWD/inc/qark/baseclass.h \
$$PWD/inc/qark/flag.h \ $$PWD/inc/qark/flag.h \
$$PWD/inc/qark/friend_access.h \ $$PWD/inc/qark/friend_access.h \
$$PWD/inc/qark/parameters.h \
$$PWD/inc/qark/qxmlinarchive.h \ $$PWD/inc/qark/qxmlinarchive.h \
$$PWD/inc/qark/qxmloutarchive.h \ $$PWD/inc/qark/qxmloutarchive.h \
$$PWD/inc/qark/reference.h \ $$PWD/inc/qark/reference.h \
@@ -13,6 +14,7 @@ HEADERS += \
$$PWD/inc/qark/serialize_basic.h \ $$PWD/inc/qark/serialize_basic.h \
$$PWD/inc/qark/serialize_container.h \ $$PWD/inc/qark/serialize_container.h \
$$PWD/inc/qark/serialize_enum.h \ $$PWD/inc/qark/serialize_enum.h \
$$PWD/inc/qark/serialize_pointer.h \
$$PWD/inc/qark/tag.h \ $$PWD/inc/qark/tag.h \
$$PWD/inc/qark/typeregistry.h \ $$PWD/inc/qark/typeregistry.h \
$$PWD/inc/qark/impl/loadingrefmap.h \ $$PWD/inc/qark/impl/loadingrefmap.h \

View File

@@ -312,6 +312,7 @@ QtcLibrary {
"inc/qark/impl/loadingrefmap.h", "inc/qark/impl/loadingrefmap.h",
"inc/qark/impl/objectid.h", "inc/qark/impl/objectid.h",
"inc/qark/impl/savingrefmap.h", "inc/qark/impl/savingrefmap.h",
"inc/qark/parameters.h",
"inc/qark/qxmlinarchive.h", "inc/qark/qxmlinarchive.h",
"inc/qark/qxmloutarchive.h", "inc/qark/qxmloutarchive.h",
"inc/qark/reference.h", "inc/qark/reference.h",
@@ -319,6 +320,7 @@ QtcLibrary {
"inc/qark/serialize_basic.h", "inc/qark/serialize_basic.h",
"inc/qark/serialize_container.h", "inc/qark/serialize_container.h",
"inc/qark/serialize_enum.h", "inc/qark/serialize_enum.h",
"inc/qark/serialize_pointer.h",
"inc/qark/tag.h", "inc/qark/tag.h",
"inc/qark/typeregistry.h", "inc/qark/typeregistry.h",
"src/flag.cpp", "src/flag.cpp",