blob: 1b214e9f74830c766b798b8099689a52386ee482 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** 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.
**
** 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.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QMETATYPE_H
#define QMETATYPE_H
#include <QtCore/qglobal.h>
#include <QtCore/qatomic.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qisenum.h>
#include <QtCore/qtypetraits.h>
#ifndef QT_NO_QOBJECT
#include <QtCore/qobjectdefs.h>
#endif
#include <new>
#include <vector>
#include <list>
#include <map>
#ifdef Bool
#error qmetatype.h must be included before any header file that defines Bool
#endif
QT_BEGIN_NAMESPACE
template <typename T>
struct QMetaTypeId2;
template <typename T>
inline Q_DECL_CONSTEXPR int qMetaTypeId();
// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
// ### Qt6: reorder the types to match the C++ integral type ranking
#define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
F(Void, 43, void) \
F(Bool, 1, bool) \
F(Int, 2, int) \
F(UInt, 3, uint) \
F(LongLong, 4, qlonglong) \
F(ULongLong, 5, qulonglong) \
F(Double, 6, double) \
F(Long, 32, long) \
F(Short, 33, short) \
F(Char, 34, char) \
F(ULong, 35, ulong) \
F(UShort, 36, ushort) \
F(UChar, 37, uchar) \
F(Float, 38, float) \
F(SChar, 40, signed char) \
#define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
F(VoidStar, 31, void*) \
#define QT_FOR_EACH_STATIC_CORE_CLASS(F)\
F(QChar, 7, QChar) \
F(QString, 10, QString) \
F(QStringList, 11, QStringList) \
F(QByteArray, 12, QByteArray) \
F(QBitArray, 13, QBitArray) \
F(QDate, 14, QDate) \
F(QTime, 15, QTime) \
F(QDateTime, 16, QDateTime) \
F(QUrl, 17, QUrl) \
F(QLocale, 18, QLocale) \
F(QRect, 19, QRect) \
F(QRectF, 20, QRectF) \
F(QSize, 21, QSize) \
F(QSizeF, 22, QSizeF) \
F(QLine, 23, QLine) \
F(QLineF, 24, QLineF) \
F(QPoint, 25, QPoint) \
F(QPointF, 26, QPointF) \
F(QRegExp, 27, QRegExp) \
F(QEasingCurve, 29, QEasingCurve) \
F(QUuid, 30, QUuid) \
F(QVariant, 41, QVariant) \
F(QModelIndex, 42, QModelIndex) \
F(QRegularExpression, 44, QRegularExpression) \
F(QJsonValue, 45, QJsonValue) \
F(QJsonObject, 46, QJsonObject) \
F(QJsonArray, 47, QJsonArray) \
F(QJsonDocument, 48, QJsonDocument) \
F(QPersistentModelIndex, 50, QPersistentModelIndex) \
#define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
F(QObjectStar, 39, QObject*)
#define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
F(QVariantMap, 8, QVariantMap) \
F(QVariantList, 9, QVariantList) \
F(QVariantHash, 28, QVariantHash) \
F(QByteArrayList, 49, QByteArrayList) \
#define QT_FOR_EACH_STATIC_GUI_CLASS(F)\
F(QFont, 64, QFont) \
F(QPixmap, 65, QPixmap) \
F(QBrush, 66, QBrush) \
F(QColor, 67, QColor) \
F(QPalette, 68, QPalette) \
F(QIcon, 69, QIcon) \
F(QImage, 70, QImage) \
F(QPolygon, 71, QPolygon) \
F(QRegion, 72, QRegion) \
F(QBitmap, 73, QBitmap) \
F(QCursor, 74, QCursor) \
F(QKeySequence, 75, QKeySequence) \
F(QPen, 76, QPen) \
F(QTextLength, 77, QTextLength) \
F(QTextFormat, 78, QTextFormat) \
F(QMatrix, 79, QMatrix) \
F(QTransform, 80, QTransform) \
F(QMatrix4x4, 81, QMatrix4x4) \
F(QVector2D, 82, QVector2D) \
F(QVector3D, 83, QVector3D) \
F(QVector4D, 84, QVector4D) \
F(QQuaternion, 85, QQuaternion) \
F(QPolygonF, 86, QPolygonF) \
#define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
F(QSizePolicy, 121, QSizePolicy) \
// ### FIXME kill that set
#define QT_FOR_EACH_STATIC_HACKS_TYPE(F)\
F(QMetaTypeId2<qreal>::MetaType, -1, qreal)
// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, AliasingType, "RealType")
#define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\
F(ULong, -1, ulong, "unsigned long") \
F(UInt, -1, uint, "unsigned int") \
F(UShort, -1, ushort, "unsigned short") \
F(UChar, -1, uchar, "unsigned char") \
F(LongLong, -1, qlonglong, "long long") \
F(ULongLong, -1, qulonglong, "unsigned long long") \
F(SChar, -1, signed char, "qint8") \
F(UChar, -1, uchar, "quint8") \
F(Short, -1, short, "qint16") \
F(UShort, -1, ushort, "quint16") \
F(Int, -1, int, "qint32") \
F(UInt, -1, uint, "quint32") \
F(LongLong, -1, qlonglong, "qint64") \
F(ULongLong, -1, qulonglong, "quint64") \
F(QVariantList, -1, QVariantList, "QList<QVariant>") \
F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \
F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \
F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \
#define QT_FOR_EACH_STATIC_TYPE(F)\
QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
QT_FOR_EACH_STATIC_CORE_CLASS(F)\
QT_FOR_EACH_STATIC_CORE_POINTER(F)\
QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
QT_FOR_EACH_STATIC_GUI_CLASS(F)\
QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
#define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \
TypeName = Id,
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
F(QList) \
F(QVector) \
F(QQueue) \
F(QStack) \
F(QSet) \
F(QLinkedList)
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
F(QHash, class) \
F(QMap, class) \
F(QPair, struct)
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
F(QSharedPointer) \
F(QWeakPointer) \
F(QPointer)
class QDataStream;
class QMetaTypeInterface;
struct QMetaObject;
namespace QtPrivate
{
/*!
This template is used for implicit conversion from type From to type To.
\internal
*/
template<typename From, typename To>
To convertImplicit(const From& from)
{
return from;
}
#ifndef QT_NO_DEBUG_STREAM
struct AbstractDebugStreamFunction
{
typedef void (*Stream)(const AbstractDebugStreamFunction *, QDebug&, const void *);
typedef void (*Destroy)(AbstractDebugStreamFunction *);
explicit AbstractDebugStreamFunction(Stream s = 0, Destroy d = 0)
: stream(s), destroy(d) {}
Q_DISABLE_COPY(AbstractDebugStreamFunction)
Stream stream;
Destroy destroy;
};
template<typename T>
struct BuiltInDebugStreamFunction : public AbstractDebugStreamFunction
{
BuiltInDebugStreamFunction()
: AbstractDebugStreamFunction(stream, destroy) {}
static void stream(const AbstractDebugStreamFunction *, QDebug& dbg, const void *r)
{
const T *rhs = static_cast<const T *>(r);
operator<<(dbg, *rhs);
}
static void destroy(AbstractDebugStreamFunction *_this)
{
delete static_cast<BuiltInDebugStreamFunction *>(_this);
}
};
#endif
struct AbstractComparatorFunction
{
typedef bool (*LessThan)(const AbstractComparatorFunction *, const void *, const void *);
typedef bool (*Equals)(const AbstractComparatorFunction *, const void *, const void *);
typedef void (*Destroy)(AbstractComparatorFunction *);
explicit AbstractComparatorFunction(LessThan lt = 0, Equals e = 0, Destroy d = 0)
: lessThan(lt), equals(e), destroy(d) {}
Q_DISABLE_COPY(AbstractComparatorFunction)
LessThan lessThan;
Equals equals;
Destroy destroy;
};
template<typename T>
struct BuiltInComparatorFunction : public AbstractComparatorFunction
{
BuiltInComparatorFunction()
: AbstractComparatorFunction(lessThan, equals, destroy) {}
static bool lessThan(const AbstractComparatorFunction *, const void *l, const void *r)
{
const T *lhs = static_cast<const T *>(l);
const T *rhs = static_cast<const T *>(r);
return *lhs < *rhs;
}
static bool equals(const AbstractComparatorFunction *, const void *l, const void *r)
{
const T *lhs = static_cast<const T *>(l);
const T *rhs = static_cast<const T *>(r);
return *lhs == *rhs;
}
static void destroy(AbstractComparatorFunction *_this)
{
delete static_cast<BuiltInComparatorFunction *>(_this);
}
};
template<typename T>
struct BuiltInEqualsComparatorFunction : public AbstractComparatorFunction
{
BuiltInEqualsComparatorFunction()
: AbstractComparatorFunction(0, equals, destroy) {}
static bool equals(const AbstractComparatorFunction *, const void *l, const void *r)
{
const T *lhs = static_cast<const T *>(l);
const T *rhs = static_cast<const T *>(r);
return *lhs == *rhs;
}
static void destroy(AbstractComparatorFunction *_this)
{
delete static_cast<BuiltInEqualsComparatorFunction *>(_this);
}
};
struct AbstractConverterFunction
{
typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*);
explicit AbstractConverterFunction(Converter c = 0)
: convert(c) {}
Q_DISABLE_COPY(AbstractConverterFunction)
Converter convert;
};
template<typename From, typename To>
struct ConverterMemberFunction : public AbstractConverterFunction
{
explicit ConverterMemberFunction(To(From::*function)() const)
: AbstractConverterFunction(convert),
m_function(function) {}
~ConverterMemberFunction();
static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
{
const From *f = static_cast<const From *>(in);
To *t = static_cast<To *>(out);
const ConverterMemberFunction *_typedThis =
static_cast<const ConverterMemberFunction *>(_this);
*t = (f->*_typedThis->m_function)();
return true;
}
To(From::* const m_function)() const;
};
template<typename From, typename To>
struct ConverterMemberFunctionOk : public AbstractConverterFunction
{
explicit ConverterMemberFunctionOk(To(From::*function)(bool *) const)
: AbstractConverterFunction(convert),
m_function(function) {}
~ConverterMemberFunctionOk();
static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
{
const From *f = static_cast<const From *>(in);
To *t = static_cast<To *>(out);
bool ok = false;
const ConverterMemberFunctionOk *_typedThis =
static_cast<const ConverterMemberFunctionOk *>(_this);
*t = (f->*_typedThis->m_function)(&ok);
if (!ok)
*t = To();
return ok;
}
To(From::* const m_function)(bool*) const;
};
template<typename From, typename To, typename UnaryFunction>
struct ConverterFunctor : public AbstractConverterFunction
{
explicit ConverterFunctor(UnaryFunction function)
: AbstractConverterFunction(convert),
m_function(function) {}
~ConverterFunctor();
static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
{
const From *f = static_cast<const From *>(in);
To *t = static_cast<To *>(out);
const ConverterFunctor *_typedThis =
static_cast<const ConverterFunctor *>(_this);
*t = _typedThis->m_function(*f);
return true;
}
UnaryFunction m_function;
};
template<typename T, bool>
struct ValueTypeIsMetaType;
template<typename T, bool>
struct AssociativeValueTypeIsMetaType;
template<typename T, bool>
struct IsMetaTypePair;
template<typename, typename>
struct MetaTypeSmartPointerHelper;
}
class Q_CORE_EXPORT QMetaType {
enum ExtensionFlag { NoExtensionFlags,
CreateEx = 0x1, DestroyEx = 0x2,
ConstructEx = 0x4, DestructEx = 0x8,
NameEx = 0x10, SizeEx = 0x20,
CtorEx = 0x40, DtorEx = 0x80,
FlagsEx = 0x100, MetaObjectEx = 0x200
};
public:
#ifndef Q_QDOC
// The code that actually gets compiled.
enum Type {
// these are merged with QVariant
QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
FirstCoreType = Bool,
LastCoreType = QPersistentModelIndex,
FirstGuiType = QFont,
LastGuiType = QPolygonF,
FirstWidgetsType = QSizePolicy,
LastWidgetsType = QSizePolicy,
HighestInternalId = LastWidgetsType,
QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
UnknownType = 0,
User = 1024
};
#else
// If we are using QDoc it fakes the Type enum looks like this.
enum Type {
UnknownType = 0, Bool = 1, Int = 2, UInt = 3, LongLong = 4, ULongLong = 5,
Double = 6, Long = 32, Short = 33, Char = 34, ULong = 35, UShort = 36,
UChar = 37, Float = 38,
VoidStar = 31,
QChar = 7, QString = 10, QStringList = 11, QByteArray = 12,
QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22,
QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QRegExp = 27,
QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42,
QPersistentModelIndex = 50, QRegularExpression = 44,
QJsonValue = 45, QJsonObject = 46, QJsonArray = 47, QJsonDocument = 48,
QByteArrayList = 49, QObjectStar = 39, SChar = 40,
Void = 43,
QVariantMap = 8, QVariantList = 9, QVariantHash = 28,
QFont = 64, QPixmap = 65, QBrush = 66, QColor = 67, QPalette = 68,
QIcon = 69, QImage = 70, QPolygon = 71, QRegion = 72, QBitmap = 73,
QCursor = 74, QKeySequence = 75, QPen = 76, QTextLength = 77, QTextFormat = 78,
QMatrix = 79, QTransform = 80, QMatrix4x4 = 81, QVector2D = 82,
QVector3D = 83, QVector4D = 84, QQuaternion = 85, QPolygonF = 86,
QSizePolicy = 121,
User = 1024
};
#endif
enum TypeFlag {
NeedsConstruction = 0x1,
NeedsDestruction = 0x2,
MovableType = 0x4,
PointerToQObject = 0x8,
IsEnumeration = 0x10,
SharedPointerToQObject = 0x20,
WeakPointerToQObject = 0x40,
TrackingPointerToQObject = 0x80,
WasDeclaredAsMetaType = 0x100,
IsGadget = 0x200
};
Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
typedef void (*Deleter)(void *);
typedef void *(*Creator)(const void *);
typedef void (*Destructor)(void *);
typedef void *(*Constructor)(void *, const void *);
typedef void (*SaveOperator)(QDataStream &, const void *);
typedef void (*LoadOperator)(QDataStream &, void *);
#ifndef QT_NO_DATASTREAM
static void registerStreamOperators(const char *typeName, SaveOperator saveOp,
LoadOperator loadOp);
static void registerStreamOperators(int type, SaveOperator saveOp,
LoadOperator loadOp);
#endif
static int registerType(const char *typeName, Deleter deleter,
Creator creator);
static int registerType(const char *typeName, Deleter deleter,
Creator creator,
Destructor destructor,
Constructor constructor,
int size,
QMetaType::TypeFlags flags,
const QMetaObject *metaObject);
static bool unregisterType(int type);
static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Deleter deleter,
Creator creator,
Destructor destructor,
Constructor constructor,
int size,
QMetaType::TypeFlags flags,
const QMetaObject *metaObject);
static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Destructor destructor,
Constructor constructor,
int size,
QMetaType::TypeFlags flags,
const QMetaObject *metaObject);
static int registerTypedef(const char *typeName, int aliasId);
static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId);
static int type(const char *typeName);
#ifndef Q_QDOC
static int type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName);
#else
static int type(const QByteArray &typeName);
#endif
static const char *typeName(int type);
static int sizeOf(int type);
static TypeFlags typeFlags(int type);
static const QMetaObject *metaObjectForType(int type);
static bool isRegistered(int type);
static void *create(int type, const void *copy = 0);
#if QT_DEPRECATED_SINCE(5, 0)
QT_DEPRECATED static void *construct(int type, const void *copy = 0)
{ return create(type, copy); }
#endif
static void destroy(int type, void *data);
static void *construct(int type, void *where, const void *copy);
static void destruct(int type, void *where);
#ifndef QT_NO_DATASTREAM
static bool save(QDataStream &stream, int type, const void *data);
static bool load(QDataStream &stream, int type, void *data);
#endif
explicit QMetaType(const int type);
inline ~QMetaType();
inline bool isValid() const;
inline bool isRegistered() const;
inline int sizeOf() const;
inline TypeFlags flags() const;
inline const QMetaObject *metaObject() const;
inline void *create(const void *copy = 0) const;
inline void destroy(void *data) const;
inline void *construct(void *where, const void *copy = 0) const;
inline void destruct(void *data) const;
public:
template<typename T>
static bool registerComparators()
{
Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
"QMetaType::registerComparators: The type must be a custom type.");
const int typeId = qMetaTypeId<T>();
static const QtPrivate::BuiltInComparatorFunction<T> f;
return registerComparatorFunction( &f, typeId);
}
template<typename T>
static bool registerEqualsComparator()
{
Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
"QMetaType::registerEqualsComparator: The type must be a custom type.");
const int typeId = qMetaTypeId<T>();
static const QtPrivate::BuiltInEqualsComparatorFunction<T> f;
return registerComparatorFunction( &f, typeId);
}
template<typename T>
static bool hasRegisteredComparators()
{
return hasRegisteredComparators(qMetaTypeId<T>());
}
static bool hasRegisteredComparators(int typeId);
#ifndef QT_NO_DEBUG_STREAM
template<typename T>
static bool registerDebugStreamOperator()
{
Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
"QMetaType::registerDebugStreamOperator: The type must be a custom type.");
const int typeId = qMetaTypeId<T>();
static const QtPrivate::BuiltInDebugStreamFunction<T> f;
return registerDebugStreamOperatorFunction(&f, typeId);
}
template<typename T>
static bool hasRegisteredDebugStreamOperator()
{
return hasRegisteredDebugStreamOperator(qMetaTypeId<T>());
}
static bool hasRegisteredDebugStreamOperator(int typeId);
#endif
// implicit conversion supported like double -> float
template<typename From, typename To>
static bool registerConverter()
{
return registerConverter<From, To>(QtPrivate::convertImplicit<From, To>);
}
#ifdef Q_QDOC
static bool registerConverter(MemberFunction function);
static bool registerConverter(MemberFunctionOk function);
static bool registerConverter(UnaryFunction function);
#else
// member function as in "QString QFont::toString() const"
template<typename From, typename To>
static bool registerConverter(To(From::*function)() const)
{
Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
"QMetaType::registerConverter: At least one of the types must be a custom type.");
const int fromTypeId = qMetaTypeId<From>();
const int toTypeId = qMetaTypeId<To>();
static const QtPrivate::ConverterMemberFunction<From, To> f(function);
return registerConverterFunction(&f, fromTypeId, toTypeId);
}
// member function as in "double QString::toDouble(bool *ok = 0) const"
template<typename From, typename To>
static bool registerConverter(To(From::*function)(bool*) const)
{
Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
"QMetaType::registerConverter: At least one of the types must be a custom type.");
const int fromTypeId = qMetaTypeId<From>();
const int toTypeId = qMetaTypeId<To>();
static const QtPrivate::ConverterMemberFunctionOk<From, To> f(function);
return registerConverterFunction(&f, fromTypeId, toTypeId);
}
// functor or function pointer
template<typename From, typename To, typename UnaryFunction>
static bool registerConverter(UnaryFunction function)
{
Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
"QMetaType::registerConverter: At least one of the types must be a custom type.");
const int fromTypeId = qMetaTypeId<From>();
const int toTypeId = qMetaTypeId<To>();
static const QtPrivate::ConverterFunctor<From, To, UnaryFunction> f(function);
return registerConverterFunction(&f, fromTypeId, toTypeId);
}
#endif
static bool convert(const void *from, int fromTypeId, void *to, int toTypeId);
static bool compare(const void *lhs, const void *rhs, int typeId, int* result);
static bool equals(const void *lhs, const void *rhs, int typeId, int* result);
static bool debugStream(QDebug& dbg, const void *rhs, int typeId);
template<typename From, typename To>
static bool hasRegisteredConverterFunction()
{
return hasRegisteredConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
}
static bool hasRegisteredConverterFunction(int fromTypeId, int toTypeId);
private:
static QMetaType typeInfo(const int type);
inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
Creator creator,
Deleter deleter,
SaveOperator saveOp,
LoadOperator loadOp,
Constructor constructor,
Destructor destructor,
uint sizeOf,
uint theTypeFlags,
int typeId,
const QMetaObject *metaObject);
QMetaType(const QMetaType &other);
QMetaType &operator =(const QMetaType &);
inline bool isExtended(const ExtensionFlag flag) const { return m_extensionFlags & flag; }
// Methods used for future binary compatible extensions
void ctor(const QMetaTypeInterface *info);
void dtor();
uint sizeExtended() const;
QMetaType::TypeFlags flagsExtended() const;
const QMetaObject *metaObjectExtended() const;
void *createExtended(const void *copy = 0) const;
void destroyExtended(void *data) const;
void *constructExtended(void *where, const void *copy = 0) const;
void destructExtended(void *data) const;
static bool registerComparatorFunction(const QtPrivate::AbstractComparatorFunction *f, int type);
#ifndef QT_NO_DEBUG_STREAM
static bool registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f, int type);
#endif
// ### Qt6: FIXME: Remove the special Q_CC_MSVC handling, it was introduced to maintain BC.
#if !defined(Q_NO_TEMPLATE_FRIENDS) && !defined(Q_CC_MSVC)
#ifndef Q_QDOC
template<typename, bool> friend struct QtPrivate::ValueTypeIsMetaType;
template<typename, typename> friend struct QtPrivate::ConverterMemberFunction;
template<typename, typename> friend struct QtPrivate::ConverterMemberFunctionOk;
template<typename, typename, typename> friend struct QtPrivate::ConverterFunctor;
template<typename, bool> friend struct QtPrivate::AssociativeValueTypeIsMetaType;
template<typename, bool> friend struct QtPrivate::IsMetaTypePair;
template<typename, typename> friend struct QtPrivate::MetaTypeSmartPointerHelper;
#endif
#else
public:
#endif
static bool registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to);
static void unregisterConverterFunction(int from, int to);
private:
Creator m_creator_unused;
Deleter m_deleter_unused;
SaveOperator m_saveOp;
LoadOperator m_loadOp;
Constructor m_constructor;
Destructor m_destructor;
void *m_extension; // space reserved for future use
uint m_size;
uint m_typeFlags;
uint m_extensionFlags;
int m_typeId;
const QMetaObject *m_metaObject;
};
#undef QT_DEFINE_METATYPE_ID
Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
namespace QtPrivate {
template<typename From, typename To>
ConverterMemberFunction<From, To>::~ConverterMemberFunction()
{
QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
}
template<typename From, typename To>
ConverterMemberFunctionOk<From, To>::~ConverterMemberFunctionOk()
{
QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
}
template<typename From, typename To, typename UnaryFunction>
ConverterFunctor<From, To, UnaryFunction>::~ConverterFunctor()
{
QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
}
}
namespace QtMetaTypePrivate {
template <typename T, bool Accepted = true>
struct QMetaTypeFunctionHelper {
static void Destruct(void *t)
{
Q_UNUSED(t) // Silence MSVC that warns for POD types.
static_cast<T*>(t)->~T();
}
static void *Construct(void *where, const void *t)
{
if (t)
return new (where) T(*static_cast<const T*>(t));
return new (where) T;
}
#ifndef QT_NO_DATASTREAM
static void Save(QDataStream &stream, const void *t)
{
stream << *static_cast<const T*>(t);
}
static void Load(QDataStream &stream, void *t)
{
stream >> *static_cast<T*>(t);
}
#endif // QT_NO_DATASTREAM
};
template <typename T>
struct QMetaTypeFunctionHelper<T, /* Accepted */ false> {
static void Destruct(void *) {}
static void *Construct(void *, const void *) { return 0; }
#ifndef QT_NO_DATASTREAM
static void Save(QDataStream &, const void *) {}
static void Load(QDataStream &, void *) {}
#endif // QT_NO_DATASTREAM
};
template <>
struct QMetaTypeFunctionHelper<void, /* Accepted */ true>
: public QMetaTypeFunctionHelper<void, /* Accepted */ false>
{};
struct VariantData
{
VariantData(const int metaTypeId_,
const void *data_,
const uint flags_)
: metaTypeId(metaTypeId_)
, data(data_)
, flags(flags_)
{
}
VariantData(const VariantData &other)
: metaTypeId(other.metaTypeId), data(other.data), flags(other.flags){}
const int metaTypeId;
const void *data;
const uint flags;
private:
// copy constructor allowed to be implicit to silence level 4 warning from MSVC
VariantData &operator=(const VariantData &) Q_DECL_EQ_DELETE;
};
template<typename const_iterator>
struct IteratorOwnerCommon
{
static void assign(void **ptr, const_iterator iterator)
{
*ptr = new const_iterator(iterator);
}
static void assign(void **ptr, void * const * src)
{
*ptr = new const_iterator(*static_cast<const_iterator*>(*src));
}
static void advance(void **iterator, int step)
{
const_iterator &it = *static_cast<const_iterator*>(*iterator);
std::advance(it, step);
}
static void destroy(void **ptr)
{
delete static_cast<const_iterator*>(*ptr);
}
static bool equal(void * const *it, void * const *other)
{
return *static_cast<const_iterator*>(*it) == *static_cast<const_iterator*>(*other);
}
};
template<typename const_iterator>
struct IteratorOwner : IteratorOwnerCommon<const_iterator>
{
static const void *getData(void * const *iterator)
{
return &**static_cast<const_iterator*>(*iterator);
}
static const void *getData(const_iterator it)
{
return &*it;
}
};
struct Q_CORE_EXPORT VectorBoolElements
{
static const bool true_element;
static const bool false_element;
};
template<>
struct IteratorOwner<std::vector<bool>::const_iterator> : IteratorOwnerCommon<std::vector<bool>::const_iterator>
{
public:
static const void *getData(void * const *iterator)
{
return **static_cast<std::vector<bool>::const_iterator*>(*iterator) ?
&VectorBoolElements::true_element : &VectorBoolElements::false_element;
}
static const void *getData(const std::vector<bool>::const_iterator& it)
{
return *it ? &VectorBoolElements::true_element : &VectorBoolElements::false_element;
}
};
template<typename value_type>
struct IteratorOwner<const value_type*>
{
private:
// We need to disable typed overloads of assign() and getData() if the value_type
// is void* to avoid overloads conflicts. We do it by injecting unaccessible Dummy
// type as part of the overload signature.
struct Dummy {};
typedef typename QtPrivate::if_<QtPrivate::is_same<value_type, void*>::value, Dummy, value_type>::type value_type_OR_Dummy;
public:
static void assign(void **ptr, const value_type_OR_Dummy *iterator )
{
*ptr = const_cast<value_type*>(iterator);
}
static void assign(void **ptr, void * const * src)
{
*ptr = static_cast<value_type*>(*src);
}
static void advance(void **iterator, int step)
{
value_type *it = static_cast<value_type*>(*iterator);
std::advance(it, step);
*iterator = it;
}
static void destroy(void **)
{
}
static const void *getData(void * const *iterator)
{
return *iterator;
}
static const void *getData(const value_type_OR_Dummy *it)
{
return it;
}
static bool equal(void * const *it, void * const *other)
{
return static_cast<value_type*>(*it) == static_cast<value_type*>(*other);
}
};
enum IteratorCapability
{
ForwardCapability = 1,
BiDirectionalCapability = 2,
RandomAccessCapability = 4
};
template<typename T, typename Category = typename std::iterator_traits<typename T::const_iterator>::iterator_category>
struct CapabilitiesImpl;
template<typename T>
struct CapabilitiesImpl<T, std::forward_iterator_tag>
{ enum { IteratorCapabilities = ForwardCapability }; };
template<typename T>
struct CapabilitiesImpl<T, std::bidirectional_iterator_tag>
{ enum { IteratorCapabilities = BiDirectionalCapability | ForwardCapability }; };
template<typename T>
struct CapabilitiesImpl<T, std::random_access_iterator_tag>
{ enum { IteratorCapabilities = RandomAccessCapability | BiDirectionalCapability | ForwardCapability }; };
template<typename T>
struct ContainerAPI : CapabilitiesImpl<T>
{
static int size(const T *t) { return int(std::distance(t->begin(), t->end())); }
};
template<typename T>
struct ContainerAPI<QList<T> > : CapabilitiesImpl<QList<T> >
{ static int size(const QList<T> *t) { return t->size(); } };
template<typename T>
struct ContainerAPI<QVector<T> > : CapabilitiesImpl<QVector<T> >
{ static int size(const QVector<T> *t) { return t->size(); } };
template<typename T>
struct ContainerAPI<std::vector<T> > : CapabilitiesImpl<std::vector<T> >
{ static int size(const std::vector<T> *t) { return int(t->size()); } };
template<typename T>
struct ContainerAPI<std::list<T> > : CapabilitiesImpl<std::list<T> >
{ static int size(const std::list<T> *t) { return int(t->size()); } };
class QSequentialIterableImpl
{
public:
const void * _iterable;
void *_iterator;
int _metaType_id;
uint _metaType_flags;
uint _iteratorCapabilities;
typedef int(*sizeFunc)(const void *p);
typedef const void * (*atFunc)(const void *p, int);
typedef void (*moveIteratorFunc)(const void *p, void **);
typedef void (*advanceFunc)(void **p, int);
typedef VariantData (*getFunc)( void * const *p, int metaTypeId, uint flags);
typedef void (*destroyIterFunc)(void **p);
typedef bool (*equalIterFunc)(void * const *p, void * const *other);
typedef void (*copyIterFunc)(void **, void * const *);
sizeFunc _size;
atFunc _at;
moveIteratorFunc _moveToBegin;
moveIteratorFunc _moveToEnd;
advanceFunc _advance;
getFunc _get;
destroyIterFunc _destroyIter;
equalIterFunc _equalIter;
copyIterFunc _copyIter;
template<class T>
static int sizeImpl(const void *p)
{ return ContainerAPI<T>::size(static_cast<const T*>(p)); }
template<class T>
static const void* atImpl(const void *p, int idx)
{
typename T::const_iterator i = static_cast<const T*>(p)->begin();
std::advance(i, idx);
return IteratorOwner<typename T::const_iterator>::getData(i);
}
template<class T>
static void moveToBeginImpl(const void *container, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); }
template<class T>
static void moveToEndImpl(const void *container, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
template<class T>
static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); }
public:
template<class T> QSequentialIterableImpl(const T*p)
: _iterable(p)
, _iterator(0)
, _metaType_id(qMetaTypeId<typename T::value_type>())
, _metaType_flags(QTypeInfo<typename T::value_type>::isPointer)
, _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities)
, _size(sizeImpl<T>)
, _at(atImpl<T>)
, _moveToBegin(moveToBeginImpl<T>)
, _moveToEnd(moveToEndImpl<T>)
, _advance(IteratorOwner<typename T::const_iterator>::advance)
, _get(getImpl<T>)
, _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
, _equalIter(IteratorOwner<typename T::const_iterator>::equal)
, _copyIter(IteratorOwner<typename T::const_iterator>::assign)
{
}
QSequentialIterableImpl()
: _iterable(0)
, _iterator(0)
, _metaType_id(QMetaType::UnknownType)
, _metaType_flags(0)
, _iteratorCapabilities(0)
, _size(0)
, _at(0)
, _moveToBegin(0)
, _moveToEnd(0)
, _advance(0)
, _get(0)
, _destroyIter(0)
, _equalIter(0)
, _copyIter(0)
{
}
inline void moveToBegin() { _moveToBegin(_iterable, &_iterator); }
inline void moveToEnd() { _moveToEnd(_iterable, &_iterator); }
inline bool equal(const QSequentialIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
inline QSequentialIterableImpl &advance(int i) {
Q_ASSERT(i > 0 || _iteratorCapabilities & BiDirectionalCapability);
_advance(&_iterator, i);
return *this;
}
inline VariantData getCurrent() const { return _get(&_iterator, _metaType_id, _metaType_flags); }
VariantData at(int idx) const
{ return VariantData(_metaType_id, _at(_iterable, idx), _metaType_flags); }
int size() const { Q_ASSERT(_iterable); return _size(_iterable); }
inline void destroyIter() { _destroyIter(&_iterator); }
void copy(const QSequentialIterableImpl &other)
{
*this = other;
_copyIter(&_iterator, &other._iterator);
}
};
template<typename From>
struct QSequentialIterableConvertFunctor
{
QSequentialIterableImpl operator()(const From &f) const
{
return QSequentialIterableImpl(&f);
}
};
}
namespace QtMetaTypePrivate {
template<typename T, bool = QtPrivate::is_same<typename T::const_iterator::value_type, typename T::mapped_type>::value>
struct AssociativeContainerAccessor
{
static const typename T::key_type& getKey(const typename T::const_iterator &it)
{
return it.key();
}
static const typename T::mapped_type& getValue(const typename T::const_iterator &it)
{
return it.value();
}
};
template<typename T, bool = QtPrivate::is_same<typename T::const_iterator::value_type, std::pair<const typename T::key_type, typename T::mapped_type> >::value>
struct StlStyleAssociativeContainerAccessor;
template<typename T>
struct StlStyleAssociativeContainerAccessor<T, true>
{
static const typename T::key_type& getKey(const typename T::const_iterator &it)
{
return it->first;
}
static const typename T::mapped_type& getValue(const typename T::const_iterator &it)
{
return it->second;
}
};
template<typename T>
struct AssociativeContainerAccessor<T, false> : public StlStyleAssociativeContainerAccessor<T>
{
};
class QAssociativeIterableImpl
{
public:
const void *_iterable;
void *_iterator;
int _metaType_id_key;
uint _metaType_flags_key;
int _metaType_id_value;
uint _metaType_flags_value;
typedef int(*sizeFunc)(const void *p);
typedef void (*findFunc)(const void *container, const void *p, void **iterator);
typedef void (*beginFunc)(const void *p, void **);
typedef void (*advanceFunc)(void **p, int);
typedef VariantData (*getFunc)(void * const *p, int metaTypeId, uint flags);
typedef void (*destroyIterFunc)(void **p);
typedef bool (*equalIterFunc)(void * const *p, void * const *other);
typedef void (*copyIterFunc)(void **, void * const *);
sizeFunc _size;
findFunc _find;
beginFunc _begin;
beginFunc _end;
advanceFunc _advance;
getFunc _getKey;
getFunc _getValue;
destroyIterFunc _destroyIter;
equalIterFunc _equalIter;
copyIterFunc _copyIter;
template<class T>
static int sizeImpl(const void *p)
{ return int(std::distance(static_cast<const T*>(p)->begin(),
static_cast<const T*>(p)->end())); }
template<class T>
static void findImpl(const void *container, const void *p, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator,
static_cast<const T*>(container)->find(*static_cast<const typename T::key_type*>(p))); }
template<class T>
static void advanceImpl(void **p, int step)
{ std::advance(*static_cast<typename T::const_iterator*>(*p), step); }
template<class T>
static void beginImpl(const void *container, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); }
template<class T>
static void endImpl(const void *container, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
template<class T>
static VariantData getKeyImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getKey(*static_cast<typename T::const_iterator*>(*iterator)), flags); }
template<class T>
static VariantData getValueImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getValue(*static_cast<typename T::const_iterator*>(*iterator)), flags); }
public:
template<class T> QAssociativeIterableImpl(const T*p)
: _iterable(p)
, _metaType_id_key(qMetaTypeId<typename T::key_type>())
, _metaType_flags_key(QTypeInfo<typename T::key_type>::isPointer)
, _metaType_id_value(qMetaTypeId<typename T::mapped_type>())
, _metaType_flags_value(QTypeInfo<typename T::mapped_type>::isPointer)
, _size(sizeImpl<T>)
, _find(findImpl<T>)
, _begin(beginImpl<T>)
, _end(endImpl<T>)
, _advance(advanceImpl<T>)
, _getKey(getKeyImpl<T>)
, _getValue(getValueImpl<T>)
, _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
, _equalIter(IteratorOwner<typename T::const_iterator>::equal)
, _copyIter(IteratorOwner<typename T::const_iterator>::assign)
{
}
QAssociativeIterableImpl()
: _iterable(0)
, _metaType_id_key(QMetaType::UnknownType)
, _metaType_flags_key(0)
, _metaType_id_value(QMetaType::UnknownType)
, _metaType_flags_value(0)
, _size(0)
, _find(0)
, _begin(0)
, _end(0)
, _advance(0)
, _getKey(0)
, _getValue(0)
, _destroyIter(0)
, _equalIter(0)
, _copyIter(0)
{
}
inline void begin() { _begin(_iterable, &_iterator); }
inline void end() { _end(_iterable, &_iterator); }
inline bool equal(const QAssociativeIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
inline QAssociativeIterableImpl &advance(int i) { _advance(&_iterator, i); return *this; }
inline void destroyIter() { _destroyIter(&_iterator); }
inline VariantData getCurrentKey() const { return _getKey(&_iterator, _metaType_id_key, _metaType_flags_value); }
inline VariantData getCurrentValue() const { return _getValue(&_iterator, _metaType_id_value, _metaType_flags_value); }
inline void find(const VariantData &key)
{ _find(_iterable, key.data, &_iterator); }
int size() const { Q_ASSERT(_iterable); return _size(_iterable); }
void copy(const QAssociativeIterableImpl &other)
{
*this = other;
_copyIter(&_iterator, &other._iterator);
}
};
template<typename From>
struct QAssociativeIterableConvertFunctor
{
QAssociativeIterableImpl operator()(const From& f) const
{
return QAssociativeIterableImpl(&f);
}
};
class QPairVariantInterfaceImpl
{
const void *_pair;
int _metaType_id_first;
uint _metaType_flags_first;
int _metaType_id_second;
uint _metaType_flags_second;
typedef VariantData (*getFunc)(const void * const *p, int metaTypeId, uint flags);
getFunc _getFirst;
getFunc _getSecond;
template<class T>
static VariantData getFirstImpl(const void * const *pair, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, &static_cast<const T*>(*pair)->first, flags); }
template<class T>
static VariantData getSecondImpl(const void * const *pair, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, &static_cast<const T*>(*pair)->second, flags); }
public:
template<class T> QPairVariantInterfaceImpl(const T*p)
: _pair(p)
, _metaType_id_first(qMetaTypeId<typename T::first_type>())
, _metaType_flags_first(QTypeInfo<typename T::first_type>::isPointer)
, _metaType_id_second(qMetaTypeId<typename T::second_type>())
, _metaType_flags_second(QTypeInfo<typename T::second_type>::isPointer)
, _getFirst(getFirstImpl<T>)
, _getSecond(getSecondImpl<T>)
{
}
QPairVariantInterfaceImpl()
: _pair(0)
, _getFirst(0)
, _getSecond(0)
{
}
inline VariantData first() const { return _getFirst(&_pair, _metaType_id_first, _metaType_flags_first); }
inline VariantData second() const { return _getSecond(&_pair, _metaType_id_second, _metaType_flags_second); }
};
template<typename From>
struct QPairVariantInterfaceConvertFunctor;
template<typename T, typename U>
struct QPairVariantInterfaceConvertFunctor<QPair<T, U> >
{
QPairVariantInterfaceImpl operator()(const QPair<T, U>& f) const
{
return QPairVariantInterfaceImpl(&f);
}
};
template<typename T, typename U>
struct QPairVariantInterfaceConvertFunctor<std::pair<T, U> >
{
QPairVariantInterfaceImpl operator()(const std::pair<T, U>& f) const
{
return QPairVariantInterfaceImpl(&f);
}
};
}
class QObject;
class QWidget;
#define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name) \
template <class T> class Name; \
QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER)
namespace QtPrivate
{
template<typename T>
struct IsPointerToTypeDerivedFromQObject
{
enum { Value = false };
};
// Specialize to avoid sizeof(void) warning
template<>
struct IsPointerToTypeDerivedFromQObject<void*>
{
enum { Value = false };
};
template<>
struct IsPointerToTypeDerivedFromQObject<const void*>
{
enum { Value = false };
};
template<>
struct IsPointerToTypeDerivedFromQObject<QObject*>
{
enum { Value = true };
};
template<typename T>
struct IsPointerToTypeDerivedFromQObject<T*>
{
typedef qint8 yes_type;
typedef qint64 no_type;
#ifndef QT_NO_QOBJECT
static yes_type checkType(QObject* );
#endif
static no_type checkType(...);
Q_STATIC_ASSERT_X(sizeof(T), "Type argument of Q_DECLARE_METATYPE(T*) must be fully defined");
enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(yes_type) };
};
template<typename T, typename Enable = void>
struct IsGadgetHelper { enum { Value = false }; };
template<typename T>
struct IsGadgetHelper<T, typename T::QtGadgetHelper>
{
template <typename X>
static char checkType(void (X::*)());
static void *checkType(void (T::*)());
enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) };
};
QT_WARNING_PUSH
// In C++03 mode, clang consider local or unnamed type and throw a warning instead of ignoring them
QT_WARNING_DISABLE_CLANG("-Wunnamed-type-template-args")
QT_WARNING_DISABLE_CLANG("-Wlocal-type-template-args")
template<typename T> char qt_getEnumMetaObject(const T&);
template<typename T>
struct IsQEnumHelper {
static const T &declval();
// If the type was declared with Q_ENUM, the friend qt_getEnumMetaObject() declared in the
// Q_ENUM macro will be chosen by ADL, and the return type will be QMetaObject*.
// Otherwise the chosen overload will be the catch all template function
// qt_getEnumMetaObject(T) which returns 'char'
enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) };
};
template<> struct IsQEnumHelper<void> { enum { Value = false }; };
QT_WARNING_POP
template<typename T, typename Enable = void>
struct MetaObjectForType
{
static inline const QMetaObject *value() { return 0; }
};
template<>
struct MetaObjectForType<void>
{
static inline const QMetaObject *value() { return Q_NULLPTR; }
};
template<typename T>
struct MetaObjectForType<T*, typename QEnableIf<IsPointerToTypeDerivedFromQObject<T*>::Value>::Type>
{
static inline const QMetaObject *value() { return &T::staticMetaObject; }
};
template<typename T>
struct MetaObjectForType<T, typename QEnableIf<IsGadgetHelper<T>::Value>::Type>
{
static inline const QMetaObject *value() { return &T::staticMetaObject; }
};
template<typename T>
struct MetaObjectForType<T, typename QEnableIf<IsQEnumHelper<T>::Value>::Type >
{
static inline const QMetaObject *value() { return qt_getEnumMetaObject(T()); }
};
template<typename T>
struct IsSharedPointerToTypeDerivedFromQObject
{
enum { Value = false };
};
template<typename T>
struct IsSharedPointerToTypeDerivedFromQObject<QSharedPointer<T> > : IsPointerToTypeDerivedFromQObject<T*>
{
};
template<typename T>
struct IsWeakPointerToTypeDerivedFromQObject
{
enum { Value = false };
};
template<typename T>
struct IsWeakPointerToTypeDerivedFromQObject<QWeakPointer<T> > : IsPointerToTypeDerivedFromQObject<T*>
{
};
template<typename T>
struct IsTrackingPointerToTypeDerivedFromQObject
{
enum { Value = false };
};
template<typename T>
struct IsTrackingPointerToTypeDerivedFromQObject<QPointer<T> >
{
enum { Value = true };
};
template<typename T>
struct IsSequentialContainer
{
enum { Value = false };
};
template<typename T>
struct IsAssociativeContainer
{
enum { Value = false };
};
template<typename T, bool = QtPrivate::IsSequentialContainer<T>::Value>
struct SequentialContainerConverterHelper
{
static bool registerConverter(int)
{
return false;
}
};
template<typename T, bool = QMetaTypeId2<typename T::value_type>::Defined>
struct ValueTypeIsMetaType
{
static bool registerConverter(int)
{
return false;
}
};
template<typename T>
struct SequentialContainerConverterHelper<T, true> : ValueTypeIsMetaType<T>
{
};
template<typename T, bool = QtPrivate::IsAssociativeContainer<T>::Value>
struct AssociativeContainerConverterHelper
{
static bool registerConverter(int)
{
return false;
}
};
template<typename T, bool = QMetaTypeId2<typename T::mapped_type>::Defined>
struct AssociativeValueTypeIsMetaType
{
static bool registerConverter(int)
{
return false;
}
};
template<typename T, bool = QMetaTypeId2<typename T::key_type>::Defined>
struct KeyAndValueTypeIsMetaType
{
static bool registerConverter(int)
{
return false;
}
};
template<typename T>
struct KeyAndValueTypeIsMetaType<T, true> : AssociativeValueTypeIsMetaType<T>
{
};
template<typename T>
struct AssociativeContainerConverterHelper<T, true> : KeyAndValueTypeIsMetaType<T>
{
};
template<typename T, bool = QMetaTypeId2<typename T::first_type>::Defined
&& QMetaTypeId2<typename T::second_type>::Defined>
struct IsMetaTypePair
{
static bool registerConverter(int)
{
return false;
}
};
template<typename T>
struct IsMetaTypePair<T, true>
{
inline static bool registerConverter(int id);
};
template<typename T>
struct IsPair
{
static bool registerConverter(int)
{
return false;
}
};
template<typename T, typename U>
struct IsPair<QPair<T, U> > : IsMetaTypePair<QPair<T, U> > {};
template<typename T, typename U>
struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {};
template<typename T>
struct MetaTypePairHelper : IsPair<T> {};
template<typename T, typename = void>
struct MetaTypeSmartPointerHelper
{
static bool registerConverter(int) { return false; }
};
Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
} // namespace QtPrivate
template <typename T, int =
QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject :
QtPrivate::IsGadgetHelper<T>::Value ? QMetaType::IsGadget :
QtPrivate::IsQEnumHelper<T>::Value ? QMetaType::IsEnumeration : 0>
struct QMetaTypeIdQObject
{
enum {
Defined = 0
};
};
template <typename T>
struct QMetaTypeId : public QMetaTypeIdQObject<T>
{
};
template <typename T>
struct QMetaTypeId2
{
enum { Defined = QMetaTypeId<T>::Defined, IsBuiltIn=false };
static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
};
template <typename T>
struct QMetaTypeId2<const T&> : QMetaTypeId2<T> {};
template <typename T>
struct QMetaTypeId2<T&> { enum {Defined = false }; };
namespace QtPrivate {
template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
struct QMetaTypeIdHelper {
static inline Q_DECL_CONSTEXPR int qt_metatype_id()
{ return QMetaTypeId2<T>::qt_metatype_id(); }
};
template <typename T> struct QMetaTypeIdHelper<T, false> {
static inline Q_DECL_CONSTEXPR int qt_metatype_id()
{ return -1; }
};
#ifndef Q_COMPILER_VARIADIC_TEMPLATES
// Function pointers don't derive from QObject
template <class Result> struct IsPointerToTypeDerivedFromQObject<Result(*)()> { enum { Value = false }; };
template <class Result, class Arg0> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1, class Arg2> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1, Arg2)> { enum { Value = false }; };
#else
template <typename Result, typename... Args>
struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; };
#endif
template<typename T>
struct QMetaTypeTypeFlags
{
enum { Flags = (!QTypeInfo<T>::isStatic ? QMetaType::MovableType : 0)
| (QTypeInfo<T>::isComplex ? QMetaType::NeedsConstruction : 0)
| (QTypeInfo<T>::isComplex ? QMetaType::NeedsDestruction : 0)
| (IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : 0)
| (IsSharedPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::SharedPointerToQObject : 0)
| (IsWeakPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::WeakPointerToQObject : 0)
| (IsTrackingPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::TrackingPointerToQObject : 0)
| (Q_IS_ENUM(T) ? QMetaType::IsEnumeration : 0)
| (IsGadgetHelper<T>::Value ? QMetaType::IsGadget : 0)
};
};
template<typename T, bool defined>
struct MetaTypeDefinedHelper
{
enum DefinedType { Defined = defined };
};
template<typename SmartPointer>
struct QSmartPointerConvertFunctor
{
QObject* operator()(const SmartPointer &p) const
{
return p.operator->();
}
};
template<typename T>
struct QSmartPointerConvertFunctor<QWeakPointer<T> >
{
QObject* operator()(const QWeakPointer<T> &p) const
{
return p.data();
}
};
}
template <typename T>
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName
#ifndef Q_QDOC
, T * dummy = 0
, typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
#endif
)
{
#ifndef QT_NO_QOBJECT
Q_ASSERT_X(normalizedTypeName == QMetaObject::normalizedType(normalizedTypeName.constData()), "qRegisterNormalizedMetaType", "qRegisterNormalizedMetaType was called with a not normalized type name, please call qRegisterMetaType instead.");
#endif
const int typedefOf = dummy ? -1 : QtPrivate::QMetaTypeIdHelper<T>::qt_metatype_id();
if (typedefOf != -1)
return QMetaType::registerNormalizedTypedef(normalizedTypeName, typedefOf);
QMetaType::TypeFlags flags(QtPrivate::QMetaTypeTypeFlags<T>::Flags);
if (defined)
flags |= QMetaType::WasDeclaredAsMetaType;
const int id = QMetaType::registerNormalizedType(normalizedTypeName,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct,
int(sizeof(T)),
flags,
QtPrivate::MetaObjectForType<T>::value());
if (id > 0) {
QtPrivate::SequentialContainerConverterHelper<T>::registerConverter(id);
QtPrivate::AssociativeContainerConverterHelper<T>::registerConverter(id);
QtPrivate::MetaTypePairHelper<T>::registerConverter(id);
QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter(id);
}
return id;
}
template <typename T>
int qRegisterMetaType(const char *typeName
#ifndef Q_QDOC
, T * dummy = 0
, typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
#endif
)
{
#ifdef QT_NO_QOBJECT
QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = typeName;
#else
QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
#endif
return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy, defined);
}
#ifndef QT_NO_DATASTREAM
template <typename T>
void qRegisterMetaTypeStreamOperators(const char *typeName
#ifndef Q_QDOC
, T * /* dummy */ = 0
#endif
)
{
qRegisterMetaType<T>(typeName);
QMetaType::registerStreamOperators(typeName, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Save,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Load);
}
#endif // QT_NO_DATASTREAM
template <typename T>
inline Q_DECL_CONSTEXPR int qMetaTypeId()
{
Q_STATIC_ASSERT_X(QMetaTypeId2<T>::Defined, "Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system");
return QMetaTypeId2<T>::qt_metatype_id();
}
template <typename T>
inline Q_DECL_CONSTEXPR int qRegisterMetaType()
{
return qMetaTypeId<T>();
}
#if QT_DEPRECATED_SINCE(5, 1) && !defined(Q_QDOC)
// There used to be a T *dummy = 0 argument in Qt 4.0 to support MSVC6
template <typename T>
QT_DEPRECATED inline Q_DECL_CONSTEXPR int qMetaTypeId(T *)
{ return qMetaTypeId<T>(); }
#ifndef Q_CC_SUN
template <typename T>
QT_DEPRECATED inline Q_DECL_CONSTEXPR int qRegisterMetaType(T *)
{ return qRegisterMetaType<T>(); }
#endif
#endif
#ifndef QT_NO_QOBJECT
template <typename T>
struct QMetaTypeIdQObject<T*, QMetaType::PointerToQObject>
{
enum {
Defined = 1
};
static int qt_metatype_id()
{
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
if (const int id = metatype_id.loadAcquire())
return id;
const char * const cName = T::staticMetaObject.className();
QByteArray typeName;
typeName.reserve(int(strlen(cName)) + 1);
typeName.append(cName).append('*');
const int newId = qRegisterNormalizedMetaType<T*>(
typeName,
reinterpret_cast<T**>(quintptr(-1)));
metatype_id.storeRelease(newId);
return newId;
}
};
template <typename T>
struct QMetaTypeIdQObject<T, QMetaType::IsGadget>
{
enum {
Defined = QtPrivate::is_default_constructible<T>::value
};
static int qt_metatype_id()
{
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
if (const int id = metatype_id.loadAcquire())
return id;
const char * const cName = T::staticMetaObject.className();
const int newId = qRegisterNormalizedMetaType<T>(
cName,
reinterpret_cast<T*>(quintptr(-1)));
metatype_id.storeRelease(newId);
return newId;
}
};
template <typename T>
struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration>
{
enum {
Defined = 1
};
static int qt_metatype_id()
{
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
if (const int id = metatype_id.loadAcquire())
return id;
const char *eName = qt_getEnumName(T());
const char *cName = qt_getEnumMetaObject(T())->className();
QByteArray typeName;
typeName.reserve(int(strlen(cName) + 2 + strlen(eName)));
typeName.append(cName).append("::").append(eName);
const int newId = qRegisterNormalizedMetaType<T>(
typeName,
reinterpret_cast<T*>(quintptr(-1)));
metatype_id.storeRelease(newId);
return newId;
}
};
#endif
#ifndef QT_NO_DATASTREAM
template <typename T>
inline int qRegisterMetaTypeStreamOperators()
{
int id = qMetaTypeId<T>();
QMetaType::registerStreamOperators(id, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Save,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Load);
return id;
}
#endif
#define Q_DECLARE_OPAQUE_POINTER(POINTER) \
QT_BEGIN_NAMESPACE namespace QtPrivate { \
template <> \
struct IsPointerToTypeDerivedFromQObject<POINTER > \
{ \
enum { Value = false }; \
}; \
} QT_END_NAMESPACE \
/**/
#define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
#define Q_DECLARE_METATYPE_IMPL(TYPE) \
QT_BEGIN_NAMESPACE \
template <> \
struct QMetaTypeId< TYPE > \
{ \
enum { Defined = 1 }; \
static int qt_metatype_id() \
{ \
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
if (const int id = metatype_id.loadAcquire()) \
return id; \
const int newId = qRegisterMetaType< TYPE >(#TYPE, \
reinterpret_cast< TYPE *>(quintptr(-1))); \
metatype_id.storeRelease(newId); \
return newId; \
} \
}; \
QT_END_NAMESPACE
#define Q_DECLARE_BUILTIN_METATYPE(TYPE, METATYPEID, NAME) \
QT_BEGIN_NAMESPACE \
template<> struct QMetaTypeId2<NAME> \
{ \
enum { Defined = 1, IsBuiltIn = true, MetaType = METATYPEID }; \
static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return METATYPEID; } \
}; \
QT_END_NAMESPACE
#define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \
class Name;
QT_FOR_EACH_STATIC_CORE_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
QT_FOR_EACH_STATIC_GUI_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
#undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER
typedef QList<QVariant> QVariantList;
typedef QMap<QString, QVariant> QVariantMap;
typedef QHash<QString, QVariant> QVariantHash;
typedef QList<QByteArray> QByteArrayList;
#define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
QT_BEGIN_NAMESPACE \
template <typename T> \
struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
{ \
enum { \
Defined = QMetaTypeId2<T>::Defined \
}; \
static int qt_metatype_id() \
{ \
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
if (const int id = metatype_id.load()) \
return id; \
const char *tName = QMetaType::typeName(qMetaTypeId<T>()); \
Q_ASSERT(tName); \
const int tNameLen = int(qstrlen(tName)); \
QByteArray typeName; \
typeName.reserve(int(sizeof(#SINGLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + 1); \
typeName.append(#SINGLE_ARG_TEMPLATE, int(sizeof(#SINGLE_ARG_TEMPLATE)) - 1) \
.append('<').append(tName, tNameLen); \
if (typeName.endsWith('>')) \
typeName.append(' '); \
typeName.append('>'); \
const int newId = qRegisterNormalizedMetaType< SINGLE_ARG_TEMPLATE<T> >( \
typeName, \
reinterpret_cast< SINGLE_ARG_TEMPLATE<T> *>(quintptr(-1))); \
metatype_id.storeRelease(newId); \
return newId; \
} \
}; \
namespace QtPrivate { \
template<typename T> \
struct IsSequentialContainer<SINGLE_ARG_TEMPLATE<T> > \
{ \
enum { Value = true }; \
}; \
} \
QT_END_NAMESPACE
#define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
QT_BEGIN_NAMESPACE \
template<typename T, typename U> \
struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
{ \
enum { \
Defined = QMetaTypeId2<T>::Defined && QMetaTypeId2<U>::Defined \
}; \
static int qt_metatype_id() \
{ \
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
if (const int id = metatype_id.loadAcquire()) \
return id; \
const char *tName = QMetaType::typeName(qMetaTypeId<T>()); \
const char *uName = QMetaType::typeName(qMetaTypeId<U>()); \
Q_ASSERT(tName); \
Q_ASSERT(uName); \
const int tNameLen = int(qstrlen(tName)); \
const int uNameLen = int(qstrlen(uName)); \
QByteArray typeName; \
typeName.reserve(int(sizeof(#DOUBLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \
typeName.append(#DOUBLE_ARG_TEMPLATE, int(sizeof(#DOUBLE_ARG_TEMPLATE)) - 1) \
.append('<').append(tName, tNameLen).append(',').append(uName, uNameLen); \
if (typeName.endsWith('>')) \
typeName.append(' '); \
typeName.append('>'); \
const int newId = qRegisterNormalizedMetaType< DOUBLE_ARG_TEMPLATE<T, U> >(\
typeName, \
reinterpret_cast< DOUBLE_ARG_TEMPLATE<T, U> *>(quintptr(-1))); \
metatype_id.storeRelease(newId); \
return newId; \
} \
}; \
QT_END_NAMESPACE
namespace QtPrivate {
template<typename T, bool /* isSharedPointerToQObjectDerived */ = false>
struct SharedPointerMetaTypeIdHelper
{
enum {
Defined = 0
};
static int qt_metatype_id()
{
return -1;
}
};
}
#define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \
QT_BEGIN_NAMESPACE \
namespace QtPrivate { \
template<typename T> \
struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
{ \
enum { \
Defined = 1 \
}; \
static int qt_metatype_id() \
{ \
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
if (const int id = metatype_id.loadAcquire()) \
return id; \
const char * const cName = T::staticMetaObject.className(); \
QByteArray typeName; \
typeName.reserve(int(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1)); \
typeName.append(#SMART_POINTER, int(sizeof(#SMART_POINTER)) - 1) \
.append('<').append(cName).append('>'); \
const int newId = qRegisterNormalizedMetaType< SMART_POINTER<T> >( \
typeName, \
reinterpret_cast< SMART_POINTER<T> *>(quintptr(-1))); \
metatype_id.storeRelease(newId); \
return newId; \
} \
}; \
template<typename T> \
struct MetaTypeSmartPointerHelper<SMART_POINTER<T> , \
typename QEnableIf<IsPointerToTypeDerivedFromQObject<T*>::Value >::Type> \
{ \
static bool registerConverter(int id) \
{ \
const int toId = QMetaType::QObjectStar; \
if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { \
QtPrivate::QSmartPointerConvertFunctor<SMART_POINTER<T> > o; \
static const QtPrivate::ConverterFunctor<SMART_POINTER<T>, \
QObject*, \
QSmartPointerConvertFunctor<SMART_POINTER<T> > > f(o); \
return QMetaType::registerConverterFunction(&f, id, toId); \
} \
return true; \
} \
}; \
} \
template <typename T> \
struct QMetaTypeId< SMART_POINTER<T> > \
: QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \
QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
{ \
};\
QT_END_NAMESPACE
#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME) \
QT_BEGIN_NAMESPACE \
template <class T> class TEMPLATENAME; \
QT_END_NAMESPACE \
Q_DECLARE_METATYPE_TEMPLATE_1ARG(TEMPLATENAME)
QT_END_NAMESPACE
QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER)
#undef Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER
#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE Q_DECLARE_METATYPE_TEMPLATE_1ARG
Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::vector)
Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::list)
#define Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \
QT_BEGIN_NAMESPACE \
template <class T1, class T2> CPPTYPE TEMPLATENAME; \
QT_END_NAMESPACE \
QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER)
#undef Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER
#define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME) \
QT_BEGIN_NAMESPACE \
namespace QtPrivate { \
template<typename T, typename U> \
struct IsAssociativeContainer<TEMPLATENAME<T, U> > \
{ \
enum { Value = true }; \
}; \
} \
QT_END_NAMESPACE \
Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QHash)
Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMap)
Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::map)
Q_DECLARE_METATYPE_TEMPLATE_2ARG(QPair)
Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair)
#define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER)
QT_BEGIN_NAMESPACE
#undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
Creator creator,
Deleter deleter,
SaveOperator saveOp,
LoadOperator loadOp,
Constructor constructor,
Destructor destructor,
uint size,
uint theTypeFlags,
int typeId,
const QMetaObject *_metaObject)
: m_creator_unused(creator)
, m_deleter_unused(deleter)
, m_saveOp(saveOp)
, m_loadOp(loadOp)
, m_constructor(constructor)
, m_destructor(destructor)
, m_extension(0)
, m_size(size)
, m_typeFlags(theTypeFlags)
, m_extensionFlags(extensionFlags)
, m_typeId(typeId)
, m_metaObject(_metaObject)
{
if (Q_UNLIKELY(isExtended(CtorEx) || typeId == QMetaType::Void))
ctor(info);
}
inline QMetaType::~QMetaType()
{
if (Q_UNLIKELY(isExtended(DtorEx)))
dtor();
}
inline bool QMetaType::isValid() const
{
return m_typeId != UnknownType;
}
inline bool QMetaType::isRegistered() const
{
return isValid();
}
inline void *QMetaType::create(const void *copy) const
{
// ### TODO Qt6 remove the extension
return createExtended(copy);
}
inline void QMetaType::destroy(void *data) const
{
// ### TODO Qt6 remove the extension
destroyExtended(data);
}
inline void *QMetaType::construct(void *where, const void *copy) const
{
if (Q_UNLIKELY(isExtended(ConstructEx)))
return constructExtended(where, copy);
return m_constructor(where, copy);
}
inline void QMetaType::destruct(void *data) const
{
if (Q_UNLIKELY(isExtended(DestructEx)))
return destructExtended(data);
if (Q_UNLIKELY(!data))
return;
m_destructor(data);
}
inline int QMetaType::sizeOf() const
{
if (Q_UNLIKELY(isExtended(SizeEx)))
return sizeExtended();
return m_size;
}
inline QMetaType::TypeFlags QMetaType::flags() const
{
if (Q_UNLIKELY(isExtended(FlagsEx)))
return flagsExtended();
return QMetaType::TypeFlags(m_typeFlags);
}
inline const QMetaObject *QMetaType::metaObject() const
{
if (Q_UNLIKELY(isExtended(MetaObjectEx)))
return metaObjectExtended();
return m_metaObject;
}
QT_END_NAMESPACE
QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
Q_DECLARE_METATYPE(QtMetaTypePrivate::QSequentialIterableImpl)
Q_DECLARE_METATYPE(QtMetaTypePrivate::QAssociativeIterableImpl)
Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl)
QT_BEGIN_NAMESPACE
template <typename T>
inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter(int id)
{
const int toId = qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
static const QtPrivate::ConverterFunctor<T,
QtMetaTypePrivate::QPairVariantInterfaceImpl,
QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> > f(o);
return QMetaType::registerConverterFunction(&f, id, toId);
}
return true;
}
namespace QtPrivate {
template<typename T>
struct ValueTypeIsMetaType<T, true>
{
static bool registerConverter(int id)
{
const int toId = qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>();
if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> o;
static const QtPrivate::ConverterFunctor<T,
QtMetaTypePrivate::QSequentialIterableImpl,
QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> > f(o);
return QMetaType::registerConverterFunction(&f, id, toId);
}
return true;
}
};
template<typename T>
struct AssociativeValueTypeIsMetaType<T, true>
{
static bool registerConverter(int id)
{
const int toId = qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>();
if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> o;
static const QtPrivate::ConverterFunctor<T,
QtMetaTypePrivate::QAssociativeIterableImpl,
QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> > f(o);
return QMetaType::registerConverterFunction(&f, id, toId);
}
return true;
}
};
}
namespace QtMetaTypePrivate {
inline Q_DECL_CONSTEXPR bool isBuiltinSequentialType(int typeId)
{
return typeId == qMetaTypeId<QStringList>()
|| typeId == qMetaTypeId<QByteArrayList>()
|| typeId == qMetaTypeId<QVariantList>();
}
inline Q_DECL_CONSTEXPR bool isBuiltinAssociativeType(int typeId)
{
return typeId == qMetaTypeId<QVariantHash>()
|| typeId == qMetaTypeId<QVariantMap>();
}
} // QtMetaTypePrivate
QT_END_NAMESPACE
#endif // QMETATYPE_H