Coverage Report

Created: 2024-02-11 06:14

/src/qtbase/src/corelib/kernel/qmetatype.h
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
**
3
** Copyright (C) 2016 The Qt Company Ltd.
4
** Copyright (C) 2018 Intel Corporation.
5
** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
6
** Contact: https://www.qt.io/licensing/
7
**
8
** This file is part of the QtCore module of the Qt Toolkit.
9
**
10
** $QT_BEGIN_LICENSE:LGPL$
11
** Commercial License Usage
12
** Licensees holding valid commercial Qt licenses may use this file in
13
** accordance with the commercial license agreement provided with the
14
** Software or, alternatively, in accordance with the terms contained in
15
** a written agreement between you and The Qt Company. For licensing terms
16
** and conditions see https://www.qt.io/terms-conditions. For further
17
** information use the contact form at https://www.qt.io/contact-us.
18
**
19
** GNU Lesser General Public License Usage
20
** Alternatively, this file may be used under the terms of the GNU Lesser
21
** General Public License version 3 as published by the Free Software
22
** Foundation and appearing in the file LICENSE.LGPL3 included in the
23
** packaging of this file. Please review the following information to
24
** ensure the GNU Lesser General Public License version 3 requirements
25
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26
**
27
** GNU General Public License Usage
28
** Alternatively, this file may be used under the terms of the GNU
29
** General Public License version 2.0 or (at your option) the GNU General
30
** Public license version 3 or any later version approved by the KDE Free
31
** Qt Foundation. The licenses are as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33
** included in the packaging of this file. Please review the following
34
** information to ensure the GNU General Public License requirements will
35
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36
** https://www.gnu.org/licenses/gpl-3.0.html.
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#ifndef QMETATYPE_H
43
#define QMETATYPE_H
44
45
#include <QtCore/qglobal.h>
46
#include <QtCore/qatomic.h>
47
#include <QtCore/qbytearray.h>
48
#include <QtCore/qvarlengtharray.h>
49
#ifndef QT_NO_QOBJECT
50
#include <QtCore/qobjectdefs.h>
51
#endif
52
#include <new>
53
54
#include <vector>
55
#include <list>
56
#include <map>
57
58
#ifdef Bool
59
#error qmetatype.h must be included before any header file that defines Bool
60
#endif
61
62
QT_BEGIN_NAMESPACE
63
64
// from qcborcommon.h
65
enum class QCborSimpleType : quint8;
66
67
template <typename T>
68
struct QMetaTypeId2;
69
70
template <typename T>
71
inline Q_DECL_CONSTEXPR int qMetaTypeId();
72
73
// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
74
// ### Qt6: reorder the types to match the C++ integral type ranking
75
#define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
76
0
    F(Void, 43, void) \
77
0
    F(Bool, 1, bool) \
78
0
    F(Int, 2, int) \
79
0
    F(UInt, 3, uint) \
80
0
    F(LongLong, 4, qlonglong) \
81
0
    F(ULongLong, 5, qulonglong) \
82
0
    F(Double, 6, double) \
83
0
    F(Long, 32, long) \
84
0
    F(Short, 33, short) \
85
0
    F(Char, 34, char) \
86
0
    F(ULong, 35, ulong) \
87
0
    F(UShort, 36, ushort) \
88
0
    F(UChar, 37, uchar) \
89
0
    F(Float, 38, float) \
90
0
    F(SChar, 40, signed char) \
91
0
    F(Nullptr, 51, std::nullptr_t) \
92
0
    F(QCborSimpleType, 52, QCborSimpleType) \
93
94
#define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
95
0
    F(VoidStar, 31, void*) \
96
97
#if QT_CONFIG(easingcurve)
98
#define QT_FOR_EACH_STATIC_EASINGCURVE(F)\
99
0
    F(QEasingCurve, 29, QEasingCurve)
100
#else
101
#define QT_FOR_EACH_STATIC_EASINGCURVE(F)
102
#endif
103
104
#if QT_CONFIG(itemmodel)
105
#define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)\
106
0
    F(QModelIndex, 42, QModelIndex) \
107
0
    F(QPersistentModelIndex, 50, QPersistentModelIndex)
108
#else
109
#define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)
110
#endif
111
112
#define QT_FOR_EACH_STATIC_CORE_CLASS(F)\
113
5
    F(QChar, 7, QChar) \
114
5
    F(QString, 10, QString) \
115
0
    F(QStringList, 11, QStringList) \
116
0
    F(QByteArray, 12, QByteArray) \
117
0
    F(QBitArray, 13, QBitArray) \
118
0
    F(QDate, 14, QDate) \
119
0
    F(QTime, 15, QTime) \
120
0
    F(QDateTime, 16, QDateTime) \
121
0
    F(QUrl, 17, QUrl) \
122
0
    F(QLocale, 18, QLocale) \
123
0
    F(QRect, 19, QRect) \
124
0
    F(QRectF, 20, QRectF) \
125
0
    F(QSize, 21, QSize) \
126
0
    F(QSizeF, 22, QSizeF) \
127
0
    F(QLine, 23, QLine) \
128
0
    F(QLineF, 24, QLineF) \
129
0
    F(QPoint, 25, QPoint) \
130
0
    F(QPointF, 26, QPointF) \
131
0
    F(QRegExp, 27, QRegExp) \
132
0
    QT_FOR_EACH_STATIC_EASINGCURVE(F) \
133
0
    F(QUuid, 30, QUuid) \
134
0
    F(QVariant, 41, QVariant) \
135
0
    F(QRegularExpression, 44, QRegularExpression) \
136
0
    F(QJsonValue, 45, QJsonValue) \
137
0
    F(QJsonObject, 46, QJsonObject) \
138
0
    F(QJsonArray, 47, QJsonArray) \
139
0
    F(QJsonDocument, 48, QJsonDocument) \
140
0
    F(QCborValue, 53, QCborValue) \
141
0
    F(QCborArray, 54, QCborArray) \
142
0
    F(QCborMap, 55, QCborMap) \
143
0
    QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)
144
145
#define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
146
0
    F(QObjectStar, 39, QObject*)
147
148
#define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
149
0
    F(QVariantMap, 8, QVariantMap) \
150
0
    F(QVariantList, 9, QVariantList) \
151
0
    F(QVariantHash, 28, QVariantHash) \
152
0
    F(QByteArrayList, 49, QByteArrayList) \
153
154
#define QT_FOR_EACH_STATIC_GUI_CLASS(F)\
155
0
    F(QFont, 64, QFont) \
156
0
    F(QPixmap, 65, QPixmap) \
157
0
    F(QBrush, 66, QBrush) \
158
0
    F(QColor, 67, QColor) \
159
0
    F(QPalette, 68, QPalette) \
160
0
    F(QIcon, 69, QIcon) \
161
0
    F(QImage, 70, QImage) \
162
0
    F(QPolygon, 71, QPolygon) \
163
0
    F(QRegion, 72, QRegion) \
164
0
    F(QBitmap, 73, QBitmap) \
165
0
    F(QCursor, 74, QCursor) \
166
0
    F(QKeySequence, 75, QKeySequence) \
167
0
    F(QPen, 76, QPen) \
168
0
    F(QTextLength, 77, QTextLength) \
169
0
    F(QTextFormat, 78, QTextFormat) \
170
0
    F(QMatrix, 79, QMatrix) \
171
0
    F(QTransform, 80, QTransform) \
172
0
    F(QMatrix4x4, 81, QMatrix4x4) \
173
0
    F(QVector2D, 82, QVector2D) \
174
0
    F(QVector3D, 83, QVector3D) \
175
0
    F(QVector4D, 84, QVector4D) \
176
0
    F(QQuaternion, 85, QQuaternion) \
177
0
    F(QPolygonF, 86, QPolygonF) \
178
0
    F(QColorSpace, 87, QColorSpace) \
179
180
181
#define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
182
0
    F(QSizePolicy, 121, QSizePolicy) \
183
184
// ### FIXME kill that set
185
#define QT_FOR_EACH_STATIC_HACKS_TYPE(F)\
186
    F(QMetaTypeId2<qreal>::MetaType, -1, qreal)
187
188
// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, AliasingType, "RealType")
189
#define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\
190
    F(ULong, -1, ulong, "unsigned long") \
191
    F(UInt, -1, uint, "unsigned int") \
192
    F(UShort, -1, ushort, "unsigned short") \
193
    F(UChar, -1, uchar, "unsigned char") \
194
    F(LongLong, -1, qlonglong, "long long") \
195
    F(ULongLong, -1, qulonglong, "unsigned long long") \
196
    F(SChar, -1, signed char, "qint8") \
197
    F(UChar, -1, uchar, "quint8") \
198
    F(Short, -1, short, "qint16") \
199
    F(UShort, -1, ushort, "quint16") \
200
    F(Int, -1, int, "qint32") \
201
    F(UInt, -1, uint, "quint32") \
202
    F(LongLong, -1, qlonglong, "qint64") \
203
    F(ULongLong, -1, qulonglong, "quint64") \
204
    F(QVariantList, -1, QVariantList, "QList<QVariant>") \
205
    F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \
206
    F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \
207
    F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \
208
209
#define QT_FOR_EACH_STATIC_TYPE(F)\
210
0
    QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
211
0
    QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
212
0
    QT_FOR_EACH_STATIC_CORE_CLASS(F)\
213
0
    QT_FOR_EACH_STATIC_CORE_POINTER(F)\
214
0
    QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
215
0
    QT_FOR_EACH_STATIC_GUI_CLASS(F)\
216
0
    QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
217
218
#define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \
219
    TypeName = Id,
220
221
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
222
    F(QList) \
223
    F(QVector) \
224
    F(QQueue) \
225
    F(QStack) \
226
    F(QSet) \
227
    /*end*/
228
229
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
230
    F(QHash, class) \
231
    F(QMap, class) \
232
    F(QPair, struct)
233
234
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
235
    F(QSharedPointer) \
236
    F(QWeakPointer) \
237
    F(QPointer)
238
239
class QDataStream;
240
class QMetaTypeInterface;
241
struct QMetaObject;
242
243
namespace QtPrivate
244
{
245
/*!
246
    This template is used for implicit conversion from type From to type To.
247
    \internal
248
*/
249
template<typename From, typename To>
250
To convertImplicit(const From& from)
251
{
252
    return from;
253
}
254
255
#ifndef QT_NO_DEBUG_STREAM
256
struct AbstractDebugStreamFunction
257
{
258
    typedef void (*Stream)(const AbstractDebugStreamFunction *, QDebug&, const void *);
259
    typedef void (*Destroy)(AbstractDebugStreamFunction *);
260
    explicit AbstractDebugStreamFunction(Stream s = nullptr, Destroy d = nullptr)
261
0
        : stream(s), destroy(d) {}
262
    Q_DISABLE_COPY(AbstractDebugStreamFunction)
263
    Stream stream;
264
    Destroy destroy;
265
};
266
267
template<typename T>
268
struct BuiltInDebugStreamFunction : public AbstractDebugStreamFunction
269
{
270
    BuiltInDebugStreamFunction()
271
        : AbstractDebugStreamFunction(stream, destroy) {}
272
    static void stream(const AbstractDebugStreamFunction *, QDebug& dbg, const void *r)
273
    {
274
        const T *rhs = static_cast<const T *>(r);
275
        operator<<(dbg, *rhs);
276
    }
277
278
    static void destroy(AbstractDebugStreamFunction *_this)
279
    {
280
        delete static_cast<BuiltInDebugStreamFunction *>(_this);
281
    }
282
};
283
#endif
284
285
struct AbstractComparatorFunction
286
{
287
    typedef bool (*LessThan)(const AbstractComparatorFunction *, const void *, const void *);
288
    typedef bool (*Equals)(const AbstractComparatorFunction *, const void *, const void *);
289
    typedef void (*Destroy)(AbstractComparatorFunction *);
290
    explicit AbstractComparatorFunction(LessThan lt = nullptr, Equals e = nullptr, Destroy d = nullptr)
291
0
        : lessThan(lt), equals(e), destroy(d) {}
292
    Q_DISABLE_COPY(AbstractComparatorFunction)
293
    LessThan lessThan;
294
    Equals equals;
295
    Destroy destroy;
296
};
297
298
template<typename T>
299
struct BuiltInComparatorFunction : public AbstractComparatorFunction
300
{
301
    BuiltInComparatorFunction()
302
        : AbstractComparatorFunction(lessThan, equals, destroy) {}
303
    static bool lessThan(const AbstractComparatorFunction *, const void *l, const void *r)
304
    {
305
        const T *lhs = static_cast<const T *>(l);
306
        const T *rhs = static_cast<const T *>(r);
307
        return *lhs < *rhs;
308
    }
309
310
    static bool equals(const AbstractComparatorFunction *, const void *l, const void *r)
311
    {
312
        const T *lhs = static_cast<const T *>(l);
313
        const T *rhs = static_cast<const T *>(r);
314
        return *lhs == *rhs;
315
    }
316
317
    static void destroy(AbstractComparatorFunction *_this)
318
    {
319
        delete static_cast<BuiltInComparatorFunction *>(_this);
320
    }
321
};
322
323
template<typename T>
324
struct BuiltInEqualsComparatorFunction : public AbstractComparatorFunction
325
{
326
    BuiltInEqualsComparatorFunction()
327
        : AbstractComparatorFunction(nullptr, equals, destroy) {}
328
    static bool equals(const AbstractComparatorFunction *, const void *l, const void *r)
329
    {
330
        const T *lhs = static_cast<const T *>(l);
331
        const T *rhs = static_cast<const T *>(r);
332
        return *lhs == *rhs;
333
    }
334
335
    static void destroy(AbstractComparatorFunction *_this)
336
    {
337
        delete static_cast<BuiltInEqualsComparatorFunction *>(_this);
338
    }
339
};
340
341
struct AbstractConverterFunction
342
{
343
    typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*);
344
    explicit AbstractConverterFunction(Converter c = nullptr)
345
        : convert(c) {}
346
    Q_DISABLE_COPY(AbstractConverterFunction)
347
    Converter convert;
348
};
349
350
template<typename From, typename To>
351
struct ConverterMemberFunction : public AbstractConverterFunction
352
{
353
    explicit ConverterMemberFunction(To(From::*function)() const)
354
        : AbstractConverterFunction(convert),
355
          m_function(function) {}
356
    ~ConverterMemberFunction();
357
    static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
358
    {
359
        const From *f = static_cast<const From *>(in);
360
        To *t = static_cast<To *>(out);
361
        const ConverterMemberFunction *_typedThis =
362
            static_cast<const ConverterMemberFunction *>(_this);
363
        *t = (f->*_typedThis->m_function)();
364
        return true;
365
    }
366
367
    To(From::* const m_function)() const;
368
};
369
370
template<typename From, typename To>
371
struct ConverterMemberFunctionOk : public AbstractConverterFunction
372
{
373
    explicit ConverterMemberFunctionOk(To(From::*function)(bool *) const)
374
        : AbstractConverterFunction(convert),
375
          m_function(function) {}
376
    ~ConverterMemberFunctionOk();
377
    static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
378
    {
379
        const From *f = static_cast<const From *>(in);
380
        To *t = static_cast<To *>(out);
381
        bool ok = false;
382
        const ConverterMemberFunctionOk *_typedThis =
383
            static_cast<const ConverterMemberFunctionOk *>(_this);
384
        *t = (f->*_typedThis->m_function)(&ok);
385
        if (!ok)
386
            *t = To();
387
        return ok;
388
    }
389
390
    To(From::* const m_function)(bool*) const;
391
};
392
393
template<typename From, typename To, typename UnaryFunction>
394
struct ConverterFunctor : public AbstractConverterFunction
395
{
396
    explicit ConverterFunctor(UnaryFunction function)
397
        : AbstractConverterFunction(convert),
398
0
          m_function(function) {}
399
    ~ConverterFunctor();
400
    static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
401
0
    {
402
0
        const From *f = static_cast<const From *>(in);
403
0
        To *t = static_cast<To *>(out);
404
0
        const ConverterFunctor *_typedThis =
405
0
            static_cast<const ConverterFunctor *>(_this);
406
0
        *t = _typedThis->m_function(*f);
407
0
        return true;
408
0
    }
409
410
    UnaryFunction m_function;
411
};
412
413
    template<typename T, bool>
414
    struct ValueTypeIsMetaType;
415
    template<typename T, bool>
416
    struct AssociativeValueTypeIsMetaType;
417
    template<typename T, bool>
418
    struct IsMetaTypePair;
419
    template<typename, typename>
420
    struct MetaTypeSmartPointerHelper;
421
}
422
423
class Q_CORE_EXPORT QMetaType {
424
    enum ExtensionFlag { NoExtensionFlags,
425
                         CreateEx = 0x1, DestroyEx = 0x2,
426
                         ConstructEx = 0x4, DestructEx = 0x8,
427
                         NameEx = 0x10, SizeEx = 0x20,
428
                         CtorEx = 0x40, DtorEx = 0x80,
429
                         FlagsEx = 0x100, MetaObjectEx = 0x200
430
                       };
431
public:
432
#ifndef Q_CLANG_QDOC
433
    // The code that actually gets compiled.
434
    enum Type {
435
        // these are merged with QVariant
436
        QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
437
438
        FirstCoreType = Bool,
439
        LastCoreType = QCborMap,
440
        FirstGuiType = QFont,
441
        LastGuiType = QColorSpace,
442
        FirstWidgetsType = QSizePolicy,
443
        LastWidgetsType = QSizePolicy,
444
        HighestInternalId = LastWidgetsType,
445
446
        QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
447
448
        UnknownType = 0,
449
        User = 1024
450
    };
451
#else
452
    // If we are using QDoc it fakes the Type enum looks like this.
453
    enum Type {
454
        UnknownType = 0, Bool = 1, Int = 2, UInt = 3, LongLong = 4, ULongLong = 5,
455
        Double = 6, Long = 32, Short = 33, Char = 34, ULong = 35, UShort = 36,
456
        UChar = 37, Float = 38,
457
        VoidStar = 31,
458
        QChar = 7, QString = 10, QStringList = 11, QByteArray = 12,
459
        QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
460
        QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22,
461
        QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QRegExp = 27,
462
        QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42,
463
        QPersistentModelIndex = 50, QRegularExpression = 44,
464
        QJsonValue = 45, QJsonObject = 46, QJsonArray = 47, QJsonDocument = 48,
465
        QByteArrayList = 49, QObjectStar = 39, SChar = 40,
466
        Void = 43,
467
        Nullptr = 51,
468
        QVariantMap = 8, QVariantList = 9, QVariantHash = 28,
469
        QCborSimpleType = 52, QCborValue = 53, QCborArray = 54, QCborMap = 55,
470
471
        // Gui types
472
        QFont = 64, QPixmap = 65, QBrush = 66, QColor = 67, QPalette = 68,
473
        QIcon = 69, QImage = 70, QPolygon = 71, QRegion = 72, QBitmap = 73,
474
        QCursor = 74, QKeySequence = 75, QPen = 76, QTextLength = 77, QTextFormat = 78,
475
        QMatrix = 79, QTransform = 80, QMatrix4x4 = 81, QVector2D = 82,
476
        QVector3D = 83, QVector4D = 84, QQuaternion = 85, QPolygonF = 86, QColorSpace = 87,
477
478
        // Widget types
479
        QSizePolicy = 121,
480
        LastCoreType = QCborMap,
481
        LastGuiType = QColorSpace,
482
        User = 1024
483
    };
484
#endif
485
486
    enum TypeFlag {
487
        NeedsConstruction = 0x1,
488
        NeedsDestruction = 0x2,
489
        MovableType = 0x4,
490
        PointerToQObject = 0x8,
491
        IsEnumeration = 0x10,
492
        SharedPointerToQObject = 0x20,
493
        WeakPointerToQObject = 0x40,
494
        TrackingPointerToQObject = 0x80,
495
        WasDeclaredAsMetaType = 0x100,
496
        IsGadget = 0x200,
497
        PointerToGadget = 0x400
498
    };
499
    Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
500
501
    typedef void (*Deleter)(void *);
502
    typedef void *(*Creator)(const void *);
503
504
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
505
    typedef void (*Destructor)(void *);
506
    typedef void *(*Constructor)(void *, const void *); // TODO Qt6: remove me
507
#endif
508
    typedef void (*TypedDestructor)(int, void *);
509
    typedef void *(*TypedConstructor)(int, void *, const void *);
510
511
    typedef void (*SaveOperator)(QDataStream &, const void *);
512
    typedef void (*LoadOperator)(QDataStream &, void *);
513
#ifndef QT_NO_DATASTREAM
514
    static void registerStreamOperators(const char *typeName, SaveOperator saveOp,
515
                                        LoadOperator loadOp);
516
    static void registerStreamOperators(int type, SaveOperator saveOp,
517
                                        LoadOperator loadOp);
518
#endif
519
    static int registerType(const char *typeName, Deleter deleter,
520
                            Creator creator);
521
    static int registerType(const char *typeName, Deleter deleter,
522
                            Creator creator,
523
                            Destructor destructor,
524
                            Constructor constructor,
525
                            int size,
526
                            QMetaType::TypeFlags flags,
527
                            const QMetaObject *metaObject);
528
    static int registerType(const char *typeName,
529
                            TypedDestructor destructor,
530
                            TypedConstructor constructor,
531
                            int size,
532
                            QMetaType::TypeFlags flags,
533
                            const QMetaObject *metaObject);
534
    static bool unregisterType(int type);
535
    static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Deleter deleter,
536
                            Creator creator,
537
                            Destructor destructor,
538
                            Constructor constructor,
539
                            int size,
540
                            QMetaType::TypeFlags flags,
541
                            const QMetaObject *metaObject);
542
    static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Destructor destructor,
543
                            Constructor constructor,
544
                            int size,
545
                            QMetaType::TypeFlags flags,
546
                            const QMetaObject *metaObject);
547
    static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, TypedDestructor destructor,
548
                            TypedConstructor constructor,
549
                            int size,
550
                            QMetaType::TypeFlags flags,
551
                            const QMetaObject *metaObject);
552
    static int registerTypedef(const char *typeName, int aliasId);
553
    static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId);
554
    static int type(const char *typeName);
555
556
    static int type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName);
557
    static const char *typeName(int type);
558
    static int sizeOf(int type);
559
    static TypeFlags typeFlags(int type);
560
    static const QMetaObject *metaObjectForType(int type);
561
    static bool isRegistered(int type);
562
    static void *create(int type, const void *copy = nullptr);
563
#if QT_DEPRECATED_SINCE(5, 0)
564
    QT_DEPRECATED static void *construct(int type, const void *copy = nullptr)
565
    { return create(type, copy); }
566
#endif
567
    static void destroy(int type, void *data);
568
    static void *construct(int type, void *where, const void *copy);
569
    static void destruct(int type, void *where);
570
571
#ifndef QT_NO_DATASTREAM
572
    static bool save(QDataStream &stream, int type, const void *data);
573
    static bool load(QDataStream &stream, int type, void *data);
574
#endif
575
576
    explicit QMetaType(const int type = QMetaType::UnknownType); // ### Qt6: drop const
577
    inline ~QMetaType();
578
579
    inline bool isValid() const;
580
    inline bool isRegistered() const;
581
    inline int id() const;
582
    inline int sizeOf() const;
583
    inline TypeFlags flags() const;
584
    inline const QMetaObject *metaObject() const;
585
    QT_PREPEND_NAMESPACE(QByteArray) name() const;
586
587
    inline void *create(const void *copy = nullptr) const;
588
    inline void destroy(void *data) const;
589
    inline void *construct(void *where, const void *copy = nullptr) const;
590
    inline void destruct(void *data) const;
591
592
    template<typename T>
593
    static QMetaType fromType()
594
    { return QMetaType(qMetaTypeId<T>()); }
595
596
    friend bool operator==(const QMetaType &a, const QMetaType &b)
597
0
    { return a.m_typeId == b.m_typeId; }
598
599
    friend bool operator!=(const QMetaType &a, const QMetaType &b)
600
0
    { return a.m_typeId != b.m_typeId; }
601
602
603
public:
604
    template<typename T>
605
    static bool registerComparators()
606
    {
607
        Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
608
            "QMetaType::registerComparators: The type must be a custom type.");
609
610
        const int typeId = qMetaTypeId<T>();
611
        static const QtPrivate::BuiltInComparatorFunction<T> f;
612
        return registerComparatorFunction( &f, typeId);
613
    }
614
    template<typename T>
615
    static bool registerEqualsComparator()
616
    {
617
        Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
618
            "QMetaType::registerEqualsComparator: The type must be a custom type.");
619
        const int typeId = qMetaTypeId<T>();
620
        static const QtPrivate::BuiltInEqualsComparatorFunction<T> f;
621
        return registerComparatorFunction( &f, typeId);
622
    }
623
624
    template<typename T>
625
    static bool hasRegisteredComparators()
626
    {
627
        return hasRegisteredComparators(qMetaTypeId<T>());
628
    }
629
    static bool hasRegisteredComparators(int typeId);
630
631
632
#ifndef QT_NO_DEBUG_STREAM
633
    template<typename T>
634
    static bool registerDebugStreamOperator()
635
    {
636
        Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
637
            "QMetaType::registerDebugStreamOperator: The type must be a custom type.");
638
639
        const int typeId = qMetaTypeId<T>();
640
        static const QtPrivate::BuiltInDebugStreamFunction<T> f;
641
        return registerDebugStreamOperatorFunction(&f, typeId);
642
    }
643
    template<typename T>
644
    static bool hasRegisteredDebugStreamOperator()
645
    {
646
        return hasRegisteredDebugStreamOperator(qMetaTypeId<T>());
647
    }
648
    static bool hasRegisteredDebugStreamOperator(int typeId);
649
#endif
650
651
    // implicit conversion supported like double -> float
652
    template<typename From, typename To>
653
    static bool registerConverter()
654
    {
655
        return registerConverter<From, To>(QtPrivate::convertImplicit<From, To>);
656
    }
657
658
#ifdef Q_CLANG_QDOC
659
    template<typename MemberFunction, int>
660
    static bool registerConverter(MemberFunction function);
661
    template<typename MemberFunctionOk, char>
662
    static bool registerConverter(MemberFunctionOk function);
663
    template<typename UnaryFunction>
664
    static bool registerConverter(UnaryFunction function);
665
#else
666
    // member function as in "QString QFont::toString() const"
667
    template<typename From, typename To>
668
    static bool registerConverter(To(From::*function)() const)
669
    {
670
        Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
671
            "QMetaType::registerConverter: At least one of the types must be a custom type.");
672
673
        const int fromTypeId = qMetaTypeId<From>();
674
        const int toTypeId = qMetaTypeId<To>();
675
        static const QtPrivate::ConverterMemberFunction<From, To> f(function);
676
        return registerConverterFunction(&f, fromTypeId, toTypeId);
677
    }
678
679
    // member function as in "double QString::toDouble(bool *ok = nullptr) const"
680
    template<typename From, typename To>
681
    static bool registerConverter(To(From::*function)(bool*) const)
682
    {
683
        Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
684
            "QMetaType::registerConverter: At least one of the types must be a custom type.");
685
686
        const int fromTypeId = qMetaTypeId<From>();
687
        const int toTypeId = qMetaTypeId<To>();
688
        static const QtPrivate::ConverterMemberFunctionOk<From, To> f(function);
689
        return registerConverterFunction(&f, fromTypeId, toTypeId);
690
    }
691
692
    // functor or function pointer
693
    template<typename From, typename To, typename UnaryFunction>
694
    static bool registerConverter(UnaryFunction function)
695
    {
696
        Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
697
            "QMetaType::registerConverter: At least one of the types must be a custom type.");
698
699
        const int fromTypeId = qMetaTypeId<From>();
700
        const int toTypeId = qMetaTypeId<To>();
701
        static const QtPrivate::ConverterFunctor<From, To, UnaryFunction> f(function);
702
        return registerConverterFunction(&f, fromTypeId, toTypeId);
703
    }
704
#endif
705
706
    static bool convert(const void *from, int fromTypeId, void *to, int toTypeId);
707
    static bool compare(const void *lhs, const void *rhs, int typeId, int* result);
708
    static bool equals(const void *lhs, const void *rhs, int typeId, int* result);
709
    static bool debugStream(QDebug& dbg, const void *rhs, int typeId);
710
711
    template<typename From, typename To>
712
    static bool hasRegisteredConverterFunction()
713
    {
714
        return hasRegisteredConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
715
    }
716
717
    static bool hasRegisteredConverterFunction(int fromTypeId, int toTypeId);
718
719
private:
720
    static QMetaType typeInfo(const int type);
721
    inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
722
                     TypedConstructor creator,
723
                     TypedDestructor deleter,
724
                     SaveOperator saveOp,
725
                     LoadOperator loadOp,
726
                     Constructor constructor,
727
                     Destructor destructor,
728
                     uint sizeOf,
729
                     uint theTypeFlags,
730
                     int typeId,
731
                     const QMetaObject *metaObject);
732
    QMetaType(const QMetaType &other);
733
    QMetaType &operator =(const QMetaType &);
734
    inline bool isExtended(const ExtensionFlag flag) const { return m_extensionFlags & flag; }
735
736
    // Methods used for future binary compatible extensions
737
    void ctor(const QMetaTypeInterface *info);
738
    void dtor();
739
    uint sizeExtended() const;
740
    QMetaType::TypeFlags flagsExtended() const;
741
    const QMetaObject *metaObjectExtended() const;
742
    void *createExtended(const void *copy = nullptr) const;
743
    void destroyExtended(void *data) const;
744
    void *constructExtended(void *where, const void *copy = nullptr) const;
745
    void destructExtended(void *data) const;
746
747
    static bool registerComparatorFunction(const QtPrivate::AbstractComparatorFunction *f, int type);
748
#ifndef QT_NO_DEBUG_STREAM
749
    static bool registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f, int type);
750
#endif
751
752
// ### Qt6: FIXME: Remove the special Q_CC_MSVC handling, it was introduced to maintain BC.
753
#if !defined(Q_NO_TEMPLATE_FRIENDS) && !defined(Q_CC_MSVC)
754
#ifndef Q_CLANG_QDOC
755
    template<typename, bool> friend struct QtPrivate::ValueTypeIsMetaType;
756
    template<typename, typename> friend struct QtPrivate::ConverterMemberFunction;
757
    template<typename, typename> friend struct QtPrivate::ConverterMemberFunctionOk;
758
    template<typename, typename, typename> friend struct QtPrivate::ConverterFunctor;
759
    template<typename, bool> friend struct QtPrivate::AssociativeValueTypeIsMetaType;
760
    template<typename, bool> friend struct QtPrivate::IsMetaTypePair;
761
    template<typename, typename> friend struct QtPrivate::MetaTypeSmartPointerHelper;
762
#endif
763
#else
764
public:
765
#endif
766
    static bool registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to);
767
    static void unregisterConverterFunction(int from, int to);
768
private:
769
770
    TypedConstructor m_typedConstructor;
771
    TypedDestructor m_typedDestructor;
772
    SaveOperator m_saveOp;
773
    LoadOperator m_loadOp;
774
    Constructor m_constructor;
775
    Destructor m_destructor;
776
    void *m_extension; // space reserved for future use
777
    uint m_size;
778
    uint m_typeFlags;
779
    uint m_extensionFlags;
780
    int m_typeId;
781
    const QMetaObject *m_metaObject;
782
};
783
784
#undef QT_DEFINE_METATYPE_ID
785
786
Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
787
788
namespace QtPrivate {
789
790
template<typename From, typename To>
791
ConverterMemberFunction<From, To>::~ConverterMemberFunction()
792
{
793
    QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
794
}
795
template<typename From, typename To>
796
ConverterMemberFunctionOk<From, To>::~ConverterMemberFunctionOk()
797
{
798
    QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
799
}
800
template<typename From, typename To, typename UnaryFunction>
801
ConverterFunctor<From, To, UnaryFunction>::~ConverterFunctor()
802
0
{
803
0
    QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
804
0
}
805
806
}
807
808
#define QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(C, F)  \
809
    }                                               \
810
    Q_DECLARE_TYPEINFO(QtMetaTypePrivate:: C, (F)); \
811
    namespace QtMetaTypePrivate {
812
813
namespace QtMetaTypePrivate {
814
template <typename T, bool Accepted = true>
815
struct QMetaTypeFunctionHelper {
816
    static void Destruct(void *t)
817
0
    {
818
0
        Q_UNUSED(t) // Silence MSVC that warns for POD types.
819
0
        static_cast<T*>(t)->~T();
820
0
    }
Unexecuted instantiation: QtMetaTypePrivate::QMetaTypeFunctionHelper<QtMetaTypePrivate::QAssociativeIterableImpl, true>::Destruct(void*)
Unexecuted instantiation: QtMetaTypePrivate::QMetaTypeFunctionHelper<QtMetaTypePrivate::QPairVariantInterfaceImpl, true>::Destruct(void*)
Unexecuted instantiation: QtMetaTypePrivate::QMetaTypeFunctionHelper<QPair<QVariant, QVariant>, true>::Destruct(void*)
821
822
    static void *Construct(void *where, const void *t)
823
0
    {
824
0
        if (t)
825
0
            return new (where) T(*static_cast<const T*>(t));
826
0
        return new (where) T;
827
0
    }
Unexecuted instantiation: QtMetaTypePrivate::QMetaTypeFunctionHelper<QtMetaTypePrivate::QAssociativeIterableImpl, true>::Construct(void*, void const*)
Unexecuted instantiation: QtMetaTypePrivate::QMetaTypeFunctionHelper<QtMetaTypePrivate::QPairVariantInterfaceImpl, true>::Construct(void*, void const*)
Unexecuted instantiation: QtMetaTypePrivate::QMetaTypeFunctionHelper<QPair<QVariant, QVariant>, true>::Construct(void*, void const*)
828
#ifndef QT_NO_DATASTREAM
829
    static void Save(QDataStream &stream, const void *t)
830
    {
831
        stream << *static_cast<const T*>(t);
832
    }
833
834
    static void Load(QDataStream &stream, void *t)
835
    {
836
        stream >> *static_cast<T*>(t);
837
    }
838
#endif // QT_NO_DATASTREAM
839
};
840
841
template <typename T>
842
struct QMetaTypeFunctionHelper<T, /* Accepted */ false> {
843
    static void Destruct(void *) {}
844
    static void *Construct(void *, const void *) { return nullptr; }
845
#ifndef QT_NO_DATASTREAM
846
    static void Save(QDataStream &, const void *) {}
847
    static void Load(QDataStream &, void *) {}
848
#endif // QT_NO_DATASTREAM
849
};
850
template <>
851
struct QMetaTypeFunctionHelper<void, /* Accepted */ true>
852
        : public QMetaTypeFunctionHelper<void, /* Accepted */ false>
853
{};
854
855
struct VariantData
856
{
857
    VariantData(const int metaTypeId_,
858
                const void *data_,
859
                const uint flags_)
860
      : metaTypeId(metaTypeId_)
861
      , data(data_)
862
      , flags(flags_)
863
    {
864
    }
865
    VariantData(const VariantData &other)
866
0
        : metaTypeId(other.metaTypeId), data(other.data), flags(other.flags){}
867
    const int metaTypeId;
868
    const void *data;
869
    const uint flags;
870
private:
871
    // copy constructor allowed to be implicit to silence level 4 warning from MSVC
872
    VariantData &operator=(const VariantData &) = delete;
873
};
874
875
template<typename const_iterator>
876
struct IteratorOwnerCommon
877
{
878
    static void assign(void **ptr, const_iterator iterator)
879
    {
880
        *ptr = new const_iterator(iterator);
881
    }
882
    static void assign(void **ptr, void * const * src)
883
    {
884
        *ptr = new const_iterator(*static_cast<const_iterator*>(*src));
885
    }
886
887
    static void advance(void **iterator, int step)
888
    {
889
        const_iterator &it = *static_cast<const_iterator*>(*iterator);
890
        std::advance(it, step);
891
    }
892
893
    static void destroy(void **ptr)
894
    {
895
        delete static_cast<const_iterator*>(*ptr);
896
    }
897
898
    static bool equal(void * const *it, void * const *other)
899
    {
900
        return *static_cast<const_iterator*>(*it) == *static_cast<const_iterator*>(*other);
901
    }
902
};
903
904
template<typename const_iterator>
905
struct IteratorOwner : IteratorOwnerCommon<const_iterator>
906
{
907
    static const void *getData(void * const *iterator)
908
    {
909
        return &**static_cast<const_iterator*>(*iterator);
910
    }
911
912
    static const void *getData(const_iterator it)
913
    {
914
        return &*it;
915
    }
916
};
917
918
struct Q_CORE_EXPORT VectorBoolElements
919
{
920
  static const bool true_element;
921
  static const bool false_element;
922
};
923
924
template<>
925
struct IteratorOwner<std::vector<bool>::const_iterator> : IteratorOwnerCommon<std::vector<bool>::const_iterator>
926
{
927
public:
928
    static const void *getData(void * const *iterator)
929
0
    {
930
0
        return **static_cast<std::vector<bool>::const_iterator*>(*iterator) ?
931
0
            &VectorBoolElements::true_element : &VectorBoolElements::false_element;
932
0
    }
933
934
    static const void *getData(const std::vector<bool>::const_iterator& it)
935
0
    {
936
0
        return *it ? &VectorBoolElements::true_element : &VectorBoolElements::false_element;
937
0
    }
938
};
939
940
template<typename value_type>
941
struct IteratorOwner<const value_type*>
942
{
943
private:
944
    // We need to disable typed overloads of assign() and getData() if the value_type
945
    // is void* to avoid overloads conflicts. We do it by injecting unaccessible Dummy
946
    // type as part of the overload signature.
947
    struct Dummy {};
948
    typedef typename std::conditional<std::is_same<value_type, void*>::value, Dummy, value_type>::type value_type_OR_Dummy;
949
public:
950
    static void assign(void **ptr, const value_type_OR_Dummy *iterator )
951
    {
952
        *ptr = const_cast<value_type*>(iterator);
953
    }
954
    static void assign(void **ptr, void * const * src)
955
    {
956
        *ptr = static_cast<value_type*>(*src);
957
    }
958
959
    static void advance(void **iterator, int step)
960
    {
961
        value_type *it = static_cast<value_type*>(*iterator);
962
        std::advance(it, step);
963
        *iterator = it;
964
    }
965
966
    static void destroy(void **)
967
    {
968
    }
969
970
    static const void *getData(void * const *iterator)
971
    {
972
        return *iterator;
973
    }
974
975
    static const void *getData(const value_type_OR_Dummy *it)
976
    {
977
        return it;
978
    }
979
980
    static bool equal(void * const *it, void * const *other)
981
    {
982
        return static_cast<value_type*>(*it) == static_cast<value_type*>(*other);
983
    }
984
};
985
986
enum IteratorCapability
987
{
988
    ForwardCapability = 1,
989
    BiDirectionalCapability = 2,
990
    RandomAccessCapability = 4
991
};
992
993
enum ContainerCapability
994
{
995
    ContainerIsAppendable = 1
996
};
997
998
template<typename Container, typename T = void>
999
struct ContainerCapabilitiesImpl
1000
{
1001
    enum {ContainerCapabilities = 0};
1002
    using appendFunction = void(*)(const void *container, const void *newElement);
1003
    static constexpr const appendFunction appendImpl = nullptr;
1004
};
1005
1006
template<typename Container>
1007
struct ContainerCapabilitiesImpl<Container, decltype(std::declval<Container>().push_back(std::declval<typename Container::value_type>()))>
1008
{
1009
    enum {ContainerCapabilities = ContainerIsAppendable};
1010
1011
    // The code below invokes undefined behavior if and only if the pointer passed into QSequentialIterableImpl
1012
    // pointed to a const object to begin with
1013
    static void appendImpl(const void *container, const void *value)
1014
    { static_cast<Container *>(const_cast<void *>(container))->push_back(*static_cast<const typename Container::value_type *>(value)); }
1015
};
1016
1017
namespace QtPrivate {
1018
namespace ContainerCapabilitiesMetaProgrammingHelper {
1019
    template<typename... Ts>
1020
    using void_t = void;
1021
}
1022
}
1023
1024
template<typename Container>
1025
struct ContainerCapabilitiesImpl<Container, QtPrivate::ContainerCapabilitiesMetaProgrammingHelper::void_t<decltype(std::declval<Container>().insert(std::declval<typename Container::value_type>())), decltype(std::declval<typename Container::value_type>() == std::declval<typename Container::value_type>())>>
1026
{
1027
    enum {ContainerCapabilities = ContainerIsAppendable};
1028
1029
    // The code below invokes undefined behavior if and only if the pointer passed into QSequentialIterableImpl
1030
    // pointed to a const object to begin with
1031
    static void appendImpl(const void *container, const void *value)
1032
    { static_cast<Container *>(const_cast<void *>(container))->insert(*static_cast<const typename Container::value_type *>(value)); }
1033
};
1034
1035
template<typename T, typename Category = typename std::iterator_traits<typename T::const_iterator>::iterator_category>
1036
struct CapabilitiesImpl;
1037
1038
template<typename T>
1039
struct CapabilitiesImpl<T, std::forward_iterator_tag>
1040
{ enum { IteratorCapabilities = ForwardCapability }; };
1041
template<typename T>
1042
struct CapabilitiesImpl<T, std::bidirectional_iterator_tag>
1043
{ enum { IteratorCapabilities = BiDirectionalCapability | ForwardCapability }; };
1044
template<typename T>
1045
struct CapabilitiesImpl<T, std::random_access_iterator_tag>
1046
{ enum { IteratorCapabilities = RandomAccessCapability | BiDirectionalCapability | ForwardCapability }; };
1047
1048
template<typename T>
1049
struct ContainerAPI : CapabilitiesImpl<T>
1050
{
1051
    static int size(const T *t) { return int(std::distance(t->begin(), t->end())); }
1052
};
1053
1054
template<typename T>
1055
struct ContainerAPI<QList<T> > : CapabilitiesImpl<QList<T> >
1056
{ static int size(const QList<T> *t) { return t->size(); } };
1057
1058
template<typename T>
1059
struct ContainerAPI<QVector<T> > : CapabilitiesImpl<QVector<T> >
1060
{ static int size(const QVector<T> *t) { return t->size(); } };
1061
1062
template<typename T>
1063
struct ContainerAPI<std::vector<T> > : CapabilitiesImpl<std::vector<T> >
1064
{ static int size(const std::vector<T> *t) { return int(t->size()); } };
1065
1066
template<typename T>
1067
struct ContainerAPI<std::list<T> > : CapabilitiesImpl<std::list<T> >
1068
{ static int size(const std::list<T> *t) { return int(t->size()); } };
1069
1070
/*
1071
 revision 0: _iteratorCapabilities is simply a uint, where the bits at _revision were never set
1072
 revision 1: _iteratorCapabilties is treated as a bitfield, the remaining bits are used to introduce
1073
             _revision, _containerCapabilities and _unused. The latter contains 21 bits that are
1074
             not used yet
1075
*/
1076
class QSequentialIterableImpl
1077
{
1078
public:
1079
    const void * _iterable;
1080
    void *_iterator;
1081
    int _metaType_id;
1082
    uint _metaType_flags;
1083
    uint _iteratorCapabilities;
1084
    // Iterator capabilities looks actually like
1085
    // uint _iteratorCapabilities:4;
1086
    // uint _revision:3;
1087
    // uint _containerCapabilities:4;
1088
    // uint _unused:21;*/
1089
    typedef int(*sizeFunc)(const void *p);
1090
    typedef const void * (*atFunc)(const void *p, int);
1091
    typedef void (*moveIteratorFunc)(const void *p, void **);
1092
    enum Position { ToBegin, ToEnd };
1093
    typedef void (*moveIteratorFunc2)(const void *p, void **, Position position);
1094
    typedef void (*advanceFunc)(void **p, int);
1095
    typedef VariantData (*getFunc)( void * const *p, int metaTypeId, uint flags);
1096
    typedef void (*destroyIterFunc)(void **p);
1097
    typedef bool (*equalIterFunc)(void * const *p, void * const *other);
1098
    typedef void (*copyIterFunc)(void **, void * const *);
1099
    typedef void(*appendFunction)(const void *container, const void *newElement);
1100
1101
0
    IteratorCapability iteratorCapabilities() {return static_cast<IteratorCapability>(_iteratorCapabilities & 0xF);}
1102
0
    uint revision() {return _iteratorCapabilities >> 4 & 0x7;}
1103
0
    uint containerCapabilities() {return _iteratorCapabilities >> 7 & 0xF;}
1104
1105
    sizeFunc _size;
1106
    atFunc _at;
1107
    union {
1108
        moveIteratorFunc _moveToBegin;
1109
        moveIteratorFunc2 _moveTo;
1110
    };
1111
    union {
1112
        moveIteratorFunc _moveToEnd;
1113
        appendFunction _append;
1114
    };
1115
    advanceFunc _advance;
1116
    getFunc _get;
1117
    destroyIterFunc _destroyIter;
1118
    equalIterFunc _equalIter;
1119
    copyIterFunc _copyIter;
1120
1121
    template<class T>
1122
    static int sizeImpl(const void *p)
1123
    { return ContainerAPI<T>::size(static_cast<const T*>(p)); }
1124
1125
    template<class T>
1126
    static const void* atImpl(const void *p, int idx)
1127
    {
1128
        typename T::const_iterator i = static_cast<const T*>(p)->begin();
1129
        std::advance(i, idx);
1130
        return IteratorOwner<typename T::const_iterator>::getData(i);
1131
    }
1132
1133
    template<class T>
1134
    static void moveToBeginImpl(const void *container, void **iterator)
1135
    { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); }
1136
1137
    template<class T>
1138
    static void moveToEndImpl(const void *container, void **iterator)
1139
    { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
1140
1141
    template<class Container>
1142
    static void moveToImpl(const void *container, void **iterator, Position position)
1143
    {
1144
        if (position == ToBegin)
1145
            moveToBeginImpl<Container>(container, iterator);
1146
        else
1147
            moveToEndImpl<Container>(container, iterator);
1148
    }
1149
1150
    template<class T>
1151
    static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags)
1152
    { return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); }
1153
1154
public:
1155
    template<class T> QSequentialIterableImpl(const T*p)
1156
      : _iterable(p)
1157
      , _iterator(nullptr)
1158
      , _metaType_id(qMetaTypeId<typename T::value_type>())
1159
      , _metaType_flags(QTypeInfo<typename T::value_type>::isPointer)
1160
      , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities | (1 << 4) | (ContainerCapabilitiesImpl<T>::ContainerCapabilities << (4+3)))
1161
      , _size(sizeImpl<T>)
1162
      , _at(atImpl<T>)
1163
      , _moveTo(moveToImpl<T>)
1164
      , _append(ContainerCapabilitiesImpl<T>::appendImpl)
1165
      , _advance(IteratorOwner<typename T::const_iterator>::advance)
1166
      , _get(getImpl<T>)
1167
      , _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
1168
      , _equalIter(IteratorOwner<typename T::const_iterator>::equal)
1169
      , _copyIter(IteratorOwner<typename T::const_iterator>::assign)
1170
    {
1171
    }
1172
1173
    QSequentialIterableImpl()
1174
      : _iterable(nullptr)
1175
      , _iterator(nullptr)
1176
      , _metaType_id(QMetaType::UnknownType)
1177
      , _metaType_flags(0)
1178
      , _iteratorCapabilities(0 | (1 << 4) ) // no iterator capabilities, revision 1
1179
      , _size(nullptr)
1180
      , _at(nullptr)
1181
      , _moveToBegin(nullptr)
1182
      , _moveToEnd(nullptr)
1183
      , _advance(nullptr)
1184
      , _get(nullptr)
1185
      , _destroyIter(nullptr)
1186
      , _equalIter(nullptr)
1187
      , _copyIter(nullptr)
1188
    {
1189
    }
1190
1191
0
    inline void moveToBegin() {
1192
0
        if (revision() == 0)
1193
0
            _moveToBegin(_iterable, &_iterator);
1194
0
        else
1195
0
            _moveTo(_iterable, &_iterator, ToBegin);
1196
0
    }
1197
0
    inline void moveToEnd() {
1198
0
        if (revision() == 0)
1199
0
            _moveToEnd(_iterable, &_iterator);
1200
0
        else
1201
0
            _moveTo(_iterable, &_iterator, ToEnd);
1202
0
    }
1203
0
    inline bool equal(const QSequentialIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
1204
0
    inline QSequentialIterableImpl &advance(int i) {
1205
0
      Q_ASSERT(i > 0 || _iteratorCapabilities & BiDirectionalCapability);
1206
0
      _advance(&_iterator, i);
1207
0
      return *this;
1208
0
    }
1209
1210
0
    inline void append(const void *newElement) {
1211
0
        if (containerCapabilities() & ContainerIsAppendable)
1212
0
            _append(_iterable, newElement);
1213
0
    }
1214
1215
0
    inline VariantData getCurrent() const { return _get(&_iterator, _metaType_id, _metaType_flags); }
1216
1217
    VariantData at(int idx) const
1218
0
    { return VariantData(_metaType_id, _at(_iterable, idx), _metaType_flags); }
1219
1220
0
    int size() const { Q_ASSERT(_iterable); return _size(_iterable); }
1221
1222
0
    inline void destroyIter() { _destroyIter(&_iterator); }
1223
1224
    void copy(const QSequentialIterableImpl &other)
1225
0
    {
1226
0
      *this = other;
1227
0
      _copyIter(&_iterator, &other._iterator);
1228
0
    }
1229
};
1230
QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QSequentialIterableImpl, Q_MOVABLE_TYPE)
1231
1232
template<typename From>
1233
struct QSequentialIterableConvertFunctor
1234
{
1235
    QSequentialIterableImpl operator()(const From &f) const
1236
    {
1237
        return QSequentialIterableImpl(&f);
1238
    }
1239
};
1240
}
1241
1242
namespace QtMetaTypePrivate {
1243
template<typename T, bool = std::is_same<typename T::const_iterator::value_type, typename T::mapped_type>::value>
1244
struct AssociativeContainerAccessor
1245
{
1246
    static const typename T::key_type& getKey(const typename T::const_iterator &it)
1247
    {
1248
        return it.key();
1249
    }
1250
1251
    static const typename T::mapped_type& getValue(const typename T::const_iterator &it)
1252
    {
1253
        return it.value();
1254
    }
1255
};
1256
1257
template<typename T, bool = std::is_same<typename T::const_iterator::value_type, std::pair<const typename T::key_type, typename T::mapped_type> >::value>
1258
struct StlStyleAssociativeContainerAccessor;
1259
1260
template<typename T>
1261
struct StlStyleAssociativeContainerAccessor<T, true>
1262
{
1263
    static const typename T::key_type& getKey(const typename T::const_iterator &it)
1264
    {
1265
        return it->first;
1266
    }
1267
1268
    static const typename T::mapped_type& getValue(const typename T::const_iterator &it)
1269
    {
1270
        return it->second;
1271
    }
1272
};
1273
1274
template<typename T>
1275
struct AssociativeContainerAccessor<T, false> : public StlStyleAssociativeContainerAccessor<T>
1276
{
1277
};
1278
1279
class QAssociativeIterableImpl
1280
{
1281
public:
1282
    const void *_iterable;
1283
    void *_iterator;
1284
    int _metaType_id_key;
1285
    uint _metaType_flags_key;
1286
    int _metaType_id_value;
1287
    uint _metaType_flags_value;
1288
    typedef int(*sizeFunc)(const void *p);
1289
    typedef void (*findFunc)(const void *container, const void *p, void **iterator);
1290
    typedef void (*beginFunc)(const void *p, void **);
1291
    typedef void (*advanceFunc)(void **p, int);
1292
    typedef VariantData (*getFunc)(void * const *p, int metaTypeId, uint flags);
1293
    typedef void (*destroyIterFunc)(void **p);
1294
    typedef bool (*equalIterFunc)(void * const *p, void * const *other);
1295
    typedef void (*copyIterFunc)(void **, void * const *);
1296
1297
    sizeFunc _size;
1298
    findFunc _find;
1299
    beginFunc _begin;
1300
    beginFunc _end;
1301
    advanceFunc _advance;
1302
    getFunc _getKey;
1303
    getFunc _getValue;
1304
    destroyIterFunc _destroyIter;
1305
    equalIterFunc _equalIter;
1306
    copyIterFunc _copyIter;
1307
1308
    template<class T>
1309
    static int sizeImpl(const void *p)
1310
    { return int(std::distance(static_cast<const T*>(p)->begin(),
1311
                               static_cast<const T*>(p)->end())); }
1312
1313
    template<class T>
1314
    static void findImpl(const void *container, const void *p, void **iterator)
1315
    { IteratorOwner<typename T::const_iterator>::assign(iterator,
1316
                                                        static_cast<const T*>(container)->find(*static_cast<const typename T::key_type*>(p))); }
1317
1318
    QT_WARNING_PUSH
1319
    QT_WARNING_DISABLE_DEPRECATED // Hits on the deprecated QHash::iterator::operator--()
1320
    template<class T>
1321
    static void advanceImpl(void **p, int step)
1322
    { std::advance(*static_cast<typename T::const_iterator*>(*p), step); }
1323
    QT_WARNING_POP
1324
1325
    template<class T>
1326
    static void beginImpl(const void *container, void **iterator)
1327
    { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); }
1328
1329
    template<class T>
1330
    static void endImpl(const void *container, void **iterator)
1331
    { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
1332
1333
    template<class T>
1334
    static VariantData getKeyImpl(void * const *iterator, int metaTypeId, uint flags)
1335
    { return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getKey(*static_cast<typename T::const_iterator*>(*iterator)), flags); }
1336
1337
    template<class T>
1338
    static VariantData getValueImpl(void * const *iterator, int metaTypeId, uint flags)
1339
    { return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getValue(*static_cast<typename T::const_iterator*>(*iterator)), flags); }
1340
1341
public:
1342
    template<class T> QAssociativeIterableImpl(const T*p)
1343
      : _iterable(p)
1344
      , _iterator(nullptr)
1345
      , _metaType_id_key(qMetaTypeId<typename T::key_type>())
1346
      , _metaType_flags_key(QTypeInfo<typename T::key_type>::isPointer)
1347
      , _metaType_id_value(qMetaTypeId<typename T::mapped_type>())
1348
      , _metaType_flags_value(QTypeInfo<typename T::mapped_type>::isPointer)
1349
      , _size(sizeImpl<T>)
1350
      , _find(findImpl<T>)
1351
      , _begin(beginImpl<T>)
1352
      , _end(endImpl<T>)
1353
      , _advance(advanceImpl<T>)
1354
      , _getKey(getKeyImpl<T>)
1355
      , _getValue(getValueImpl<T>)
1356
      , _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
1357
      , _equalIter(IteratorOwner<typename T::const_iterator>::equal)
1358
      , _copyIter(IteratorOwner<typename T::const_iterator>::assign)
1359
    {
1360
    }
1361
1362
    QAssociativeIterableImpl()
1363
      : _iterable(nullptr)
1364
      , _iterator(nullptr)
1365
      , _metaType_id_key(QMetaType::UnknownType)
1366
      , _metaType_flags_key(0)
1367
      , _metaType_id_value(QMetaType::UnknownType)
1368
      , _metaType_flags_value(0)
1369
      , _size(nullptr)
1370
      , _find(nullptr)
1371
      , _begin(nullptr)
1372
      , _end(nullptr)
1373
      , _advance(nullptr)
1374
      , _getKey(nullptr)
1375
      , _getValue(nullptr)
1376
      , _destroyIter(nullptr)
1377
      , _equalIter(nullptr)
1378
      , _copyIter(nullptr)
1379
0
    {
1380
0
    }
1381
1382
0
    inline void begin() { _begin(_iterable, &_iterator); }
1383
0
    inline void end() { _end(_iterable, &_iterator); }
1384
0
    inline bool equal(const QAssociativeIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
1385
0
    inline QAssociativeIterableImpl &advance(int i) { _advance(&_iterator, i); return *this; }
1386
1387
0
    inline void destroyIter() { _destroyIter(&_iterator); }
1388
1389
0
    inline VariantData getCurrentKey() const { return _getKey(&_iterator, _metaType_id_key, _metaType_flags_key); }
1390
0
    inline VariantData getCurrentValue() const { return _getValue(&_iterator, _metaType_id_value, _metaType_flags_value); }
1391
1392
    inline void find(const VariantData &key)
1393
0
    { _find(_iterable, key.data, &_iterator); }
1394
1395
0
    int size() const { Q_ASSERT(_iterable); return _size(_iterable); }
1396
1397
    void copy(const QAssociativeIterableImpl &other)
1398
0
    {
1399
0
      *this = other;
1400
0
      _copyIter(&_iterator, &other._iterator);
1401
0
    }
1402
};
1403
QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QAssociativeIterableImpl, Q_MOVABLE_TYPE)
1404
1405
template<typename From>
1406
struct QAssociativeIterableConvertFunctor
1407
{
1408
    QAssociativeIterableImpl operator()(const From& f) const
1409
    {
1410
        return QAssociativeIterableImpl(&f);
1411
    }
1412
};
1413
1414
class QPairVariantInterfaceImpl
1415
{
1416
    const void *_pair;
1417
    int _metaType_id_first;
1418
    uint _metaType_flags_first;
1419
    int _metaType_id_second;
1420
    uint _metaType_flags_second;
1421
1422
    typedef VariantData (*getFunc)(const void * const *p, int metaTypeId, uint flags);
1423
1424
    getFunc _getFirst;
1425
    getFunc _getSecond;
1426
1427
    template<class T>
1428
    static VariantData getFirstImpl(const void * const *pair, int metaTypeId, uint flags)
1429
0
    { return VariantData(metaTypeId, &static_cast<const T*>(*pair)->first, flags); }
1430
    template<class T>
1431
    static VariantData getSecondImpl(const void * const *pair, int metaTypeId, uint flags)
1432
0
    { return VariantData(metaTypeId, &static_cast<const T*>(*pair)->second, flags); }
1433
1434
public:
1435
    template<class T> QPairVariantInterfaceImpl(const T*p)
1436
      : _pair(p)
1437
      , _metaType_id_first(qMetaTypeId<typename T::first_type>())
1438
      , _metaType_flags_first(QTypeInfo<typename T::first_type>::isPointer)
1439
      , _metaType_id_second(qMetaTypeId<typename T::second_type>())
1440
      , _metaType_flags_second(QTypeInfo<typename T::second_type>::isPointer)
1441
      , _getFirst(getFirstImpl<T>)
1442
      , _getSecond(getSecondImpl<T>)
1443
0
    {
1444
0
    }
1445
1446
    QPairVariantInterfaceImpl()
1447
      : _pair(nullptr)
1448
      , _metaType_id_first(QMetaType::UnknownType)
1449
      , _metaType_flags_first(0)
1450
      , _metaType_id_second(QMetaType::UnknownType)
1451
      , _metaType_flags_second(0)
1452
      , _getFirst(nullptr)
1453
      , _getSecond(nullptr)
1454
0
    {
1455
0
    }
1456
1457
0
    inline VariantData first() const { return _getFirst(&_pair, _metaType_id_first, _metaType_flags_first); }
1458
0
    inline VariantData second() const { return _getSecond(&_pair, _metaType_id_second, _metaType_flags_second); }
1459
};
1460
QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QPairVariantInterfaceImpl, Q_MOVABLE_TYPE)
1461
1462
template<typename From>
1463
struct QPairVariantInterfaceConvertFunctor;
1464
1465
template<typename T, typename U>
1466
struct QPairVariantInterfaceConvertFunctor<QPair<T, U> >
1467
{
1468
    QPairVariantInterfaceImpl operator()(const QPair<T, U>& f) const
1469
0
    {
1470
0
        return QPairVariantInterfaceImpl(&f);
1471
0
    }
1472
};
1473
1474
template<typename T, typename U>
1475
struct QPairVariantInterfaceConvertFunctor<std::pair<T, U> >
1476
{
1477
    QPairVariantInterfaceImpl operator()(const std::pair<T, U>& f) const
1478
    {
1479
        return QPairVariantInterfaceImpl(&f);
1480
    }
1481
};
1482
1483
}
1484
1485
class QObject;
1486
class QWidget;
1487
1488
#define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name) \
1489
    template <class T> class Name; \
1490
1491
QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER)
1492
1493
namespace QtPrivate
1494
{
1495
    template<typename T>
1496
    struct IsPointerToTypeDerivedFromQObject
1497
    {
1498
        enum { Value = false };
1499
    };
1500
1501
    // Specialize to avoid sizeof(void) warning
1502
    template<>
1503
    struct IsPointerToTypeDerivedFromQObject<void*>
1504
    {
1505
        enum { Value = false };
1506
    };
1507
    template<>
1508
    struct IsPointerToTypeDerivedFromQObject<const void*>
1509
    {
1510
        enum { Value = false };
1511
    };
1512
    template<>
1513
    struct IsPointerToTypeDerivedFromQObject<QObject*>
1514
    {
1515
        enum { Value = true };
1516
    };
1517
1518
    template<typename T>
1519
    struct IsPointerToTypeDerivedFromQObject<T*>
1520
    {
1521
        typedef qint8 yes_type;
1522
        typedef qint64 no_type;
1523
1524
#ifndef QT_NO_QOBJECT
1525
        static yes_type checkType(QObject* );
1526
#endif
1527
        static no_type checkType(...);
1528
        Q_STATIC_ASSERT_X(sizeof(T), "Type argument of Q_DECLARE_METATYPE(T*) must be fully defined");
1529
        enum { Value = sizeof(checkType(static_cast<T*>(nullptr))) == sizeof(yes_type) };
1530
    };
1531
1532
    template<typename T, typename Enable = void>
1533
    struct IsGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; };
1534
1535
    template<typename T>
1536
    struct IsGadgetHelper<T, typename T::QtGadgetHelper>
1537
    {
1538
        template <typename X>
1539
        static char checkType(void (X::*)());
1540
        static void *checkType(void (T::*)());
1541
        enum {
1542
            IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *),
1543
            IsGadgetOrDerivedFrom = true
1544
        };
1545
    };
1546
1547
    template<typename T, typename Enable = void>
1548
    struct IsPointerToGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; };
1549
1550
    template<typename T>
1551
    struct IsPointerToGadgetHelper<T*, typename T::QtGadgetHelper>
1552
    {
1553
        using BaseType = T;
1554
        template <typename X>
1555
        static char checkType(void (X::*)());
1556
        static void *checkType(void (T::*)());
1557
        enum {
1558
            IsRealGadget = !IsPointerToTypeDerivedFromQObject<T*>::Value && sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *),
1559
            IsGadgetOrDerivedFrom = !IsPointerToTypeDerivedFromQObject<T*>::Value
1560
        };
1561
    };
1562
1563
1564
    template<typename T> char qt_getEnumMetaObject(const T&);
1565
1566
    template<typename T>
1567
    struct IsQEnumHelper {
1568
        static const T &declval();
1569
        // If the type was declared with Q_ENUM, the friend qt_getEnumMetaObject() declared in the
1570
        // Q_ENUM macro will be chosen by ADL, and the return type will be QMetaObject*.
1571
        // Otherwise the chosen overload will be the catch all template function
1572
        // qt_getEnumMetaObject(T) which returns 'char'
1573
        enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) };
1574
    };
1575
    template<> struct IsQEnumHelper<void> { enum { Value = false }; };
1576
1577
    template<typename T, typename Enable = void>
1578
    struct MetaObjectForType
1579
    {
1580
0
        static inline const QMetaObject *value() { return nullptr; }
Unexecuted instantiation: QtPrivate::MetaObjectForType<QtMetaTypePrivate::QAssociativeIterableImpl, void>::value()
Unexecuted instantiation: QtPrivate::MetaObjectForType<QtMetaTypePrivate::QPairVariantInterfaceImpl, void>::value()
Unexecuted instantiation: QtPrivate::MetaObjectForType<QPair<QVariant, QVariant>, void>::value()
1581
    };
1582
    template<>
1583
    struct MetaObjectForType<void>
1584
    {
1585
        static inline const QMetaObject *value() { return nullptr; }
1586
    };
1587
    template<typename T>
1588
    struct MetaObjectForType<T*, typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value>::type>
1589
    {
1590
        static inline const QMetaObject *value() { return &T::staticMetaObject; }
1591
    };
1592
    template<typename T>
1593
    struct MetaObjectForType<T, typename std::enable_if<IsGadgetHelper<T>::IsGadgetOrDerivedFrom>::type>
1594
    {
1595
        static inline const QMetaObject *value() { return &T::staticMetaObject; }
1596
    };
1597
    template<typename T>
1598
    struct MetaObjectForType<T, typename std::enable_if<IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom>::type>
1599
    {
1600
        static inline const QMetaObject *value() { return &IsPointerToGadgetHelper<T>::BaseType::staticMetaObject; }
1601
    };
1602
    template<typename T>
1603
    struct MetaObjectForType<T, typename std::enable_if<IsQEnumHelper<T>::Value>::type >
1604
    {
1605
        static inline const QMetaObject *value() { return qt_getEnumMetaObject(T()); }
1606
    };
1607
1608
    template<typename T>
1609
    struct IsSharedPointerToTypeDerivedFromQObject
1610
    {
1611
        enum { Value = false };
1612
    };
1613
1614
    template<typename T>
1615
    struct IsSharedPointerToTypeDerivedFromQObject<QSharedPointer<T> > : IsPointerToTypeDerivedFromQObject<T*>
1616
    {
1617
    };
1618
1619
    template<typename T>
1620
    struct IsWeakPointerToTypeDerivedFromQObject
1621
    {
1622
        enum { Value = false };
1623
    };
1624
1625
    template<typename T>
1626
    struct IsWeakPointerToTypeDerivedFromQObject<QWeakPointer<T> > : IsPointerToTypeDerivedFromQObject<T*>
1627
    {
1628
    };
1629
1630
    template<typename T>
1631
    struct IsTrackingPointerToTypeDerivedFromQObject
1632
    {
1633
        enum { Value = false };
1634
    };
1635
1636
    template<typename T>
1637
    struct IsTrackingPointerToTypeDerivedFromQObject<QPointer<T> >
1638
    {
1639
        enum { Value = true };
1640
    };
1641
1642
    template<typename T>
1643
    struct IsSequentialContainer
1644
    {
1645
        enum { Value = false };
1646
    };
1647
1648
    template<typename T>
1649
    struct IsAssociativeContainer
1650
    {
1651
        enum { Value = false };
1652
    };
1653
1654
    template<typename T, bool = QtPrivate::IsSequentialContainer<T>::Value>
1655
    struct SequentialContainerConverterHelper
1656
    {
1657
        static bool registerConverter(int)
1658
0
        {
1659
0
            return false;
1660
0
        }
Unexecuted instantiation: QtPrivate::SequentialContainerConverterHelper<QtMetaTypePrivate::QAssociativeIterableImpl, false>::registerConverter(int)
Unexecuted instantiation: QtPrivate::SequentialContainerConverterHelper<QtMetaTypePrivate::QPairVariantInterfaceImpl, false>::registerConverter(int)
Unexecuted instantiation: QtPrivate::SequentialContainerConverterHelper<QPair<QVariant, QVariant>, false>::registerConverter(int)
1661
    };
1662
1663
    template<typename T, bool = QMetaTypeId2<typename T::value_type>::Defined>
1664
    struct ValueTypeIsMetaType
1665
    {
1666
        static bool registerConverter(int)
1667
        {
1668
            return false;
1669
        }
1670
    };
1671
1672
    template<typename T>
1673
    struct SequentialContainerConverterHelper<T, true> : ValueTypeIsMetaType<T>
1674
    {
1675
    };
1676
1677
    template<typename T, bool = QtPrivate::IsAssociativeContainer<T>::Value>
1678
    struct AssociativeContainerConverterHelper
1679
    {
1680
        static bool registerConverter(int)
1681
0
        {
1682
0
            return false;
1683
0
        }
Unexecuted instantiation: QtPrivate::AssociativeContainerConverterHelper<QtMetaTypePrivate::QAssociativeIterableImpl, false>::registerConverter(int)
Unexecuted instantiation: QtPrivate::AssociativeContainerConverterHelper<QtMetaTypePrivate::QPairVariantInterfaceImpl, false>::registerConverter(int)
Unexecuted instantiation: QtPrivate::AssociativeContainerConverterHelper<QPair<QVariant, QVariant>, false>::registerConverter(int)
1684
    };
1685
1686
    template<typename T, bool = QMetaTypeId2<typename T::mapped_type>::Defined>
1687
    struct AssociativeValueTypeIsMetaType
1688
    {
1689
        static bool registerConverter(int)
1690
        {
1691
            return false;
1692
        }
1693
    };
1694
1695
    template<typename T, bool = QMetaTypeId2<typename T::key_type>::Defined>
1696
    struct KeyAndValueTypeIsMetaType
1697
    {
1698
        static bool registerConverter(int)
1699
        {
1700
            return false;
1701
        }
1702
    };
1703
1704
    template<typename T>
1705
    struct KeyAndValueTypeIsMetaType<T, true> : AssociativeValueTypeIsMetaType<T>
1706
    {
1707
    };
1708
1709
    template<typename T>
1710
    struct AssociativeContainerConverterHelper<T, true> : KeyAndValueTypeIsMetaType<T>
1711
    {
1712
    };
1713
1714
    template<typename T, bool = QMetaTypeId2<typename T::first_type>::Defined
1715
                                && QMetaTypeId2<typename T::second_type>::Defined>
1716
    struct IsMetaTypePair
1717
    {
1718
        static bool registerConverter(int)
1719
        {
1720
            return false;
1721
        }
1722
    };
1723
1724
    template<typename T>
1725
    struct IsMetaTypePair<T, true>
1726
    {
1727
        inline static bool registerConverter(int id);
1728
    };
1729
1730
    template<typename T>
1731
    struct IsPair
1732
    {
1733
        static bool registerConverter(int)
1734
0
        {
1735
0
            return false;
1736
0
        }
Unexecuted instantiation: QtPrivate::IsPair<QtMetaTypePrivate::QAssociativeIterableImpl>::registerConverter(int)
Unexecuted instantiation: QtPrivate::IsPair<QtMetaTypePrivate::QPairVariantInterfaceImpl>::registerConverter(int)
1737
    };
1738
    template<typename T, typename U>
1739
    struct IsPair<QPair<T, U> > : IsMetaTypePair<QPair<T, U> > {};
1740
    template<typename T, typename U>
1741
    struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {};
1742
1743
    template<typename T>
1744
    struct MetaTypePairHelper : IsPair<T> {};
1745
1746
    template<typename T, typename = void>
1747
    struct MetaTypeSmartPointerHelper
1748
    {
1749
0
        static bool registerConverter(int) { return false; }
Unexecuted instantiation: QtPrivate::MetaTypeSmartPointerHelper<QtMetaTypePrivate::QAssociativeIterableImpl, void>::registerConverter(int)
Unexecuted instantiation: QtPrivate::MetaTypeSmartPointerHelper<QtMetaTypePrivate::QPairVariantInterfaceImpl, void>::registerConverter(int)
Unexecuted instantiation: QtPrivate::MetaTypeSmartPointerHelper<QPair<QVariant, QVariant>, void>::registerConverter(int)
1750
    };
1751
1752
    Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
1753
} // namespace QtPrivate
1754
1755
template <typename T, int =
1756
    QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject :
1757
    QtPrivate::IsGadgetHelper<T>::IsRealGadget             ? QMetaType::IsGadget :
1758
    QtPrivate::IsPointerToGadgetHelper<T>::IsRealGadget    ? QMetaType::PointerToGadget :
1759
    QtPrivate::IsQEnumHelper<T>::Value                     ? QMetaType::IsEnumeration : 0>
1760
struct QMetaTypeIdQObject
1761
{
1762
    enum {
1763
        Defined = 0
1764
    };
1765
};
1766
1767
template <typename T>
1768
struct QMetaTypeId : public QMetaTypeIdQObject<T>
1769
{
1770
};
1771
1772
template <typename T>
1773
struct QMetaTypeId2
1774
{
1775
    enum { Defined = QMetaTypeId<T>::Defined, IsBuiltIn=false };
1776
0
    static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
Unexecuted instantiation: QMetaTypeId2<QtMetaTypePrivate::QPairVariantInterfaceImpl>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QtMetaTypePrivate::QAssociativeIterableImpl>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QPair<QVariant, QVariant> >::qt_metatype_id()
1777
};
1778
1779
template <typename T>
1780
struct QMetaTypeId2<const T&> : QMetaTypeId2<T> {};
1781
1782
template <typename T>
1783
struct QMetaTypeId2<T&> { enum {Defined = false }; };
1784
1785
namespace QtPrivate {
1786
    template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
1787
    struct QMetaTypeIdHelper {
1788
        static inline Q_DECL_CONSTEXPR int qt_metatype_id()
1789
0
        { return QMetaTypeId2<T>::qt_metatype_id(); }
Unexecuted instantiation: QtPrivate::QMetaTypeIdHelper<QtMetaTypePrivate::QAssociativeIterableImpl, true>::qt_metatype_id()
Unexecuted instantiation: QtPrivate::QMetaTypeIdHelper<QtMetaTypePrivate::QPairVariantInterfaceImpl, true>::qt_metatype_id()
Unexecuted instantiation: QtPrivate::QMetaTypeIdHelper<QPair<QVariant, QVariant>, true>::qt_metatype_id()
1790
    };
1791
    template <typename T> struct QMetaTypeIdHelper<T, false> {
1792
        static inline Q_DECL_CONSTEXPR int qt_metatype_id()
1793
        { return -1; }
1794
    };
1795
1796
    // Function pointers don't derive from QObject
1797
    template <typename Result, typename... Args>
1798
    struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; };
1799
1800
    template<typename T>
1801
    struct QMetaTypeTypeFlags
1802
    {
1803
        enum { Flags = (QTypeInfoQuery<T>::isRelocatable ? QMetaType::MovableType : 0)
1804
                     | (QTypeInfo<T>::isComplex ? QMetaType::NeedsConstruction : 0)
1805
                     | (QTypeInfo<T>::isComplex ? QMetaType::NeedsDestruction : 0)
1806
                     | (IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : 0)
1807
                     | (IsSharedPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::SharedPointerToQObject : 0)
1808
                     | (IsWeakPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::WeakPointerToQObject : 0)
1809
                     | (IsTrackingPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::TrackingPointerToQObject : 0)
1810
                     | (std::is_enum<T>::value ? QMetaType::IsEnumeration : 0)
1811
                     | (IsGadgetHelper<T>::IsGadgetOrDerivedFrom ? QMetaType::IsGadget : 0)
1812
                     | (IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom ? QMetaType::PointerToGadget : 0)
1813
             };
1814
    };
1815
1816
    template<typename T, bool defined>
1817
    struct MetaTypeDefinedHelper
1818
    {
1819
        enum DefinedType { Defined = defined };
1820
    };
1821
1822
    template<typename SmartPointer>
1823
    struct QSmartPointerConvertFunctor
1824
    {
1825
        QObject* operator()(const SmartPointer &p) const
1826
        {
1827
            return p.operator->();
1828
        }
1829
    };
1830
1831
    // hack to delay name lookup to instantiation time by making
1832
    // EnableInternalData a dependent name:
1833
    template <typename T>
1834
    struct EnableInternalDataWrap;
1835
1836
    template<typename T>
1837
    struct QSmartPointerConvertFunctor<QWeakPointer<T> >
1838
    {
1839
        QObject* operator()(const QWeakPointer<T> &p) const
1840
        {
1841
            return QtPrivate::EnableInternalDataWrap<T>::internalData(p);
1842
        }
1843
    };
1844
}
1845
1846
template <typename T>
1847
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName
1848
#ifndef Q_CLANG_QDOC
1849
    , T * dummy = 0
1850
    , typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
1851
#endif
1852
)
1853
0
{
1854
0
#ifndef QT_NO_QOBJECT
1855
0
    Q_ASSERT_X(normalizedTypeName == QMetaObject::normalizedType(normalizedTypeName.constData()), "qRegisterNormalizedMetaType", "qRegisterNormalizedMetaType was called with a not normalized type name, please call qRegisterMetaType instead.");
1856
0
#endif
1857
0
    const int typedefOf = dummy ? -1 : QtPrivate::QMetaTypeIdHelper<T>::qt_metatype_id();
1858
0
    if (typedefOf != -1)
1859
0
        return QMetaType::registerNormalizedTypedef(normalizedTypeName, typedefOf);
1860
0
1861
0
    QMetaType::TypeFlags flags(QtPrivate::QMetaTypeTypeFlags<T>::Flags);
1862
0
1863
0
    if (defined)
1864
0
        flags |= QMetaType::WasDeclaredAsMetaType;
1865
0
1866
0
    const int id = QMetaType::registerNormalizedType(normalizedTypeName,
1867
0
                                   QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct,
1868
0
                                   QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct,
1869
0
                                   int(sizeof(T)),
1870
0
                                   flags,
1871
0
                                   QtPrivate::MetaObjectForType<T>::value());
1872
0
1873
0
    if (id > 0) {
1874
0
        QtPrivate::SequentialContainerConverterHelper<T>::registerConverter(id);
1875
0
        QtPrivate::AssociativeContainerConverterHelper<T>::registerConverter(id);
1876
0
        QtPrivate::MetaTypePairHelper<T>::registerConverter(id);
1877
0
        QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter(id);
1878
0
    }
1879
0
1880
0
    return id;
1881
0
}
Unexecuted instantiation: _Z27qRegisterNormalizedMetaTypeIN17QtMetaTypePrivate24QAssociativeIterableImplEEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS5_Xaasr12QMetaTypeId2IS5_EE7Definedntsr12QMetaTypeId2IS5_EE9IsBuiltInEE11DefinedTypeE
Unexecuted instantiation: _Z27qRegisterNormalizedMetaTypeIN17QtMetaTypePrivate25QPairVariantInterfaceImplEEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS5_Xaasr12QMetaTypeId2IS5_EE7Definedntsr12QMetaTypeId2IS5_EE9IsBuiltInEE11DefinedTypeE
Unexecuted instantiation: _Z27qRegisterNormalizedMetaTypeI5QPairI8QVariantS1_EEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS6_Xaasr12QMetaTypeId2IS6_EE7Definedntsr12QMetaTypeId2IS6_EE9IsBuiltInEE11DefinedTypeE
1882
1883
template <typename T>
1884
int qRegisterMetaType(const char *typeName
1885
#ifndef Q_CLANG_QDOC
1886
    , T * dummy = nullptr
1887
    , typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
1888
#endif
1889
)
1890
0
{
1891
0
#ifdef QT_NO_QOBJECT
1892
0
    QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = typeName;
1893
0
#else
1894
0
    QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
1895
0
#endif
1896
0
    return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy, defined);
1897
0
}
Unexecuted instantiation: _Z17qRegisterMetaTypeIN17QtMetaTypePrivate24QAssociativeIterableImplEEiPKcPT_N9QtPrivate21MetaTypeDefinedHelperIS4_Xaasr12QMetaTypeId2IS4_EE7Definedntsr12QMetaTypeId2IS4_EE9IsBuiltInEE11DefinedTypeE
Unexecuted instantiation: _Z17qRegisterMetaTypeIN17QtMetaTypePrivate25QPairVariantInterfaceImplEEiPKcPT_N9QtPrivate21MetaTypeDefinedHelperIS4_Xaasr12QMetaTypeId2IS4_EE7Definedntsr12QMetaTypeId2IS4_EE9IsBuiltInEE11DefinedTypeE
1898
1899
#ifndef QT_NO_DATASTREAM
1900
template <typename T>
1901
void qRegisterMetaTypeStreamOperators(const char *typeName
1902
#ifndef Q_CLANG_QDOC
1903
    , T * /* dummy */ = nullptr
1904
#endif
1905
)
1906
{
1907
    qRegisterMetaType<T>(typeName);
1908
    QMetaType::registerStreamOperators(typeName, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Save,
1909
                                                 QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Load);
1910
}
1911
#endif // QT_NO_DATASTREAM
1912
1913
template <typename T>
1914
inline Q_DECL_CONSTEXPR int qMetaTypeId()
1915
0
{
1916
0
    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");
1917
0
    return QMetaTypeId2<T>::qt_metatype_id();
1918
0
}
Unexecuted instantiation: int qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>()
Unexecuted instantiation: int qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()
Unexecuted instantiation: int qMetaTypeId<QPair<QVariant, QVariant> >()
Unexecuted instantiation: int qMetaTypeId<QVariant>()
Unexecuted instantiation: int qMetaTypeId<QString>()
Unexecuted instantiation: int qMetaTypeId<QObject*>()
Unexecuted instantiation: int qMetaTypeId<QDate>()
Unexecuted instantiation: int qMetaTypeId<QTime>()
Unexecuted instantiation: int qMetaTypeId<QDateTime>()
Unexecuted instantiation: int qMetaTypeId<QEasingCurve>()
Unexecuted instantiation: int qMetaTypeId<QSizeF>()
Unexecuted instantiation: int qMetaTypeId<QRectF>()
Unexecuted instantiation: int qMetaTypeId<QLineF>()
Unexecuted instantiation: int qMetaTypeId<QLine>()
Unexecuted instantiation: int qMetaTypeId<QPointF>()
Unexecuted instantiation: int qMetaTypeId<QUrl>()
Unexecuted instantiation: int qMetaTypeId<QLocale>()
Unexecuted instantiation: int qMetaTypeId<QRegExp>()
Unexecuted instantiation: int qMetaTypeId<QRegularExpression>()
Unexecuted instantiation: int qMetaTypeId<QPersistentModelIndex>()
Unexecuted instantiation: int qMetaTypeId<QUuid>()
Unexecuted instantiation: int qMetaTypeId<QJsonValue>()
Unexecuted instantiation: int qMetaTypeId<QJsonObject>()
Unexecuted instantiation: int qMetaTypeId<QJsonArray>()
Unexecuted instantiation: int qMetaTypeId<QJsonDocument>()
Unexecuted instantiation: int qMetaTypeId<QChar>()
Unexecuted instantiation: int qMetaTypeId<QBitArray>()
Unexecuted instantiation: int qMetaTypeId<unsigned int>()
Unexecuted instantiation: int qMetaTypeId<long long>()
Unexecuted instantiation: int qMetaTypeId<unsigned long long>()
Unexecuted instantiation: int qMetaTypeId<double>()
Unexecuted instantiation: int qMetaTypeId<float>()
1919
1920
template <typename T>
1921
inline Q_DECL_CONSTEXPR int qRegisterMetaType()
1922
{
1923
    return qMetaTypeId<T>();
1924
}
1925
1926
#if QT_DEPRECATED_SINCE(5, 1) && !defined(Q_CLANG_QDOC)
1927
// There used to be a T *dummy = 0 argument in Qt 4.0 to support MSVC6
1928
template <typename T>
1929
QT_DEPRECATED inline Q_DECL_CONSTEXPR int qMetaTypeId(T *)
1930
{ return qMetaTypeId<T>(); }
1931
#ifndef Q_CC_SUN
1932
template <typename T>
1933
QT_DEPRECATED inline Q_DECL_CONSTEXPR int qRegisterMetaType(T *)
1934
{ return qRegisterMetaType<T>(); }
1935
#endif
1936
#endif
1937
1938
#ifndef QT_NO_QOBJECT
1939
template <typename T>
1940
struct QMetaTypeIdQObject<T*, QMetaType::PointerToQObject>
1941
{
1942
    enum {
1943
        Defined = 1
1944
    };
1945
1946
    static int qt_metatype_id()
1947
    {
1948
        static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1949
        if (const int id = metatype_id.loadAcquire())
1950
            return id;
1951
        const char * const cName = T::staticMetaObject.className();
1952
        QByteArray typeName;
1953
        typeName.reserve(int(strlen(cName)) + 1);
1954
        typeName.append(cName).append('*');
1955
        const int newId = qRegisterNormalizedMetaType<T*>(
1956
                        typeName,
1957
                        reinterpret_cast<T**>(quintptr(-1)));
1958
        metatype_id.storeRelease(newId);
1959
        return newId;
1960
    }
1961
};
1962
1963
template <typename T>
1964
struct QMetaTypeIdQObject<T, QMetaType::IsGadget>
1965
{
1966
    enum {
1967
        Defined = std::is_default_constructible<T>::value
1968
    };
1969
1970
    static int qt_metatype_id()
1971
    {
1972
        static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1973
        if (const int id = metatype_id.loadAcquire())
1974
            return id;
1975
        const char * const cName = T::staticMetaObject.className();
1976
        const int newId = qRegisterNormalizedMetaType<T>(
1977
            cName,
1978
            reinterpret_cast<T*>(quintptr(-1)));
1979
        metatype_id.storeRelease(newId);
1980
        return newId;
1981
    }
1982
};
1983
1984
template <typename T>
1985
struct QMetaTypeIdQObject<T*, QMetaType::PointerToGadget>
1986
{
1987
    enum {
1988
        Defined = 1
1989
    };
1990
1991
    static int qt_metatype_id()
1992
    {
1993
        static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1994
        if (const int id = metatype_id.loadAcquire())
1995
            return id;
1996
        const char * const cName = T::staticMetaObject.className();
1997
        QByteArray typeName;
1998
        typeName.reserve(int(strlen(cName)) + 1);
1999
        typeName.append(cName).append('*');
2000
        const int newId = qRegisterNormalizedMetaType<T*>(
2001
            typeName,
2002
            reinterpret_cast<T**>(quintptr(-1)));
2003
        metatype_id.storeRelease(newId);
2004
        return newId;
2005
    }
2006
};
2007
2008
template <typename T>
2009
struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration>
2010
{
2011
    enum {
2012
        Defined = 1
2013
    };
2014
2015
    static int qt_metatype_id()
2016
    {
2017
        static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
2018
        if (const int id = metatype_id.loadAcquire())
2019
            return id;
2020
        const char *eName = qt_getEnumName(T());
2021
        const char *cName = qt_getEnumMetaObject(T())->className();
2022
        QByteArray typeName;
2023
        typeName.reserve(int(strlen(cName) + 2 + strlen(eName)));
2024
        typeName.append(cName).append("::").append(eName);
2025
        const int newId = qRegisterNormalizedMetaType<T>(
2026
            typeName,
2027
            reinterpret_cast<T*>(quintptr(-1)));
2028
        metatype_id.storeRelease(newId);
2029
        return newId;
2030
    }
2031
};
2032
#endif
2033
2034
#ifndef QT_NO_DATASTREAM
2035
template <typename T>
2036
inline int qRegisterMetaTypeStreamOperators()
2037
{
2038
    int id = qMetaTypeId<T>();
2039
    QMetaType::registerStreamOperators(id, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Save,
2040
                                           QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Load);
2041
    return id;
2042
}
2043
#endif
2044
2045
#define Q_DECLARE_OPAQUE_POINTER(POINTER)                               \
2046
    QT_BEGIN_NAMESPACE namespace QtPrivate {                            \
2047
        template <>                                                     \
2048
        struct IsPointerToTypeDerivedFromQObject<POINTER >              \
2049
        {                                                               \
2050
            enum { Value = false };                                     \
2051
        };                                                              \
2052
    } QT_END_NAMESPACE                                                  \
2053
    /**/
2054
2055
#ifndef Q_MOC_RUN
2056
#define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
2057
#define Q_DECLARE_METATYPE_IMPL(TYPE)                                   \
2058
    QT_BEGIN_NAMESPACE                                                  \
2059
    template <>                                                         \
2060
    struct QMetaTypeId< TYPE >                                          \
2061
    {                                                                   \
2062
        enum { Defined = 1 };                                           \
2063
        static int qt_metatype_id()                                     \
2064
0
            {                                                           \
2065
0
                static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
2066
0
                if (const int id = metatype_id.loadAcquire())           \
2067
0
                    return id;                                          \
2068
0
                const int newId = qRegisterMetaType< TYPE >(#TYPE,      \
2069
0
                              reinterpret_cast< TYPE *>(quintptr(-1))); \
2070
0
                metatype_id.storeRelease(newId);                        \
2071
0
                return newId;                                           \
2072
0
            }                                                           \
Unexecuted instantiation: QMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>::qt_metatype_id()
2073
    };                                                                  \
2074
    QT_END_NAMESPACE
2075
#endif // Q_MOC_RUN
2076
2077
#define Q_DECLARE_BUILTIN_METATYPE(TYPE, METATYPEID, NAME) \
2078
    QT_BEGIN_NAMESPACE \
2079
    template<> struct QMetaTypeId2<NAME> \
2080
    { \
2081
        enum { Defined = 1, IsBuiltIn = true, MetaType = METATYPEID };   \
2082
0
        static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return METATYPEID; } \
Unexecuted instantiation: QMetaTypeId2<void>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<bool>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<unsigned int>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<long long>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<unsigned long long>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<double>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<long>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<short>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<char>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<unsigned long>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<unsigned short>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<unsigned char>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<float>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<signed char>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<void*>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QChar>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QString>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QByteArray>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QBitArray>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QDate>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QTime>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QDateTime>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QUrl>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QLocale>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QRect>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QRectF>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QSize>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QSizeF>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QLine>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QLineF>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QPoint>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QPointF>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QRegExp>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QEasingCurve>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QUuid>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QVariant>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QRegularExpression>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QJsonValue>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QJsonObject>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QJsonArray>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QJsonDocument>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QCborValue>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QCborArray>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QCborMap>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QModelIndex>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QPersistentModelIndex>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QObject*>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QMap<QString, QVariant> >::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QList<QVariant> >::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QHash<QString, QVariant> >::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QList<QByteArray> >::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QFont>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QPixmap>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QBrush>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QColor>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QPalette>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QIcon>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QImage>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QPolygon>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QRegion>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QBitmap>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QCursor>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QKeySequence>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QPen>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QTextLength>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QTextFormat>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QMatrix>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QTransform>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QMatrix4x4>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QVector2D>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QVector3D>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QVector4D>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QQuaternion>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QPolygonF>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QColorSpace>::qt_metatype_id()
Unexecuted instantiation: QMetaTypeId2<QSizePolicy>::qt_metatype_id()
2083
    }; \
2084
    QT_END_NAMESPACE
2085
2086
#define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \
2087
    class Name;
2088
2089
QT_FOR_EACH_STATIC_CORE_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
2090
QT_FOR_EACH_STATIC_GUI_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
2091
QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
2092
2093
#undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER
2094
2095
typedef QList<QVariant> QVariantList;
2096
typedef QMap<QString, QVariant> QVariantMap;
2097
typedef QHash<QString, QVariant> QVariantHash;
2098
#ifdef Q_CLANG_QDOC
2099
class QByteArrayList;
2100
#else
2101
typedef QList<QByteArray> QByteArrayList;
2102
#endif
2103
2104
#define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
2105
QT_BEGIN_NAMESPACE \
2106
template <typename T> \
2107
struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
2108
{ \
2109
    enum { \
2110
        Defined = QMetaTypeId2<T>::Defined \
2111
    }; \
2112
    static int qt_metatype_id() \
2113
    { \
2114
        static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
2115
        if (const int id = metatype_id.loadRelaxed()) \
2116
            return id; \
2117
        const char *tName = QMetaType::typeName(qMetaTypeId<T>()); \
2118
        Q_ASSERT(tName); \
2119
        const int tNameLen = int(qstrlen(tName)); \
2120
        QByteArray typeName; \
2121
        typeName.reserve(int(sizeof(#SINGLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + 1); \
2122
        typeName.append(#SINGLE_ARG_TEMPLATE, int(sizeof(#SINGLE_ARG_TEMPLATE)) - 1) \
2123
            .append('<').append(tName, tNameLen); \
2124
        if (typeName.endsWith('>')) \
2125
            typeName.append(' '); \
2126
        typeName.append('>'); \
2127
        const int newId = qRegisterNormalizedMetaType< SINGLE_ARG_TEMPLATE<T> >( \
2128
                        typeName, \
2129
                        reinterpret_cast< SINGLE_ARG_TEMPLATE<T> *>(quintptr(-1))); \
2130
        metatype_id.storeRelease(newId); \
2131
        return newId; \
2132
    } \
2133
}; \
2134
namespace QtPrivate { \
2135
template<typename T> \
2136
struct IsSequentialContainer<SINGLE_ARG_TEMPLATE<T> > \
2137
{ \
2138
    enum { Value = true }; \
2139
}; \
2140
} \
2141
QT_END_NAMESPACE
2142
2143
#define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
2144
QT_BEGIN_NAMESPACE \
2145
template<typename T, typename U> \
2146
struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
2147
{ \
2148
    enum { \
2149
        Defined = QMetaTypeId2<T>::Defined && QMetaTypeId2<U>::Defined \
2150
    }; \
2151
    static int qt_metatype_id() \
2152
0
    { \
2153
0
        static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
2154
0
        if (const int id = metatype_id.loadAcquire()) \
2155
0
            return id; \
2156
0
        const char *tName = QMetaType::typeName(qMetaTypeId<T>()); \
2157
0
        const char *uName = QMetaType::typeName(qMetaTypeId<U>()); \
2158
0
        Q_ASSERT(tName); \
2159
0
        Q_ASSERT(uName); \
2160
0
        const int tNameLen = int(qstrlen(tName)); \
2161
0
        const int uNameLen = int(qstrlen(uName)); \
2162
0
        QByteArray typeName; \
2163
0
        typeName.reserve(int(sizeof(#DOUBLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \
2164
0
        typeName.append(#DOUBLE_ARG_TEMPLATE, int(sizeof(#DOUBLE_ARG_TEMPLATE)) - 1) \
2165
0
            .append('<').append(tName, tNameLen).append(',').append(uName, uNameLen); \
2166
0
        if (typeName.endsWith('>')) \
2167
0
            typeName.append(' '); \
2168
0
        typeName.append('>'); \
2169
0
        const int newId = qRegisterNormalizedMetaType< DOUBLE_ARG_TEMPLATE<T, U> >(\
2170
0
                        typeName, \
2171
0
                        reinterpret_cast< DOUBLE_ARG_TEMPLATE<T, U> *>(quintptr(-1))); \
2172
0
        metatype_id.storeRelease(newId); \
2173
0
        return newId; \
2174
0
    } \
2175
}; \
2176
QT_END_NAMESPACE
2177
2178
namespace QtPrivate {
2179
2180
template<typename T, bool /* isSharedPointerToQObjectDerived */ = false>
2181
struct SharedPointerMetaTypeIdHelper
2182
{
2183
    enum {
2184
        Defined = 0
2185
    };
2186
    static int qt_metatype_id()
2187
    {
2188
        return -1;
2189
    }
2190
};
2191
2192
}
2193
2194
#define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \
2195
QT_BEGIN_NAMESPACE \
2196
namespace QtPrivate { \
2197
template<typename T> \
2198
struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
2199
{ \
2200
    enum { \
2201
        Defined = 1 \
2202
    }; \
2203
    static int qt_metatype_id() \
2204
    { \
2205
        static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
2206
        if (const int id = metatype_id.loadAcquire()) \
2207
            return id; \
2208
        const char * const cName = T::staticMetaObject.className(); \
2209
        QByteArray typeName; \
2210
        typeName.reserve(int(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1)); \
2211
        typeName.append(#SMART_POINTER, int(sizeof(#SMART_POINTER)) - 1) \
2212
            .append('<').append(cName).append('>'); \
2213
        const int newId = qRegisterNormalizedMetaType< SMART_POINTER<T> >( \
2214
                        typeName, \
2215
                        reinterpret_cast< SMART_POINTER<T> *>(quintptr(-1))); \
2216
        metatype_id.storeRelease(newId); \
2217
        return newId; \
2218
    } \
2219
}; \
2220
template<typename T> \
2221
struct MetaTypeSmartPointerHelper<SMART_POINTER<T> , \
2222
        typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value>::type> \
2223
{ \
2224
    static bool registerConverter(int id) \
2225
    { \
2226
        const int toId = QMetaType::QObjectStar; \
2227
        if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { \
2228
            QtPrivate::QSmartPointerConvertFunctor<SMART_POINTER<T> > o; \
2229
            static const QtPrivate::ConverterFunctor<SMART_POINTER<T>, \
2230
                                    QObject*, \
2231
                                    QSmartPointerConvertFunctor<SMART_POINTER<T> > > f(o); \
2232
            return QMetaType::registerConverterFunction(&f, id, toId); \
2233
        } \
2234
        return true; \
2235
    } \
2236
}; \
2237
} \
2238
template <typename T> \
2239
struct QMetaTypeId< SMART_POINTER<T> > \
2240
    : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \
2241
                                                QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
2242
{ \
2243
};\
2244
QT_END_NAMESPACE
2245
2246
#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME) \
2247
    QT_BEGIN_NAMESPACE \
2248
    template <class T> class TEMPLATENAME; \
2249
    QT_END_NAMESPACE \
2250
    Q_DECLARE_METATYPE_TEMPLATE_1ARG(TEMPLATENAME)
2251
2252
QT_END_NAMESPACE
2253
2254
QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER)
2255
2256
#undef Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER
2257
2258
#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE Q_DECLARE_METATYPE_TEMPLATE_1ARG
2259
2260
Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::vector)
2261
Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::list)
2262
2263
#define Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \
2264
    QT_BEGIN_NAMESPACE \
2265
    template <class T1, class T2> CPPTYPE TEMPLATENAME; \
2266
    QT_END_NAMESPACE \
2267
2268
QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_FORWARD_DECLARE_METATYPE_TEMPLATE_2ARG_ITER)
2269
2270
#undef Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER
2271
2272
#define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME) \
2273
    QT_BEGIN_NAMESPACE \
2274
    namespace QtPrivate { \
2275
    template<typename T, typename U> \
2276
    struct IsAssociativeContainer<TEMPLATENAME<T, U> > \
2277
    { \
2278
        enum { Value = true }; \
2279
    }; \
2280
    } \
2281
    QT_END_NAMESPACE \
2282
    Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
2283
2284
Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QHash)
2285
Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMap)
2286
Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::map)
2287
2288
Q_DECLARE_METATYPE_TEMPLATE_2ARG(QPair)
2289
Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair)
2290
2291
#define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
2292
    Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
2293
2294
2295
QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER)
2296
2297
QT_BEGIN_NAMESPACE
2298
2299
#undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
2300
2301
inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
2302
                            TypedConstructor creator,
2303
                            TypedDestructor deleter,
2304
                            SaveOperator saveOp,
2305
                            LoadOperator loadOp,
2306
                            Constructor constructor,
2307
                            Destructor destructor,
2308
                            uint size,
2309
                            uint theTypeFlags,
2310
                            int typeId,
2311
                            const QMetaObject *_metaObject)
2312
    : m_typedConstructor(creator)
2313
    , m_typedDestructor(deleter)
2314
    , m_saveOp(saveOp)
2315
    , m_loadOp(loadOp)
2316
    , m_constructor(constructor)
2317
    , m_destructor(destructor)
2318
    , m_extension(nullptr)
2319
    , m_size(size)
2320
    , m_typeFlags(theTypeFlags)
2321
    , m_extensionFlags(extensionFlags)
2322
    , m_typeId(typeId)
2323
    , m_metaObject(_metaObject)
2324
{
2325
    if (Q_UNLIKELY(isExtended(CtorEx) || typeId == QMetaType::Void))
2326
        ctor(info);
2327
}
2328
2329
inline QMetaType::~QMetaType()
2330
{
2331
    if (Q_UNLIKELY(isExtended(DtorEx)))
2332
        dtor();
2333
}
2334
2335
inline bool QMetaType::isValid() const
2336
0
{
2337
0
    return m_typeId != UnknownType;
2338
0
}
2339
2340
inline bool QMetaType::isRegistered() const
2341
0
{
2342
0
    return isValid();
2343
0
}
2344
2345
inline int QMetaType::id() const
2346
0
{
2347
0
    return m_typeId;
2348
0
}
2349
2350
inline void *QMetaType::create(const void *copy) const
2351
0
{
2352
0
    // ### TODO Qt6 remove the extension
2353
0
    return createExtended(copy);
2354
0
}
2355
2356
inline void QMetaType::destroy(void *data) const
2357
0
{
2358
0
    // ### TODO Qt6 remove the extension
2359
0
    destroyExtended(data);
2360
0
}
2361
2362
inline void *QMetaType::construct(void *where, const void *copy) const
2363
{
2364
    if (Q_UNLIKELY(isExtended(ConstructEx)))
2365
        return constructExtended(where, copy);
2366
    return m_constructor(where, copy);
2367
}
2368
2369
inline void QMetaType::destruct(void *data) const
2370
{
2371
    if (Q_UNLIKELY(isExtended(DestructEx)))
2372
        return destructExtended(data);
2373
    if (Q_UNLIKELY(!data))
2374
        return;
2375
    m_destructor(data);
2376
}
2377
2378
inline int QMetaType::sizeOf() const
2379
{
2380
    if (Q_UNLIKELY(isExtended(SizeEx)))
2381
        return sizeExtended();
2382
    return m_size;
2383
}
2384
2385
inline QMetaType::TypeFlags QMetaType::flags() const
2386
0
{
2387
0
    if (Q_UNLIKELY(isExtended(FlagsEx)))
2388
0
        return flagsExtended();
2389
0
    return QMetaType::TypeFlags(m_typeFlags);
2390
0
}
2391
2392
inline const QMetaObject *QMetaType::metaObject() const
2393
0
{
2394
0
    if (Q_UNLIKELY(isExtended(MetaObjectEx)))
2395
0
        return metaObjectExtended();
2396
0
    return m_metaObject;
2397
0
}
2398
2399
QT_END_NAMESPACE
2400
2401
2402
QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
2403
2404
Q_DECLARE_METATYPE(QtMetaTypePrivate::QSequentialIterableImpl)
2405
Q_DECLARE_METATYPE(QtMetaTypePrivate::QAssociativeIterableImpl)
2406
Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl)
2407
2408
QT_BEGIN_NAMESPACE
2409
2410
template <typename T>
2411
inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter(int id)
2412
0
{
2413
0
    const int toId = qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
2414
0
    if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
2415
0
        QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
2416
0
        static const QtPrivate::ConverterFunctor<T,
2417
0
                                    QtMetaTypePrivate::QPairVariantInterfaceImpl,
2418
0
                                    QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> > f(o);
2419
0
        return QMetaType::registerConverterFunction(&f, id, toId);
2420
0
    }
2421
0
    return true;
2422
0
}
2423
2424
namespace QtPrivate {
2425
    template<typename T>
2426
    struct ValueTypeIsMetaType<T, true>
2427
    {
2428
        static bool registerConverter(int id)
2429
        {
2430
            const int toId = qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>();
2431
            if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
2432
                QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> o;
2433
                static const QtPrivate::ConverterFunctor<T,
2434
                        QtMetaTypePrivate::QSequentialIterableImpl,
2435
                QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> > f(o);
2436
                return QMetaType::registerConverterFunction(&f, id, toId);
2437
            }
2438
            return true;
2439
        }
2440
    };
2441
2442
    template<typename T>
2443
    struct AssociativeValueTypeIsMetaType<T, true>
2444
    {
2445
        static bool registerConverter(int id)
2446
        {
2447
            const int toId = qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>();
2448
            if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
2449
                QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> o;
2450
                static const QtPrivate::ConverterFunctor<T,
2451
                                            QtMetaTypePrivate::QAssociativeIterableImpl,
2452
                                            QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> > f(o);
2453
                return QMetaType::registerConverterFunction(&f, id, toId);
2454
            }
2455
            return true;
2456
        }
2457
    };
2458
}
2459
2460
QT_END_NAMESPACE
2461
2462
#endif // QMETATYPE_H