Coverage Report

Created: 2024-02-25 06:10

/src/qtbase/src/corelib/kernel/qvariant.cpp
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
**
3
** Copyright (C) 2020 The Qt Company Ltd.
4
** Copyright (C) 2018 Intel Corporation.
5
** Copyright (C) 2015 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
#include "qvariant.h"
43
#include "qbitarray.h"
44
#include "qbytearray.h"
45
#include "qdatastream.h"
46
#include "qdebug.h"
47
#include "qmap.h"
48
#include "qdatetime.h"
49
#if QT_CONFIG(easingcurve)
50
#include "qeasingcurve.h"
51
#endif
52
#include "qlist.h"
53
#if QT_CONFIG(regularexpression)
54
#include "qregularexpression.h"
55
#endif
56
#include "qstring.h"
57
#include "qstringlist.h"
58
#include "qurl.h"
59
#include "qlocale.h"
60
#include "qregexp.h"
61
#include "quuid.h"
62
#if QT_CONFIG(itemmodel)
63
#include "qabstractitemmodel.h"
64
#endif
65
#ifndef QT_BOOTSTRAPPED
66
#include "qcborarray.h"
67
#include "qcborcommon.h"
68
#include "qcbormap.h"
69
#include "qjsonvalue.h"
70
#include "qjsonobject.h"
71
#include "qjsonarray.h"
72
#include "qjsondocument.h"
73
#include "qbytearraylist.h"
74
#endif
75
#include "private/qvariant_p.h"
76
#include "private/qlocale_p.h"
77
#include "qmetatype_p.h"
78
#include <qmetaobject.h>
79
80
#ifndef QT_NO_GEOM_VARIANT
81
#include "qsize.h"
82
#include "qpoint.h"
83
#include "qrect.h"
84
#include "qline.h"
85
#endif
86
87
#include <cmath>
88
#include <float.h>
89
#include <cstring>
90
91
QT_BEGIN_NAMESPACE
92
93
namespace {
94
class HandlersManager
95
{
96
    static const QVariant::Handler *Handlers[QModulesPrivate::ModulesCount];
97
public:
98
    const QVariant::Handler *operator[] (const uint typeId) const
99
18
    {
100
18
        return Handlers[QModulesPrivate::moduleForType(typeId)];
101
18
    }
102
103
    void registerHandler(const QModulesPrivate::Names name, const QVariant::Handler *handler)
104
0
    {
105
0
        Handlers[name] = handler;
106
0
    }
107
};
108
}  // namespace
109
110
namespace {
111
struct CoreTypesFilter {
112
    template<typename T>
113
    struct Acceptor {
114
        static const bool IsAccepted = QModulesPrivate::QTypeModuleInfo<T>::IsCore && QtMetaTypePrivate::TypeDefinition<T>::IsAvailable;
115
    };
116
};
117
} // annonymous
118
119
namespace { // annonymous used to hide QVariant handlers
120
121
static void construct(QVariant::Private *x, const void *copy)
122
0
{
123
0
    QVariantConstructor<CoreTypesFilter> constructor(x, copy);
124
0
    QMetaTypeSwitcher::switcher<void>(constructor, x->type);
125
0
}
126
127
static void clear(QVariant::Private *d)
128
0
{
129
0
    QVariantDestructor<CoreTypesFilter> cleaner(d);
130
0
    QMetaTypeSwitcher::switcher<void>(cleaner, d->type);
131
0
}
132
133
static bool isNull(const QVariant::Private *d)
134
8
{
135
8
    QVariantIsNull<CoreTypesFilter> isNull(d);
136
8
    return QMetaTypeSwitcher::switcher<bool>(isNull, d->type);
137
8
}
138
139
/*!
140
  \internal
141
142
  Compares \a a to \a b. The caller guarantees that \a a and \a b
143
  are of the same type.
144
 */
145
static bool compare(const QVariant::Private *a, const QVariant::Private *b)
146
0
{
147
0
    QVariantComparator<CoreTypesFilter> comparator(a, b);
148
0
    return QMetaTypeSwitcher::switcher<bool>(comparator, a->type);
149
0
}
150
151
/*!
152
  \internal
153
 */
154
static qlonglong qMetaTypeNumber(const QVariant::Private *d)
155
0
{
156
0
    switch (d->type) {
157
0
    case QMetaType::Int:
158
0
        return d->data.i;
159
0
    case QMetaType::LongLong:
160
0
        return d->data.ll;
161
0
    case QMetaType::Char:
162
0
        return qlonglong(d->data.c);
163
0
    case QMetaType::SChar:
164
0
        return qlonglong(d->data.sc);
165
0
    case QMetaType::Short:
166
0
        return qlonglong(d->data.s);
167
0
    case QMetaType::Long:
168
0
        return qlonglong(d->data.l);
169
0
    case QMetaType::Float:
170
0
        return qRound64(d->data.f);
171
0
    case QMetaType::Double:
172
0
        return qRound64(d->data.d);
173
0
#ifndef QT_BOOTSTRAPPED
174
0
    case QMetaType::QJsonValue:
175
0
        return v_cast<QJsonValue>(d)->toDouble();
176
0
    case QMetaType::QCborValue:
177
0
        return v_cast<QCborValue>(d)->toInteger();
178
0
#endif
179
0
    }
180
0
    Q_ASSERT(false);
181
0
    return 0;
182
0
}
183
184
static qulonglong qMetaTypeUNumber(const QVariant::Private *d)
185
0
{
186
0
    switch (d->type) {
187
0
    case QMetaType::UInt:
188
0
        return d->data.u;
189
0
    case QMetaType::ULongLong:
190
0
        return d->data.ull;
191
0
    case QMetaType::UChar:
192
0
        return d->data.uc;
193
0
    case QMetaType::UShort:
194
0
        return d->data.us;
195
0
    case QMetaType::ULong:
196
0
        return d->data.ul;
197
0
    }
198
0
    Q_ASSERT(false);
199
0
    return 0;
200
0
}
201
202
static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
203
0
{
204
0
    *ok = true;
205
206
0
    switch (uint(d->type)) {
207
0
    case QMetaType::QString:
208
0
        return v_cast<QString>(d)->toLongLong(ok);
209
0
    case QMetaType::QChar:
210
0
        return v_cast<QChar>(d)->unicode();
211
0
    case QMetaType::QByteArray:
212
0
        return v_cast<QByteArray>(d)->toLongLong(ok);
213
0
    case QMetaType::Bool:
214
0
        return qlonglong(d->data.b);
215
0
#ifndef QT_BOOTSTRAPPED
216
0
    case QMetaType::QCborValue:
217
0
        if (!v_cast<QCborValue>(d)->isInteger() && !v_cast<QCborValue>(d)->isDouble())
218
0
            break;
219
0
        return qMetaTypeNumber(d);
220
0
    case QMetaType::QJsonValue:
221
0
        if (!v_cast<QJsonValue>(d)->isDouble())
222
0
            break;
223
0
        Q_FALLTHROUGH();
224
0
#endif
225
0
    case QMetaType::Double:
226
0
    case QMetaType::Int:
227
0
    case QMetaType::Char:
228
0
    case QMetaType::SChar:
229
0
    case QMetaType::Short:
230
0
    case QMetaType::Long:
231
0
    case QMetaType::Float:
232
0
    case QMetaType::LongLong:
233
0
        return qMetaTypeNumber(d);
234
0
    case QMetaType::ULongLong:
235
0
    case QMetaType::UInt:
236
0
    case QMetaType::UChar:
237
0
    case QMetaType::UShort:
238
0
    case QMetaType::ULong:
239
240
0
        return qlonglong(qMetaTypeUNumber(d));
241
0
    }
242
243
0
    QMetaType typeInfo(d->type);
244
0
    if (typeInfo.flags() & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
245
0
        switch (typeInfo.sizeOf()) {
246
0
        case 1:
247
0
            return d->is_shared ? *reinterpret_cast<signed char *>(d->data.shared->ptr) : d->data.sc;
248
0
        case 2:
249
0
            return d->is_shared ? *reinterpret_cast<qint16 *>(d->data.shared->ptr) : d->data.s;
250
0
        case 4:
251
0
            return d->is_shared ? *reinterpret_cast<qint32 *>(d->data.shared->ptr) : d->data.i;
252
0
        case 8:
253
0
            return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->ptr) : d->data.ll;
254
0
        }
255
0
    }
256
257
0
    *ok = false;
258
0
    return Q_INT64_C(0);
259
0
}
260
261
static qreal qConvertToRealNumber(const QVariant::Private *d, bool *ok)
262
0
{
263
0
    *ok = true;
264
0
    switch (uint(d->type)) {
265
0
    case QMetaType::Double:
266
0
        return qreal(d->data.d);
267
0
    case QMetaType::Float:
268
0
        return qreal(d->data.f);
269
0
    case QMetaType::ULongLong:
270
0
    case QMetaType::UInt:
271
0
    case QMetaType::UChar:
272
0
    case QMetaType::UShort:
273
0
    case QMetaType::ULong:
274
0
        return qreal(qMetaTypeUNumber(d));
275
0
#ifndef QT_BOOTSTRAPPED
276
0
    case QMetaType::QCborValue:
277
0
        return v_cast<QCborValue>(d)->toDouble();
278
0
    case QMetaType::QJsonValue:
279
0
        return v_cast<QJsonValue>(d)->toDouble();
280
0
#endif
281
0
    default:
282
        // includes enum conversion as well as invalid types
283
0
        return qreal(qConvertToNumber(d, ok));
284
0
    }
285
0
}
286
287
static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
288
0
{
289
0
    *ok = true;
290
291
0
    switch (uint(d->type)) {
292
0
    case QMetaType::QString:
293
0
        return v_cast<QString>(d)->toULongLong(ok);
294
0
    case QMetaType::QChar:
295
0
        return v_cast<QChar>(d)->unicode();
296
0
    case QMetaType::QByteArray:
297
0
        return v_cast<QByteArray>(d)->toULongLong(ok);
298
0
    case QMetaType::Bool:
299
0
        return qulonglong(d->data.b);
300
0
#ifndef QT_BOOTSTRAPPED
301
0
    case QMetaType::QCborValue:
302
0
        if (v_cast<QCborValue>(d)->isDouble())
303
0
            return qulonglong(qConvertToRealNumber(d, ok));
304
0
        if (!v_cast<QCborValue>(d)->isInteger())
305
0
            return false;
306
0
        return qulonglong(qMetaTypeNumber(d));
307
0
    case QMetaType::QJsonValue:
308
0
        if (!v_cast<QJsonValue>(d)->isDouble())
309
0
            break;
310
0
        Q_FALLTHROUGH();
311
0
#endif
312
0
    case QMetaType::Double:
313
0
    case QMetaType::Int:
314
0
    case QMetaType::Char:
315
0
    case QMetaType::SChar:
316
0
    case QMetaType::Short:
317
0
    case QMetaType::Long:
318
0
    case QMetaType::Float:
319
0
    case QMetaType::LongLong:
320
0
        return qulonglong(qMetaTypeNumber(d));
321
0
    case QMetaType::ULongLong:
322
0
    case QMetaType::UInt:
323
0
    case QMetaType::UChar:
324
0
    case QMetaType::UShort:
325
0
    case QMetaType::ULong:
326
0
        return qMetaTypeUNumber(d);
327
0
    }
328
329
0
    QMetaType typeInfo(d->type);
330
0
    if (typeInfo.flags() & QMetaType::IsEnumeration) {
331
0
        switch (typeInfo.sizeOf()) {
332
0
        case 1:
333
0
            return d->is_shared ? *reinterpret_cast<uchar *>(d->data.shared->ptr) : d->data.uc;
334
0
        case 2:
335
0
            return d->is_shared ? *reinterpret_cast<quint16 *>(d->data.shared->ptr) : d->data.us;
336
0
        case 4:
337
0
            return d->is_shared ? *reinterpret_cast<quint32 *>(d->data.shared->ptr) : d->data.u;
338
0
        case 8:
339
0
            return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->ptr) : d->data.ull;
340
0
        }
341
0
    }
342
343
0
    *ok = false;
344
0
    return Q_UINT64_C(0);
345
0
}
346
347
template<typename TInput, typename LiteralWrapper>
348
inline bool qt_convertToBool(const QVariant::Private *const d)
349
0
{
350
0
    TInput str = v_cast<TInput>(d)->toLower();
351
0
    return !(str.isEmpty() || str == LiteralWrapper("0") || str == LiteralWrapper("false"));
352
0
}
Unexecuted instantiation: qvariant.cpp:bool (anonymous namespace)::qt_convertToBool<QByteArray, char const*>(QVariant::Private const*)
Unexecuted instantiation: qvariant.cpp:bool (anonymous namespace)::qt_convertToBool<QString, QLatin1String>(QVariant::Private const*)
353
354
/*!
355
 \internal
356
 Returns the internal data pointer from \a d.
357
 */
358
359
static const void *constData(const QVariant::Private &d)
360
0
{
361
0
    return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.c);
362
0
}
363
364
#ifndef QT_NO_QOBJECT
365
/*!
366
  \internal
367
  returns a QMetaEnum for a given meta tape type id if possible
368
*/
369
static QMetaEnum metaEnumFromType(int type)
370
0
{
371
0
    QMetaType t(type);
372
0
    if (t.flags() & QMetaType::IsEnumeration) {
373
0
        if (const QMetaObject *metaObject = t.metaObject()) {
374
0
            const char *enumName = QMetaType::typeName(type);
375
0
            const char *lastColon = std::strrchr(enumName, ':');
376
0
            if (lastColon)
377
0
                enumName = lastColon + 1;
378
0
            return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
379
0
        }
380
0
    }
381
0
    return QMetaEnum();
382
0
}
383
#endif
384
385
/*!
386
 \internal
387
388
 Converts \a d to type \a t, which is placed in \a result.
389
 */
390
static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
391
10
{
392
10
    Q_ASSERT(d->type != uint(t));
393
10
    Q_ASSERT(result);
394
395
10
    if (d->type >= QMetaType::User || t >= QMetaType::User) {
396
0
        const bool isOk = QMetaType::convert(constData(*d), d->type, result, t);
397
0
        if (ok)
398
0
            *ok = isOk;
399
0
        if (isOk)
400
0
            return true;
401
0
    }
402
403
10
    bool dummy;
404
10
    if (!ok)
405
10
        ok = &dummy;
406
407
10
    switch (uint(t)) {
408
0
#ifndef QT_BOOTSTRAPPED
409
0
    case QMetaType::QUrl:
410
0
        switch (d->type) {
411
0
        case QMetaType::QString:
412
0
            *static_cast<QUrl *>(result) = QUrl(*v_cast<QString>(d));
413
0
            break;
414
0
        case QMetaType::QCborValue:
415
0
            if (v_cast<QCborValue>(d)->isUrl()) {
416
0
                *static_cast<QUrl *>(result) = v_cast<QCborValue>(d)->toUrl();
417
0
                break;
418
0
            }
419
0
            return false;
420
0
        default:
421
0
            return false;
422
0
        }
423
0
        break;
424
0
#endif // QT_BOOTSTRAPPED
425
0
#if QT_CONFIG(itemmodel)
426
0
    case QMetaType::QModelIndex:
427
0
        switch (d->type) {
428
0
        case QMetaType::QPersistentModelIndex:
429
0
            *static_cast<QModelIndex *>(result) = QModelIndex(*v_cast<QPersistentModelIndex>(d));
430
0
            break;
431
0
        default:
432
0
            return false;
433
0
        }
434
0
        break;
435
0
    case QMetaType::QPersistentModelIndex:
436
0
        switch (d->type) {
437
0
        case QMetaType::QModelIndex:
438
0
            *static_cast<QPersistentModelIndex *>(result) = QPersistentModelIndex(*v_cast<QModelIndex>(d));
439
0
            break;
440
0
        default:
441
0
            return false;
442
0
        }
443
0
        break;
444
0
#endif // QT_CONFIG(itemmodel)
445
10
    case QMetaType::QString: {
446
10
        QString *str = static_cast<QString *>(result);
447
10
        switch (d->type) {
448
10
        case QMetaType::QChar:
449
10
            *str = *v_cast<QChar>(d);
450
10
            break;
451
0
        case QMetaType::Char:
452
0
        case QMetaType::SChar:
453
0
        case QMetaType::UChar:
454
0
            *str = QChar::fromLatin1(d->data.c);
455
0
            break;
456
0
        case QMetaType::Short:
457
0
        case QMetaType::Long:
458
0
        case QMetaType::Int:
459
0
        case QMetaType::LongLong:
460
0
            *str = QString::number(qMetaTypeNumber(d));
461
0
            break;
462
0
        case QMetaType::UInt:
463
0
        case QMetaType::ULongLong:
464
0
        case QMetaType::UShort:
465
0
        case QMetaType::ULong:
466
0
            *str = QString::number(qMetaTypeUNumber(d));
467
0
            break;
468
0
        case QMetaType::Float:
469
0
            *str = QString::number(d->data.f, 'g', QLocale::FloatingPointShortest);
470
0
            break;
471
0
        case QMetaType::Double:
472
0
            *str = QString::number(d->data.d, 'g', QLocale::FloatingPointShortest);
473
0
            break;
474
0
#if QT_CONFIG(datestring)
475
0
        case QMetaType::QDate:
476
0
            *str = v_cast<QDate>(d)->toString(Qt::ISODate);
477
0
            break;
478
0
        case QMetaType::QTime:
479
0
            *str = v_cast<QTime>(d)->toString(Qt::ISODateWithMs);
480
0
            break;
481
0
        case QMetaType::QDateTime:
482
0
            *str = v_cast<QDateTime>(d)->toString(Qt::ISODateWithMs);
483
0
            break;
484
0
#endif
485
0
        case QMetaType::Bool:
486
0
            *str = d->data.b ? QStringLiteral("true") : QStringLiteral("false");
487
0
            break;
488
0
        case QMetaType::QByteArray:
489
0
            *str = QString::fromUtf8(v_cast<QByteArray>(d)->constData());
490
0
            break;
491
0
        case QMetaType::QStringList:
492
0
            if (v_cast<QStringList>(d)->count() == 1)
493
0
                *str = v_cast<QStringList>(d)->at(0);
494
0
            break;
495
0
#ifndef QT_BOOTSTRAPPED
496
0
        case QMetaType::QUrl:
497
0
            *str = v_cast<QUrl>(d)->toString();
498
0
            break;
499
0
        case QMetaType::QJsonValue:
500
0
            if (v_cast<QJsonValue>(d)->isString())
501
0
                *str = v_cast<QJsonValue>(d)->toString();
502
0
            else if (!v_cast<QJsonValue>(d)->isNull())
503
0
                return false;
504
0
            break;
505
0
        case QMetaType::QCborValue:
506
0
            if (v_cast<QCborValue>(d)->isContainer() || v_cast<QCborValue>(d)->isTag())
507
0
                return false;
508
0
            *str = v_cast<QCborValue>(d)->toVariant().toString();
509
0
            break;
510
0
#endif
511
0
        case QMetaType::QUuid:
512
0
            *str = v_cast<QUuid>(d)->toString();
513
0
            break;
514
0
        case QMetaType::Nullptr:
515
0
            *str = QString();
516
0
            break;
517
0
        default:
518
0
#ifndef QT_NO_QOBJECT
519
0
            {
520
0
                QMetaEnum en = metaEnumFromType(d->type);
521
0
                if (en.isValid()) {
522
0
                    *str = QString::fromUtf8(en.valueToKey(qConvertToNumber(d, ok)));
523
0
                    return *ok;
524
0
                }
525
0
            }
526
0
#endif
527
0
            return false;
528
10
        }
529
10
        break;
530
10
    }
531
10
    case QMetaType::QChar: {
532
0
        QChar *c = static_cast<QChar *>(result);
533
0
        switch (d->type) {
534
0
        case QMetaType::Int:
535
0
        case QMetaType::LongLong:
536
0
        case QMetaType::Char:
537
0
        case QMetaType::SChar:
538
0
        case QMetaType::Short:
539
0
        case QMetaType::Long:
540
0
        case QMetaType::Float:
541
0
            *c = QChar(ushort(qMetaTypeNumber(d)));
542
0
            break;
543
0
        case QMetaType::UInt:
544
0
        case QMetaType::ULongLong:
545
0
        case QMetaType::UChar:
546
0
        case QMetaType::UShort:
547
0
        case QMetaType::ULong:
548
0
            *c = QChar(ushort(qMetaTypeUNumber(d)));
549
0
            break;
550
0
        default:
551
0
            return false;
552
0
        }
553
0
        break;
554
0
    }
555
0
#ifndef QT_NO_GEOM_VARIANT
556
0
    case QMetaType::QSize: {
557
0
        QSize *s = static_cast<QSize *>(result);
558
0
        switch (d->type) {
559
0
        case QMetaType::QSizeF:
560
0
            *s = v_cast<QSizeF>(d)->toSize();
561
0
            break;
562
0
        default:
563
0
            return false;
564
0
        }
565
0
        break;
566
0
    }
567
568
0
    case QMetaType::QSizeF: {
569
0
        QSizeF *s = static_cast<QSizeF *>(result);
570
0
        switch (d->type) {
571
0
        case QMetaType::QSize:
572
0
            *s = QSizeF(*(v_cast<QSize>(d)));
573
0
            break;
574
0
        default:
575
0
            return false;
576
0
        }
577
0
        break;
578
0
    }
579
580
0
    case QMetaType::QLine: {
581
0
        QLine *s = static_cast<QLine *>(result);
582
0
        switch (d->type) {
583
0
        case QMetaType::QLineF:
584
0
            *s = v_cast<QLineF>(d)->toLine();
585
0
            break;
586
0
        default:
587
0
            return false;
588
0
        }
589
0
        break;
590
0
    }
591
592
0
    case QMetaType::QLineF: {
593
0
        QLineF *s = static_cast<QLineF *>(result);
594
0
        switch (d->type) {
595
0
        case QMetaType::QLine:
596
0
            *s = QLineF(*(v_cast<QLine>(d)));
597
0
            break;
598
0
        default:
599
0
            return false;
600
0
        }
601
0
        break;
602
0
    }
603
0
#endif
604
0
    case QMetaType::QStringList:
605
0
        if (d->type == QMetaType::QVariantList) {
606
0
            QStringList *slst = static_cast<QStringList *>(result);
607
0
            const QVariantList *list = v_cast<QVariantList >(d);
608
0
            const int size = list->size();
609
0
            slst->reserve(size);
610
0
            for (int i = 0; i < size; ++i)
611
0
                slst->append(list->at(i).toString());
612
0
        } else if (d->type == QMetaType::QString) {
613
0
            QStringList *slst = static_cast<QStringList *>(result);
614
0
            *slst = QStringList(*v_cast<QString>(d));
615
0
        } else {
616
0
            return false;
617
0
        }
618
0
        break;
619
0
    case QMetaType::QDate: {
620
0
        QDate *dt = static_cast<QDate *>(result);
621
0
        if (d->type == QMetaType::QDateTime)
622
0
            *dt = v_cast<QDateTime>(d)->date();
623
0
#if QT_CONFIG(datestring)
624
0
        else if (d->type == QMetaType::QString)
625
0
            *dt = QDate::fromString(*v_cast<QString>(d), Qt::ISODate);
626
0
#endif
627
0
        else
628
0
            return false;
629
630
0
        return dt->isValid();
631
0
    }
632
0
    case QMetaType::QTime: {
633
0
        QTime *t = static_cast<QTime *>(result);
634
0
        switch (d->type) {
635
0
        case QMetaType::QDateTime:
636
0
            *t = v_cast<QDateTime>(d)->time();
637
0
            break;
638
0
#if QT_CONFIG(datestring)
639
0
        case QMetaType::QString:
640
0
            *t = QTime::fromString(*v_cast<QString>(d), Qt::ISODate);
641
0
            break;
642
0
#endif
643
0
        default:
644
0
            return false;
645
0
        }
646
0
        return t->isValid();
647
0
    }
648
0
    case QMetaType::QDateTime: {
649
0
        QDateTime *dt = static_cast<QDateTime *>(result);
650
0
        switch (d->type) {
651
0
#if QT_CONFIG(datestring)
652
0
        case QMetaType::QString:
653
0
            *dt = QDateTime::fromString(*v_cast<QString>(d), Qt::ISODate);
654
0
            break;
655
0
#  ifndef QT_BOOTSTRAPPED
656
0
        case QMetaType::QCborValue:
657
0
            if (v_cast<QCborValue>(d)->isDateTime())
658
0
                *dt = v_cast<QCborValue>(d)->toDateTime();
659
0
            else
660
0
                return false;
661
0
            break;
662
0
#  endif
663
0
#endif
664
0
        case QMetaType::QDate:
665
0
            *dt = v_cast<QDate>(d)->startOfDay();
666
0
            break;
667
0
        default:
668
0
            return false;
669
0
        }
670
0
        return dt->isValid();
671
0
    }
672
0
    case QMetaType::QByteArray: {
673
0
        QByteArray *ba = static_cast<QByteArray *>(result);
674
0
        switch (d->type) {
675
0
        case QMetaType::QString:
676
0
            *ba = v_cast<QString>(d)->toUtf8();
677
0
            break;
678
0
        case QMetaType::Double:
679
0
            *ba = QByteArray::number(d->data.d, 'g', QLocale::FloatingPointShortest);
680
0
            break;
681
0
        case QMetaType::Float:
682
0
            *ba = QByteArray::number(d->data.f, 'g', QLocale::FloatingPointShortest);
683
0
            break;
684
0
        case QMetaType::Char:
685
0
        case QMetaType::SChar:
686
0
        case QMetaType::UChar:
687
0
            *ba = QByteArray(1, d->data.c);
688
0
            break;
689
0
        case QMetaType::Int:
690
0
        case QMetaType::LongLong:
691
0
        case QMetaType::Short:
692
0
        case QMetaType::Long:
693
0
            *ba = QByteArray::number(qMetaTypeNumber(d));
694
0
            break;
695
0
        case QMetaType::UInt:
696
0
        case QMetaType::ULongLong:
697
0
        case QMetaType::UShort:
698
0
        case QMetaType::ULong:
699
0
            *ba = QByteArray::number(qMetaTypeUNumber(d));
700
0
            break;
701
0
        case QMetaType::Bool:
702
0
            *ba = QByteArray(d->data.b ? "true" : "false");
703
0
            break;
704
0
        case QMetaType::QUuid:
705
0
            *ba = v_cast<QUuid>(d)->toByteArray();
706
0
            break;
707
0
        case QMetaType::Nullptr:
708
0
            *ba = QByteArray();
709
0
            break;
710
0
#ifndef QT_BOOTSTRAPPED
711
0
        case QMetaType::QCborValue:
712
0
            if (v_cast<QCborValue>(d)->isByteArray())
713
0
                *ba = v_cast<QCborValue>(d)->toByteArray();
714
0
            else
715
0
                return false;
716
0
            break;
717
0
#endif
718
0
        default:
719
0
#ifndef QT_NO_QOBJECT
720
0
            {
721
0
                QMetaEnum en = metaEnumFromType(d->type);
722
0
                if (en.isValid()) {
723
0
                    *ba = en.valueToKey(qConvertToNumber(d, ok));
724
0
                    return *ok;
725
0
                }
726
0
            }
727
0
#endif
728
0
            return false;
729
0
        }
730
0
    }
731
0
    break;
732
0
    case QMetaType::Short:
733
0
        *static_cast<short *>(result) = short(qConvertToNumber(d, ok));
734
0
        return *ok;
735
0
    case QMetaType::Long:
736
0
        *static_cast<long *>(result) = long(qConvertToNumber(d, ok));
737
0
        return *ok;
738
0
    case QMetaType::UShort:
739
0
        *static_cast<ushort *>(result) = ushort(qConvertToUnsignedNumber(d, ok));
740
0
        return *ok;
741
0
    case QMetaType::ULong:
742
0
        *static_cast<ulong *>(result) = ulong(qConvertToUnsignedNumber(d, ok));
743
0
        return *ok;
744
0
    case QMetaType::Int:
745
0
        *static_cast<int *>(result) = int(qConvertToNumber(d, ok));
746
0
        return *ok;
747
0
    case QMetaType::UInt:
748
0
        *static_cast<uint *>(result) = uint(qConvertToUnsignedNumber(d, ok));
749
0
        return *ok;
750
0
    case QMetaType::LongLong:
751
0
        *static_cast<qlonglong *>(result) = qConvertToNumber(d, ok);
752
0
        return *ok;
753
0
    case QMetaType::ULongLong: {
754
0
        *static_cast<qulonglong *>(result) = qConvertToUnsignedNumber(d, ok);
755
0
        return *ok;
756
0
    }
757
0
    case QMetaType::SChar: {
758
0
        signed char s = qConvertToNumber(d, ok);
759
0
        *static_cast<signed char*>(result) = s;
760
0
        return *ok;
761
0
    }
762
0
    case QMetaType::UChar: {
763
0
        *static_cast<uchar *>(result) = qConvertToUnsignedNumber(d, ok);
764
0
        return *ok;
765
0
    }
766
0
    case QMetaType::Bool: {
767
0
        bool *b = static_cast<bool *>(result);
768
0
        switch(d->type) {
769
0
        case QMetaType::QByteArray:
770
0
            *b = qt_convertToBool<QByteArray, const char*>(d);
771
0
            break;
772
0
        case QMetaType::QString:
773
0
            *b = qt_convertToBool<QString, QLatin1String>(d);
774
0
            break;
775
0
        case QMetaType::QChar:
776
0
            *b = !v_cast<QChar>(d)->isNull();
777
0
            break;
778
0
        case QMetaType::Double:
779
0
        case QMetaType::Int:
780
0
        case QMetaType::LongLong:
781
0
        case QMetaType::Char:
782
0
        case QMetaType::SChar:
783
0
        case QMetaType::Short:
784
0
        case QMetaType::Long:
785
0
        case QMetaType::Float:
786
0
            *b = qMetaTypeNumber(d) != Q_INT64_C(0);
787
0
            break;
788
0
        case QMetaType::UInt:
789
0
        case QMetaType::ULongLong:
790
0
        case QMetaType::UChar:
791
0
        case QMetaType::UShort:
792
0
        case QMetaType::ULong:
793
0
            *b = qMetaTypeUNumber(d) != Q_UINT64_C(0);
794
0
            break;
795
0
#ifndef QT_BOOTSTRAPPED
796
0
        case QMetaType::QCborValue:
797
0
            *b = v_cast<QCborValue>(d)->toBool();
798
0
            if (!v_cast<QCborValue>(d)->isBool())
799
0
                return false;
800
0
            break;
801
0
        case QMetaType::QJsonValue:
802
0
            *b = v_cast<QJsonValue>(d)->toBool(false);
803
0
            if (!v_cast<QJsonValue>(d)->isBool())
804
0
                return false;
805
0
            break;
806
0
#endif
807
0
        default:
808
0
            *b = false;
809
0
            return false;
810
0
        }
811
0
        break;
812
0
    }
813
0
    case QMetaType::Double: {
814
0
        double *f = static_cast<double *>(result);
815
0
        switch (d->type) {
816
0
        case QMetaType::QString:
817
0
            *f = v_cast<QString>(d)->toDouble(ok);
818
0
            break;
819
0
        case QMetaType::QByteArray:
820
0
            *f = v_cast<QByteArray>(d)->toDouble(ok);
821
0
            break;
822
0
        case QMetaType::Bool:
823
0
            *f = double(d->data.b);
824
0
            break;
825
0
        case QMetaType::Float:
826
0
            *f = double(d->data.f);
827
0
            break;
828
0
        case QMetaType::LongLong:
829
0
        case QMetaType::Int:
830
0
        case QMetaType::Char:
831
0
        case QMetaType::SChar:
832
0
        case QMetaType::Short:
833
0
        case QMetaType::Long:
834
0
            *f = double(qMetaTypeNumber(d));
835
0
            break;
836
0
        case QMetaType::UInt:
837
0
        case QMetaType::ULongLong:
838
0
        case QMetaType::UChar:
839
0
        case QMetaType::UShort:
840
0
        case QMetaType::ULong:
841
0
            *f = double(qMetaTypeUNumber(d));
842
0
            break;
843
0
#ifndef QT_BOOTSTRAPPED
844
0
        case QMetaType::QCborValue:
845
0
            *f = v_cast<QCborValue>(d)->toDouble();
846
0
            if (!v_cast<QCborValue>(d)->isDouble())
847
0
                return false;
848
0
            break;
849
0
        case QMetaType::QJsonValue:
850
0
            *f = v_cast<QJsonValue>(d)->toDouble(0.0);
851
0
            if (!v_cast<QJsonValue>(d)->isDouble())
852
0
                return false;
853
0
            break;
854
0
#endif
855
0
        default:
856
0
            *f = 0.0;
857
0
            return false;
858
0
        }
859
0
        break;
860
0
    }
861
0
    case QMetaType::Float: {
862
0
        float *f = static_cast<float *>(result);
863
0
        switch (d->type) {
864
0
        case QMetaType::QString:
865
0
            *f = v_cast<QString>(d)->toFloat(ok);
866
0
            break;
867
0
        case QMetaType::QByteArray:
868
0
            *f = v_cast<QByteArray>(d)->toFloat(ok);
869
0
            break;
870
0
        case QMetaType::Bool:
871
0
            *f = float(d->data.b);
872
0
            break;
873
0
        case QMetaType::Double:
874
0
            *f = float(d->data.d);
875
0
            break;
876
0
        case QMetaType::LongLong:
877
0
        case QMetaType::Int:
878
0
        case QMetaType::Char:
879
0
        case QMetaType::SChar:
880
0
        case QMetaType::Short:
881
0
        case QMetaType::Long:
882
0
            *f = float(qMetaTypeNumber(d));
883
0
            break;
884
0
        case QMetaType::UInt:
885
0
        case QMetaType::ULongLong:
886
0
        case QMetaType::UChar:
887
0
        case QMetaType::UShort:
888
0
        case QMetaType::ULong:
889
0
            *f = float(qMetaTypeUNumber(d));
890
0
            break;
891
0
#ifndef QT_BOOTSTRAPPED
892
0
        case QMetaType::QCborValue:
893
0
            *f = v_cast<QCborValue>(d)->toDouble();
894
0
            if (!v_cast<QCborValue>(d)->isDouble())
895
0
                return false;
896
0
            break;
897
0
        case QMetaType::QJsonValue:
898
0
            *f = v_cast<QJsonValue>(d)->toDouble(0.0);
899
0
            if (!v_cast<QJsonValue>(d)->isDouble())
900
0
                return false;
901
0
            break;
902
0
#endif
903
0
        default:
904
0
            *f = 0.0f;
905
0
            return false;
906
0
        }
907
0
        break;
908
0
    }
909
0
    case QMetaType::QVariantList:
910
0
        if (d->type == QMetaType::QStringList) {
911
0
            QVariantList *lst = static_cast<QVariantList *>(result);
912
0
            const QStringList *slist = v_cast<QStringList>(d);
913
0
            const int size = slist->size();
914
0
            lst->reserve(size);
915
0
            for (int i = 0; i < size; ++i)
916
0
                lst->append(QVariant(slist->at(i)));
917
0
        } else if (qstrcmp(QMetaType::typeName(d->type), "QList<QVariant>") == 0) {
918
0
            *static_cast<QVariantList *>(result) =
919
0
                *static_cast<QList<QVariant> *>(d->data.shared->ptr);
920
0
#ifndef QT_BOOTSTRAPPED
921
0
        } else if (d->type == QMetaType::QCborValue) {
922
0
            if (!v_cast<QCborValue>(d)->isArray())
923
0
                return false;
924
0
            *static_cast<QVariantList *>(result) = v_cast<QCborValue>(d)->toArray().toVariantList();
925
0
        } else if (d->type == QMetaType::QCborArray) {
926
0
            *static_cast<QVariantList *>(result) = v_cast<QCborArray>(d)->toVariantList();
927
0
        } else if (d->type == QMetaType::QJsonValue) {
928
0
            if (!v_cast<QJsonValue>(d)->isArray())
929
0
                return false;
930
0
            *static_cast<QVariantList *>(result) = v_cast<QJsonValue>(d)->toArray().toVariantList();
931
0
        } else if (d->type == QMetaType::QJsonArray) {
932
0
            *static_cast<QVariantList *>(result) = v_cast<QJsonArray>(d)->toVariantList();
933
0
#endif
934
0
        } else {
935
0
            return false;
936
0
        }
937
0
        break;
938
0
    case QMetaType::QVariantMap:
939
0
        if (qstrcmp(QMetaType::typeName(d->type), "QMap<QString, QVariant>") == 0) {
940
0
            *static_cast<QVariantMap *>(result) =
941
0
                *static_cast<QMap<QString, QVariant> *>(d->data.shared->ptr);
942
0
        } else if (d->type == QMetaType::QVariantHash) {
943
0
            QVariantMap *map = static_cast<QVariantMap *>(result);
944
0
            const QVariantHash *hash = v_cast<QVariantHash>(d);
945
0
            const auto end = hash->end();
946
0
            for (auto it = hash->begin(); it != end; ++it)
947
0
                static_cast<QMultiMap<QString, QVariant> *>(map)->insert(it.key(), it.value());
948
0
#ifndef QT_BOOTSTRAPPED
949
0
        } else if (d->type == QMetaType::QCborValue) {
950
0
            if (!v_cast<QCborValue>(d)->isMap())
951
0
                return false;
952
0
            *static_cast<QVariantMap *>(result) = v_cast<QCborValue>(d)->toMap().toVariantMap();
953
0
        } else if (d->type == QMetaType::QCborMap) {
954
0
            *static_cast<QVariantMap *>(result) = v_cast<QCborMap>(d)->toVariantMap();
955
0
        } else if (d->type == QMetaType::QJsonValue) {
956
0
            if (!v_cast<QJsonValue>(d)->isObject())
957
0
                return false;
958
0
            *static_cast<QVariantMap *>(result) = v_cast<QJsonValue>(d)->toObject().toVariantMap();
959
0
        } else if (d->type == QMetaType::QJsonObject) {
960
0
            *static_cast<QVariantMap *>(result) = v_cast<QJsonObject>(d)->toVariantMap();
961
0
#endif
962
0
        } else {
963
0
            return false;
964
0
        }
965
0
        break;
966
0
    case QMetaType::QVariantHash:
967
0
        if (qstrcmp(QMetaType::typeName(d->type), "QHash<QString, QVariant>") == 0) {
968
0
            *static_cast<QVariantHash *>(result) =
969
0
                *static_cast<QHash<QString, QVariant> *>(d->data.shared->ptr);
970
0
        } else if (d->type == QMetaType::QVariantMap) {
971
0
            QVariantHash *hash = static_cast<QVariantHash *>(result);
972
0
            const QVariantMap *map = v_cast<QVariantMap>(d);
973
0
            const auto end = map->end();
974
0
            for (auto it = map->begin(); it != end; ++it)
975
0
                static_cast<QMultiHash<QString, QVariant> *>(hash)->insert(it.key(), it.value());
976
0
#ifndef QT_BOOTSTRAPPED
977
0
        } else if (d->type == QMetaType::QCborValue) {
978
0
            if (!v_cast<QCborValue>(d)->isMap())
979
0
                return false;
980
0
            *static_cast<QVariantHash *>(result) = v_cast<QCborValue>(d)->toMap().toVariantHash();
981
0
        } else if (d->type == QMetaType::QCborMap) {
982
0
            *static_cast<QVariantHash *>(result) = v_cast<QCborMap>(d)->toVariantHash();
983
0
        } else if (d->type == QMetaType::QJsonValue) {
984
0
            if (!v_cast<QJsonValue>(d)->isObject())
985
0
                return false;
986
0
            *static_cast<QVariantHash *>(result) = v_cast<QJsonValue>(d)->toObject().toVariantHash();
987
0
        } else if (d->type == QMetaType::QJsonObject) {
988
0
            *static_cast<QVariantHash *>(result) = v_cast<QJsonObject>(d)->toVariantHash();
989
0
#endif
990
0
        } else {
991
0
            return false;
992
0
        }
993
0
        break;
994
0
#ifndef QT_NO_GEOM_VARIANT
995
0
    case QMetaType::QRect:
996
0
        if (d->type == QMetaType::QRectF)
997
0
            *static_cast<QRect *>(result) = (v_cast<QRectF>(d))->toRect();
998
0
        else
999
0
            return false;
1000
0
        break;
1001
0
    case QMetaType::QRectF:
1002
0
        if (d->type == QMetaType::QRect)
1003
0
            *static_cast<QRectF *>(result) = *v_cast<QRect>(d);
1004
0
        else
1005
0
            return false;
1006
0
        break;
1007
0
    case QMetaType::QPointF:
1008
0
        if (d->type == QMetaType::QPoint)
1009
0
            *static_cast<QPointF *>(result) = *v_cast<QPoint>(d);
1010
0
        else
1011
0
            return false;
1012
0
        break;
1013
0
    case QMetaType::QPoint:
1014
0
        if (d->type == QMetaType::QPointF)
1015
0
            *static_cast<QPoint *>(result) = (v_cast<QPointF>(d))->toPoint();
1016
0
        else
1017
0
            return false;
1018
0
        break;
1019
0
    case QMetaType::Char:
1020
0
    {
1021
0
        *static_cast<qint8 *>(result) = qint8(qConvertToNumber(d, ok));
1022
0
        return *ok;
1023
0
    }
1024
0
#endif
1025
0
    case QMetaType::QUuid:
1026
0
        switch (d->type) {
1027
0
        case QMetaType::QString:
1028
0
            *static_cast<QUuid *>(result) = QUuid(*v_cast<QString>(d));
1029
0
            break;
1030
0
        case QMetaType::QByteArray:
1031
0
            *static_cast<QUuid *>(result) = QUuid(*v_cast<QByteArray>(d));
1032
0
            break;
1033
0
#ifndef QT_BOOTSTRAPPED
1034
0
        case QMetaType::QCborValue:
1035
0
            if (!v_cast<QCborValue>(d)->isUuid())
1036
0
                return false;
1037
0
            *static_cast<QUuid *>(result) = v_cast<QCborValue>(d)->toUuid();
1038
0
            break;
1039
0
#endif
1040
0
        default:
1041
0
            return false;
1042
0
        }
1043
0
        break;
1044
0
    case QMetaType::Nullptr:
1045
0
        *static_cast<std::nullptr_t *>(result) = nullptr;
1046
0
        if (QMetaType::typeFlags(t) & (QMetaType::PointerToGadget | QMetaType::PointerToQObject)
1047
0
                || d->type == QMetaType::VoidStar) {
1048
0
            if (v_cast<const void *>(d) == nullptr)
1049
0
                break;
1050
0
        }
1051
0
#ifndef QT_BOOTSTRAPPED
1052
0
        if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isNull())
1053
0
            break;
1054
0
#endif
1055
0
        return false;
1056
1057
0
#ifndef QT_BOOTSTRAPPED
1058
0
#if QT_CONFIG(regularexpression)
1059
0
    case QMetaType::QRegularExpression:
1060
0
        if (d->type != QMetaType::QCborValue || !v_cast<QCborValue>(d)->isRegularExpression())
1061
0
            return false;
1062
0
        *static_cast<QRegularExpression *>(result) = v_cast<QCborValue>(d)->toRegularExpression();
1063
0
        break;
1064
0
#endif
1065
0
    case QMetaType::QJsonValue:
1066
0
        switch (d->type) {
1067
0
        case QMetaType::Nullptr:
1068
0
            *static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Null);
1069
0
            break;
1070
0
        case QMetaType::Bool:
1071
0
            *static_cast<QJsonValue *>(result) = QJsonValue(d->data.b);
1072
0
            break;
1073
0
        case QMetaType::Int:
1074
0
        case QMetaType::UInt:
1075
0
        case QMetaType::Double:
1076
0
        case QMetaType::Float:
1077
0
        case QMetaType::ULong:
1078
0
        case QMetaType::Long:
1079
0
        case QMetaType::LongLong:
1080
0
        case QMetaType::ULongLong:
1081
0
        case QMetaType::UShort:
1082
0
        case QMetaType::UChar:
1083
0
        case QMetaType::Char:
1084
0
        case QMetaType::SChar:
1085
0
        case QMetaType::Short:
1086
0
            *static_cast<QJsonValue *>(result) = QJsonValue(qConvertToRealNumber(d, ok));
1087
0
            Q_ASSERT(ok);
1088
0
            break;
1089
0
        case QMetaType::QString:
1090
0
            *static_cast<QJsonValue *>(result) = QJsonValue(*v_cast<QString>(d));
1091
0
            break;
1092
0
        case QMetaType::QStringList:
1093
0
            *static_cast<QJsonValue *>(result) = QJsonValue(QJsonArray::fromStringList(*v_cast<QStringList>(d)));
1094
0
            break;
1095
0
        case QMetaType::QVariantList:
1096
0
            *static_cast<QJsonValue *>(result) = QJsonValue(QJsonArray::fromVariantList(*v_cast<QVariantList>(d)));
1097
0
            break;
1098
0
        case QMetaType::QVariantMap:
1099
0
            *static_cast<QJsonValue *>(result) = QJsonValue(QJsonObject::fromVariantMap(*v_cast<QVariantMap>(d)));
1100
0
            break;
1101
0
        case QMetaType::QVariantHash:
1102
0
            *static_cast<QJsonValue *>(result) = QJsonValue(QJsonObject::fromVariantHash(*v_cast<QVariantHash>(d)));
1103
0
            break;
1104
0
        case QMetaType::QJsonObject:
1105
0
            *static_cast<QJsonValue *>(result) = *v_cast<QJsonObject>(d);
1106
0
            break;
1107
0
        case QMetaType::QJsonArray:
1108
0
            *static_cast<QJsonValue *>(result) = *v_cast<QJsonArray>(d);
1109
0
            break;
1110
0
        case QMetaType::QJsonDocument: {
1111
0
            QJsonDocument doc = *v_cast<QJsonDocument>(d);
1112
0
            *static_cast<QJsonValue *>(result) = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1113
0
            break;
1114
0
        }
1115
0
        case QMetaType::QCborValue:
1116
0
            *static_cast<QJsonValue *>(result) = v_cast<QCborValue>(d)->toJsonValue();
1117
0
            break;
1118
0
        case QMetaType::QCborMap:
1119
0
            *static_cast<QJsonValue *>(result) = v_cast<QCborMap>(d)->toJsonObject();
1120
0
            break;
1121
0
        case QMetaType::QCborArray:
1122
0
            *static_cast<QJsonValue *>(result) = v_cast<QCborArray>(d)->toJsonArray();
1123
0
            break;
1124
0
        default:
1125
0
            *static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Undefined);
1126
0
            return false;
1127
0
        }
1128
0
        break;
1129
0
    case QMetaType::QJsonArray:
1130
0
        switch (d->type) {
1131
0
        case QMetaType::QStringList:
1132
0
            *static_cast<QJsonArray *>(result) = QJsonArray::fromStringList(*v_cast<QStringList>(d));
1133
0
            break;
1134
0
        case QMetaType::QVariantList:
1135
0
            *static_cast<QJsonArray *>(result) = QJsonArray::fromVariantList(*v_cast<QVariantList>(d));
1136
0
            break;
1137
0
        case QMetaType::QJsonValue:
1138
0
            if (!v_cast<QJsonValue>(d)->isArray())
1139
0
                return false;
1140
0
            *static_cast<QJsonArray *>(result) = v_cast<QJsonValue>(d)->toArray();
1141
0
            break;
1142
0
        case QMetaType::QJsonDocument:
1143
0
            if (!v_cast<QJsonDocument>(d)->isArray())
1144
0
                return false;
1145
0
            *static_cast<QJsonArray *>(result) = v_cast<QJsonDocument>(d)->array();
1146
0
            break;
1147
0
        case QMetaType::QCborValue:
1148
0
            if (!v_cast<QCborValue>(d)->isArray())
1149
0
                return false;
1150
0
            *static_cast<QJsonArray *>(result) = v_cast<QCborValue>(d)->toArray().toJsonArray();
1151
0
            break;
1152
0
        case QMetaType::QCborArray:
1153
0
            *static_cast<QJsonArray *>(result) = v_cast<QCborArray>(d)->toJsonArray();
1154
0
            break;
1155
0
        default:
1156
0
            return false;
1157
0
        }
1158
0
        break;
1159
0
    case QMetaType::QJsonObject:
1160
0
        switch (d->type) {
1161
0
        case QMetaType::QVariantMap:
1162
0
            *static_cast<QJsonObject *>(result) = QJsonObject::fromVariantMap(*v_cast<QVariantMap>(d));
1163
0
            break;
1164
0
        case QMetaType::QVariantHash:
1165
0
            *static_cast<QJsonObject *>(result) = QJsonObject::fromVariantHash(*v_cast<QVariantHash>(d));
1166
0
            break;
1167
0
        case QMetaType::QJsonValue:
1168
0
            if (!v_cast<QJsonValue>(d)->isObject())
1169
0
                return false;
1170
0
            *static_cast<QJsonObject *>(result) = v_cast<QJsonValue>(d)->toObject();
1171
0
            break;
1172
0
        case QMetaType::QJsonDocument:
1173
0
            if (v_cast<QJsonDocument>(d)->isArray())
1174
0
                return false;
1175
0
            *static_cast<QJsonObject *>(result) = v_cast<QJsonDocument>(d)->object();
1176
0
            break;
1177
0
        case QMetaType::QCborValue:
1178
0
            if (!v_cast<QCborValue>(d)->isMap())
1179
0
                return false;
1180
0
            *static_cast<QJsonObject *>(result) = v_cast<QCborValue>(d)->toMap().toJsonObject();
1181
0
            break;
1182
0
        case QMetaType::QCborMap:
1183
0
            *static_cast<QJsonObject *>(result) = v_cast<QCborMap>(d)->toJsonObject();
1184
0
            break;
1185
0
        default:
1186
0
            return false;
1187
0
        }
1188
0
        break;
1189
0
    case QMetaType::QCborSimpleType:
1190
0
        if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isSimpleType()) {
1191
0
            *static_cast<QCborSimpleType *>(result) = v_cast<QCborValue>(d)->toSimpleType();
1192
0
            break;
1193
0
        }
1194
0
        return false;
1195
0
    case QMetaType::QCborValue:
1196
0
        switch (d->type) {
1197
0
        case QMetaType::Nullptr:
1198
0
            *static_cast<QCborValue *>(result) = QCborValue(QCborValue::Null);
1199
0
            break;
1200
0
        case QMetaType::Bool:
1201
0
            *static_cast<QCborValue *>(result) = QCborValue(d->data.b);
1202
0
            break;
1203
0
        case QMetaType::Int:
1204
0
        case QMetaType::UInt:
1205
0
        case QMetaType::ULong:
1206
0
        case QMetaType::Long:
1207
0
        case QMetaType::LongLong:
1208
0
        case QMetaType::ULongLong:
1209
0
        case QMetaType::UShort:
1210
0
        case QMetaType::UChar:
1211
0
        case QMetaType::Char:
1212
0
        case QMetaType::SChar:
1213
0
        case QMetaType::Short:
1214
0
            *static_cast<QCborValue *>(result) = QCborValue(qConvertToNumber(d, ok));
1215
0
            Q_ASSERT(ok);
1216
0
            break;
1217
0
        case QMetaType::Double:
1218
0
        case QMetaType::Float:
1219
0
            *static_cast<QCborValue *>(result) = QCborValue(qConvertToRealNumber(d, ok));
1220
0
            Q_ASSERT(ok);
1221
0
            break;
1222
0
        case QMetaType::QString:
1223
0
            *static_cast<QCborValue *>(result) = *v_cast<QString>(d);
1224
0
            break;
1225
0
        case QMetaType::QStringList:
1226
0
            *static_cast<QCborValue *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
1227
0
            break;
1228
0
        case QMetaType::QByteArray:
1229
0
            *static_cast<QCborValue *>(result) = *v_cast<QByteArray>(d);
1230
0
            break;
1231
0
        case QMetaType::QDate:
1232
0
            *static_cast<QCborValue *>(result) = QCborValue(v_cast<QDate>(d)->startOfDay());
1233
0
            break;
1234
0
        case QMetaType::QDateTime:
1235
0
            *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QDateTime>(d));
1236
0
            break;
1237
0
        case QMetaType::QUrl:
1238
0
            *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUrl>(d));
1239
0
            break;
1240
0
#if QT_CONFIG(regularexpression)
1241
0
        case QMetaType::QRegularExpression:
1242
0
            *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QRegularExpression>(d));
1243
0
            break;
1244
0
#endif
1245
0
        case QMetaType::QUuid:
1246
0
            *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUuid>(d));
1247
0
            break;
1248
0
        case QMetaType::QVariantList:
1249
0
            *static_cast<QCborValue *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
1250
0
            break;
1251
0
        case QMetaType::QVariantMap:
1252
0
            *static_cast<QCborValue *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
1253
0
            break;
1254
0
        case QMetaType::QVariantHash:
1255
0
            *static_cast<QCborValue *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
1256
0
            break;
1257
0
        case QMetaType::QJsonValue:
1258
0
            *static_cast<QCborValue *>(result) = QCborValue::fromJsonValue(*v_cast<QJsonValue>(d));
1259
0
            break;
1260
0
        case QMetaType::QJsonObject:
1261
0
            *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
1262
0
            break;
1263
0
        case QMetaType::QJsonArray:
1264
0
            *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
1265
0
            break;
1266
0
        case QMetaType::QJsonDocument: {
1267
0
            QJsonDocument doc = *v_cast<QJsonDocument>(d);
1268
0
            if (doc.isArray())
1269
0
                *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(doc.array());
1270
0
            else
1271
0
                *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(doc.object());
1272
0
            break;
1273
0
        }
1274
0
        case QMetaType::QCborSimpleType:
1275
0
            *static_cast<QCborValue *>(result) = *v_cast<QCborSimpleType>(d);
1276
0
            break;
1277
0
        case QMetaType::QCborMap:
1278
0
            *static_cast<QCborValue *>(result) = *v_cast<QCborMap>(d);
1279
0
            break;
1280
0
        case QMetaType::QCborArray:
1281
0
            *static_cast<QCborValue *>(result) = *v_cast<QCborArray>(d);
1282
0
            break;
1283
0
        default:
1284
0
            *static_cast<QCborValue *>(result) = {};
1285
0
            return false;
1286
0
        }
1287
0
        break;
1288
0
    case QMetaType::QCborArray:
1289
0
        switch (d->type) {
1290
0
        case QMetaType::QStringList:
1291
0
            *static_cast<QCborArray *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
1292
0
            break;
1293
0
        case QMetaType::QVariantList:
1294
0
            *static_cast<QCborArray *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
1295
0
            break;
1296
0
        case QMetaType::QCborValue:
1297
0
            if (!v_cast<QCborValue>(d)->isArray())
1298
0
                return false;
1299
0
            *static_cast<QCborArray *>(result) = v_cast<QCborValue>(d)->toArray();
1300
0
            break;
1301
0
        case QMetaType::QJsonDocument:
1302
0
            if (!v_cast<QJsonDocument>(d)->isArray())
1303
0
                return false;
1304
0
            *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonDocument>(d)->array());
1305
0
            break;
1306
0
        case QMetaType::QJsonValue:
1307
0
            if (!v_cast<QJsonValue>(d)->isArray())
1308
0
                return false;
1309
0
            *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonValue>(d)->toArray());
1310
0
            break;
1311
0
        case QMetaType::QJsonArray:
1312
0
            *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
1313
0
            break;
1314
0
        default:
1315
0
            return false;
1316
0
        }
1317
0
        break;
1318
0
    case QMetaType::QCborMap:
1319
0
        switch (d->type) {
1320
0
        case QMetaType::QVariantMap:
1321
0
            *static_cast<QCborMap *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
1322
0
            break;
1323
0
        case QMetaType::QVariantHash:
1324
0
            *static_cast<QCborMap *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
1325
0
            break;
1326
0
        case QMetaType::QCborValue:
1327
0
            if (!v_cast<QCborValue>(d)->isMap())
1328
0
                return false;
1329
0
            *static_cast<QCborMap *>(result) = v_cast<QCborValue>(d)->toMap();
1330
0
            break;
1331
0
        case QMetaType::QJsonDocument:
1332
0
            if (v_cast<QJsonDocument>(d)->isArray())
1333
0
                return false;
1334
0
            *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonDocument>(d)->object());
1335
0
            break;
1336
0
        case QMetaType::QJsonValue:
1337
0
            if (!v_cast<QJsonValue>(d)->isObject())
1338
0
                return false;
1339
0
            *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonValue>(d)->toObject());
1340
0
            break;
1341
0
        case QMetaType::QJsonObject:
1342
0
            *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
1343
0
            break;
1344
0
        default:
1345
0
            return false;
1346
0
        }
1347
0
        break;
1348
0
#endif
1349
1350
0
    default:
1351
0
#ifndef QT_NO_QOBJECT
1352
0
        if (d->type == QMetaType::QString || d->type == QMetaType::QByteArray) {
1353
0
            QMetaEnum en = metaEnumFromType(t);
1354
0
            if (en.isValid()) {
1355
0
                QByteArray keys = (d->type == QMetaType::QString) ? v_cast<QString>(d)->toUtf8() : *v_cast<QByteArray>(d);
1356
0
                int value = en.keysToValue(keys.constData(), ok);
1357
0
                if (*ok) {
1358
0
                    switch (QMetaType::sizeOf(t)) {
1359
0
                    case 1:
1360
0
                        *static_cast<signed char *>(result) = value;
1361
0
                        return true;
1362
0
                    case 2:
1363
0
                        *static_cast<qint16 *>(result) = value;
1364
0
                        return true;
1365
0
                    case 4:
1366
0
                        *static_cast<qint32 *>(result) = value;
1367
0
                        return true;
1368
0
                    case 8:
1369
0
                        *static_cast<qint64 *>(result) = value;
1370
0
                        return true;
1371
0
                    }
1372
0
                }
1373
0
            }
1374
0
        }
1375
0
#endif
1376
0
        if (QMetaType::typeFlags(t) & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
1377
0
            qlonglong value = qConvertToNumber(d, ok);
1378
0
            if (*ok) {
1379
0
                switch (QMetaType::sizeOf(t)) {
1380
0
                case 1:
1381
0
                    *static_cast<signed char *>(result) = value;
1382
0
                    return true;
1383
0
                case 2:
1384
0
                    *static_cast<qint16 *>(result) = value;
1385
0
                    return true;
1386
0
                case 4:
1387
0
                    *static_cast<qint32 *>(result) = value;
1388
0
                    return true;
1389
0
                case 8:
1390
0
                    *static_cast<qint64 *>(result) = value;
1391
0
                    return true;
1392
0
                }
1393
0
            }
1394
0
            return *ok;
1395
0
        }
1396
0
        return false;
1397
10
    }
1398
10
    return true;
1399
10
}
1400
1401
#if !defined(QT_NO_DEBUG_STREAM)
1402
static void streamDebug(QDebug dbg, const QVariant &v)
1403
0
{
1404
0
    QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
1405
0
    QVariantDebugStream<CoreTypesFilter> stream(dbg, d);
1406
0
    QMetaTypeSwitcher::switcher<void>(stream, d->type);
1407
0
}
1408
#endif
1409
1410
const QVariant::Handler qt_kernel_variant_handler = {
1411
    construct,
1412
    clear,
1413
    isNull,
1414
#ifndef QT_NO_DATASTREAM
1415
    nullptr,
1416
    nullptr,
1417
#endif
1418
    compare,
1419
    convert,
1420
    nullptr,
1421
#if !defined(QT_NO_DEBUG_STREAM)
1422
    streamDebug
1423
#else
1424
    nullptr
1425
#endif
1426
};
1427
1428
0
static void dummyConstruct(QVariant::Private *, const void *) { Q_ASSERT_X(false, "QVariant", "Trying to construct an unknown type"); }
1429
0
static void dummyClear(QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to clear an unknown type"); }
1430
0
static bool dummyIsNull(const QVariant::Private *d) { Q_ASSERT_X(false, "QVariant::isNull", "Trying to call isNull on an unknown type"); return d->is_null; }
1431
0
static bool dummyCompare(const QVariant::Private *, const QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to compare an unknown types"); return false; }
1432
0
static bool dummyConvert(const QVariant::Private *, int, void *, bool *) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); return false; }
1433
#if !defined(QT_NO_DEBUG_STREAM)
1434
0
static void dummyStreamDebug(QDebug, const QVariant &) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); }
1435
#endif
1436
const QVariant::Handler qt_dummy_variant_handler = {
1437
    dummyConstruct,
1438
    dummyClear,
1439
    dummyIsNull,
1440
#ifndef QT_NO_DATASTREAM
1441
    nullptr,
1442
    nullptr,
1443
#endif
1444
    dummyCompare,
1445
    dummyConvert,
1446
    nullptr,
1447
#if !defined(QT_NO_DEBUG_STREAM)
1448
    dummyStreamDebug
1449
#else
1450
    nullptr
1451
#endif
1452
};
1453
1454
static void customConstruct(QVariant::Private *d, const void *copy)
1455
0
{
1456
0
    const QMetaType type(d->type);
1457
0
    const uint size = type.sizeOf();
1458
0
    if (!size) {
1459
0
        qWarning("Trying to construct an instance of an invalid type, type id: %i", d->type);
1460
0
        d->type = QMetaType::UnknownType;
1461
0
        return;
1462
0
    }
1463
1464
    // this logic should match with QVariantIntegrator::CanUseInternalSpace
1465
0
    if (size <= sizeof(QVariant::Private::Data)
1466
0
            && (type.flags() & (QMetaType::MovableType | QMetaType::IsEnumeration))) {
1467
0
        type.construct(&d->data.ptr, copy);
1468
0
        d->is_null = d->data.ptr == nullptr;
1469
0
        d->is_shared = false;
1470
0
    } else {
1471
        // Private::Data contains long long, and long double is the biggest standard type.
1472
0
        const size_t maxAlignment =
1473
0
            qMax(Q_ALIGNOF(QVariant::Private::Data), Q_ALIGNOF(long double));
1474
0
        const size_t s = sizeof(QVariant::PrivateShared);
1475
0
        const size_t offset = s + ((s * maxAlignment - s) % maxAlignment);
1476
0
        void *data = operator new(offset + size);
1477
0
        void *ptr = static_cast<char *>(data) + offset;
1478
0
        type.construct(ptr, copy);
1479
0
        d->is_null = ptr == nullptr;
1480
0
        d->is_shared = true;
1481
0
        d->data.shared = new (data) QVariant::PrivateShared(ptr);
1482
0
    }
1483
0
}
1484
1485
static void customClear(QVariant::Private *d)
1486
0
{
1487
0
    if (!d->is_shared) {
1488
0
        QMetaType::destruct(d->type, &d->data.ptr);
1489
0
    } else {
1490
0
        QMetaType::destruct(d->type, d->data.shared->ptr);
1491
0
        d->data.shared->~PrivateShared();
1492
0
        operator delete(d->data.shared);
1493
0
    }
1494
0
}
1495
1496
static bool customIsNull(const QVariant::Private *d)
1497
0
{
1498
0
    if (d->is_null)
1499
0
        return true;
1500
0
    const char *const typeName = QMetaType::typeName(d->type);
1501
0
    if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(d->type)))
1502
0
        qFatal("QVariant::isNull: type %d unknown to QVariant.", d->type);
1503
0
    uint typeNameLen = qstrlen(typeName);
1504
0
    if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*') {
1505
0
        const void *d_ptr = d->is_shared ? d->data.shared->ptr : &(d->data.ptr);
1506
0
        return *static_cast<void *const *>(d_ptr) == nullptr;
1507
0
    }
1508
0
    return false;
1509
0
}
1510
1511
static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
1512
0
{
1513
0
    const char *const typeName = QMetaType::typeName(a->type);
1514
0
    if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(a->type)))
1515
0
        qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
1516
1517
0
    const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data.ptr);
1518
0
    const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data.ptr);
1519
1520
0
    uint typeNameLen = qstrlen(typeName);
1521
0
    if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*')
1522
0
        return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
1523
1524
0
    if (a->is_null && b->is_null)
1525
0
        return true;
1526
1527
0
    return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
1528
0
}
1529
1530
static bool customConvert(const QVariant::Private *d, int t, void *result, bool *ok)
1531
0
{
1532
0
    if (d->type >= QMetaType::User || t >= QMetaType::User) {
1533
0
        if (QMetaType::convert(constData(*d), d->type, result, t)) {
1534
0
            if (ok)
1535
0
                *ok = true;
1536
0
            return true;
1537
0
        }
1538
0
    }
1539
0
    return convert(d, t, result, ok);
1540
0
}
1541
1542
#if !defined(QT_NO_DEBUG_STREAM)
1543
0
static void customStreamDebug(QDebug dbg, const QVariant &variant) {
1544
0
#ifndef QT_BOOTSTRAPPED
1545
0
    QMetaType::TypeFlags flags = QMetaType::typeFlags(variant.userType());
1546
0
    if (flags & QMetaType::PointerToQObject)
1547
0
        dbg.nospace() << qvariant_cast<QObject*>(variant);
1548
#else
1549
    Q_UNUSED(dbg);
1550
    Q_UNUSED(variant);
1551
#endif
1552
0
}
1553
#endif
1554
1555
const QVariant::Handler qt_custom_variant_handler = {
1556
    customConstruct,
1557
    customClear,
1558
    customIsNull,
1559
#ifndef QT_NO_DATASTREAM
1560
    nullptr,
1561
    nullptr,
1562
#endif
1563
    customCompare,
1564
    customConvert,
1565
    nullptr,
1566
#if !defined(QT_NO_DEBUG_STREAM)
1567
    customStreamDebug
1568
#else
1569
    nullptr
1570
#endif
1571
};
1572
1573
} // annonymous used to hide QVariant handlers
1574
1575
static HandlersManager handlerManager;
1576
Q_STATIC_ASSERT_X(!QModulesPrivate::Core, "Initialization assumes that ModulesNames::Core is 0");
1577
const QVariant::Handler *HandlersManager::Handlers[QModulesPrivate::ModulesCount]
1578
                                        = { &qt_kernel_variant_handler, &qt_dummy_variant_handler,
1579
                                            &qt_dummy_variant_handler, &qt_custom_variant_handler };
1580
1581
Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler()
1582
0
{
1583
0
    return &qt_kernel_variant_handler;
1584
0
}
1585
1586
Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names */name, const QVariant::Handler *handler)
1587
0
{
1588
0
    handlerManager.registerHandler(static_cast<QModulesPrivate::Names>(name), handler);
1589
0
}
1590
1591
/*!
1592
    \class QVariant
1593
    \inmodule QtCore
1594
    \brief The QVariant class acts like a union for the most common Qt data types.
1595
1596
    \ingroup objectmodel
1597
    \ingroup shared
1598
1599
1600
    Because C++ forbids unions from including types that have
1601
    non-default constructors or destructors, most interesting Qt
1602
    classes cannot be used in unions. Without QVariant, this would be
1603
    a problem for QObject::property() and for database work, etc.
1604
1605
    A QVariant object holds a single value of a single type() at a
1606
    time. (Some type()s are multi-valued, for example a string list.)
1607
    You can find out what type, T, the variant holds, convert it to a
1608
    different type using convert(), get its value using one of the
1609
    toT() functions (e.g., toSize()) and check whether the type can
1610
    be converted to a particular type using canConvert().
1611
1612
    The methods named toT() (e.g., toInt(), toString()) are const. If
1613
    you ask for the stored type, they return a copy of the stored
1614
    object. If you ask for a type that can be generated from the
1615
    stored type, toT() copies and converts and leaves the object
1616
    itself unchanged. If you ask for a type that cannot be generated
1617
    from the stored type, the result depends on the type; see the
1618
    function documentation for details.
1619
1620
    Here is some example code to demonstrate the use of QVariant:
1621
1622
    \snippet code/src_corelib_kernel_qvariant.cpp 0
1623
1624
    You can even store QList<QVariant> and QMap<QString, QVariant>
1625
    values in a variant, so you can easily construct arbitrarily
1626
    complex data structures of arbitrary types. This is very powerful
1627
    and versatile, but may prove less memory and speed efficient than
1628
    storing specific types in standard data structures.
1629
1630
    QVariant also supports the notion of null values, where you can
1631
    have a defined type with no value set. However, note that QVariant
1632
    types can only be cast when they have had a value set.
1633
1634
    \snippet code/src_corelib_kernel_qvariant.cpp 1
1635
1636
    QVariant can be extended to support other types than those
1637
    mentioned in the \l Type enum. See \l{Creating Custom Qt Types}{Creating Custom Qt Types}
1638
    for details.
1639
1640
    \section1 A Note on GUI Types
1641
1642
    Because QVariant is part of the Qt Core module, it cannot provide
1643
    conversion functions to data types defined in Qt GUI, such as
1644
    QColor, QImage, and QPixmap. In other words, there is no \c
1645
    toColor() function. Instead, you can use the QVariant::value() or
1646
    the qvariant_cast() template function. For example:
1647
1648
    \snippet code/src_corelib_kernel_qvariant.cpp 2
1649
1650
    The inverse conversion (e.g., from QColor to QVariant) is
1651
    automatic for all data types supported by QVariant, including
1652
    GUI-related types:
1653
1654
    \snippet code/src_corelib_kernel_qvariant.cpp 3
1655
1656
    \section1 Using canConvert() and convert() Consecutively
1657
1658
    When using canConvert() and convert() consecutively, it is possible for
1659
    canConvert() to return true, but convert() to return false. This
1660
    is typically because canConvert() only reports the general ability of
1661
    QVariant to convert between types given suitable data; it is still
1662
    possible to supply data which cannot actually be converted.
1663
1664
    For example, canConvert(Int) would return true when called on a variant
1665
    containing a string because, in principle, QVariant is able to convert
1666
    strings of numbers to integers.
1667
    However, if the string contains non-numeric characters, it cannot be
1668
    converted to an integer, and any attempt to convert it will fail.
1669
    Hence, it is important to have both functions return true for a
1670
    successful conversion.
1671
1672
    \sa QMetaType
1673
*/
1674
1675
/*!
1676
    \obsolete Use QMetaType::Type instead
1677
    \enum QVariant::Type
1678
1679
    This enum type defines the types of variable that a QVariant can
1680
    contain.
1681
1682
    \value Invalid  no type
1683
    \value BitArray  a QBitArray
1684
    \value Bitmap  a QBitmap
1685
    \value Bool  a bool
1686
    \value Brush  a QBrush
1687
    \value ByteArray  a QByteArray
1688
    \value Char  a QChar
1689
    \value Color  a QColor
1690
    \value Cursor  a QCursor
1691
    \value Date  a QDate
1692
    \value DateTime  a QDateTime
1693
    \value Double  a double
1694
    \value EasingCurve a QEasingCurve
1695
    \value Uuid a QUuid
1696
    \value ModelIndex a QModelIndex
1697
    \value PersistentModelIndex a QPersistentModelIndex (since 5.5)
1698
    \value Font  a QFont
1699
    \value Hash a QVariantHash
1700
    \value Icon  a QIcon
1701
    \value Image  a QImage
1702
    \value Int  an int
1703
    \value KeySequence  a QKeySequence
1704
    \value Line  a QLine
1705
    \value LineF  a QLineF
1706
    \value List  a QVariantList
1707
    \value Locale  a QLocale
1708
    \value LongLong a \l qlonglong
1709
    \value Map  a QVariantMap
1710
    \value Matrix  a QMatrix
1711
    \value Transform  a QTransform
1712
    \value Matrix4x4  a QMatrix4x4
1713
    \value Palette  a QPalette
1714
    \value Pen  a QPen
1715
    \value Pixmap  a QPixmap
1716
    \value Point  a QPoint
1717
    \value PointF  a QPointF
1718
    \value Polygon a QPolygon
1719
    \value PolygonF a QPolygonF
1720
    \value Quaternion  a QQuaternion
1721
    \value Rect  a QRect
1722
    \value RectF  a QRectF
1723
    \value RegExp  a QRegExp
1724
    \value RegularExpression  a QRegularExpression
1725
    \value Region  a QRegion
1726
    \value Size  a QSize
1727
    \value SizeF  a QSizeF
1728
    \value SizePolicy  a QSizePolicy
1729
    \value String  a QString
1730
    \value StringList  a QStringList
1731
    \value TextFormat  a QTextFormat
1732
    \value TextLength  a QTextLength
1733
    \value Time  a QTime
1734
    \value UInt  a \l uint
1735
    \value ULongLong a \l qulonglong
1736
    \value Url  a QUrl
1737
    \value Vector2D  a QVector2D
1738
    \value Vector3D  a QVector3D
1739
    \value Vector4D  a QVector4D
1740
1741
    \value UserType Base value for user-defined types.
1742
1743
    \omitvalue LastGuiType
1744
    \omitvalue LastCoreType
1745
    \omitvalue LastType
1746
*/
1747
1748
/*!
1749
    \fn QVariant::QVariant(QVariant &&other)
1750
1751
    Move-constructs a QVariant instance, making it point at the same
1752
    object that \a other was pointing to.
1753
1754
    \since 5.2
1755
*/
1756
1757
/*!
1758
    \fn QVariant &QVariant::operator=(QVariant &&other)
1759
1760
    Move-assigns \a other to this QVariant instance.
1761
1762
    \since 5.2
1763
*/
1764
1765
/*!
1766
    \fn QVariant::QVariant()
1767
1768
    Constructs an invalid variant.
1769
*/
1770
1771
1772
/*!
1773
    \fn QVariant::QVariant(int typeId, const void *copy)
1774
1775
    Constructs variant of type \a typeId, and initializes with
1776
    \a copy if \a copy is not \nullptr.
1777
1778
    Note that you have to pass the address of the variable you want stored.
1779
1780
    Usually, you never have to use this constructor, use QVariant::fromValue()
1781
    instead to construct variants from the pointer types represented by
1782
    \c QMetaType::VoidStar, and \c QMetaType::QObjectStar.
1783
1784
    \sa QVariant::fromValue(), QMetaType::Type
1785
*/
1786
1787
/*!
1788
    \fn QVariant::QVariant(Type type)
1789
1790
    Constructs an uninitialized variant of type \a type. This will create a
1791
    variant in a special null state that if accessed will return a default
1792
    constructed value of the \a type.
1793
1794
    \sa isNull()
1795
*/
1796
1797
1798
1799
/*!
1800
    \fn QVariant::create(int type, const void *copy)
1801
1802
    \internal
1803
1804
    Constructs a variant private of type \a type, and initializes with \a copy if
1805
    \a copy is not \nullptr.
1806
*/
1807
1808
void QVariant::create(int type, const void *copy)
1809
0
{
1810
0
    d.type = type;
1811
0
    handlerManager[type]->construct(&d, copy);
1812
0
}
1813
1814
/*!
1815
    \fn QVariant::~QVariant()
1816
1817
    Destroys the QVariant and the contained object.
1818
1819
    Note that subclasses that reimplement clear() should reimplement
1820
    the destructor to call clear(). This destructor calls clear(), but
1821
    because it is the destructor, QVariant::clear() is called rather
1822
    than a subclass's clear().
1823
*/
1824
1825
QVariant::~QVariant()
1826
18
{
1827
18
    if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
1828
0
        handlerManager[d.type]->clear(&d);
1829
18
}
1830
1831
/*!
1832
  \fn QVariant::QVariant(const QVariant &p)
1833
1834
    Constructs a copy of the variant, \a p, passed as the argument to
1835
    this constructor.
1836
*/
1837
1838
QVariant::QVariant(const QVariant &p)
1839
    : d(p.d)
1840
0
{
1841
0
    if (d.is_shared) {
1842
0
        d.data.shared->ref.ref();
1843
0
    } else if (p.d.type > Char) {
1844
0
        handlerManager[d.type]->construct(&d, p.constData());
1845
0
        d.is_null = p.d.is_null;
1846
0
    }
1847
0
}
1848
1849
#ifndef QT_NO_DATASTREAM
1850
/*!
1851
    Reads the variant from the data stream, \a s.
1852
*/
1853
QVariant::QVariant(QDataStream &s)
1854
0
{
1855
0
    d.is_null = true;
1856
0
    s >> *this;
1857
0
}
1858
#endif //QT_NO_DATASTREAM
1859
1860
/*!
1861
  \fn QVariant::QVariant(const QString &val)
1862
1863
    Constructs a new variant with a string value, \a val.
1864
*/
1865
1866
/*!
1867
  \fn QVariant::QVariant(QLatin1String val)
1868
1869
    Constructs a new variant with a string value, \a val.
1870
*/
1871
1872
/*!
1873
  \fn QVariant::QVariant(const char *val)
1874
1875
    Constructs a new variant with a string value of \a val.
1876
    The variant creates a deep copy of \a val into a QString assuming
1877
    UTF-8 encoding on the input \a val.
1878
1879
    Note that \a val is converted to a QString for storing in the
1880
    variant and QVariant::userType() will return QMetaType::QString for
1881
    the variant.
1882
1883
    You can disable this operator by defining \c
1884
    QT_NO_CAST_FROM_ASCII when you compile your applications.
1885
*/
1886
1887
#ifndef QT_NO_CAST_FROM_ASCII
1888
QVariant::QVariant(const char *val)
1889
0
{
1890
0
    QString s = QString::fromUtf8(val);
1891
0
    create(String, &s);
1892
0
}
1893
#endif
1894
1895
/*!
1896
  \fn QVariant::QVariant(const QStringList &val)
1897
1898
    Constructs a new variant with a string list value, \a val.
1899
*/
1900
1901
/*!
1902
  \fn QVariant::QVariant(const QMap<QString, QVariant> &val)
1903
1904
    Constructs a new variant with a map of \l {QVariant}s, \a val.
1905
*/
1906
1907
/*!
1908
  \fn QVariant::QVariant(const QHash<QString, QVariant> &val)
1909
1910
    Constructs a new variant with a hash of \l {QVariant}s, \a val.
1911
*/
1912
1913
/*!
1914
  \fn QVariant::QVariant(const QDate &val)
1915
1916
    Constructs a new variant with a date value, \a val.
1917
*/
1918
1919
/*!
1920
  \fn QVariant::QVariant(const QTime &val)
1921
1922
    Constructs a new variant with a time value, \a val.
1923
*/
1924
1925
/*!
1926
  \fn QVariant::QVariant(const QDateTime &val)
1927
1928
    Constructs a new variant with a date/time value, \a val.
1929
*/
1930
1931
/*!
1932
    \since 4.7
1933
  \fn QVariant::QVariant(const QEasingCurve &val)
1934
1935
    Constructs a new variant with an easing curve value, \a val.
1936
*/
1937
1938
/*!
1939
    \since 5.0
1940
    \fn QVariant::QVariant(const QUuid &val)
1941
1942
    Constructs a new variant with an uuid value, \a val.
1943
*/
1944
1945
/*!
1946
    \since 5.0
1947
    \fn QVariant::QVariant(const QModelIndex &val)
1948
1949
    Constructs a new variant with a QModelIndex value, \a val.
1950
*/
1951
1952
/*!
1953
    \since 5.5
1954
    \fn QVariant::QVariant(const QPersistentModelIndex &val)
1955
1956
    Constructs a new variant with a QPersistentModelIndex value, \a val.
1957
*/
1958
1959
/*!
1960
    \since 5.0
1961
    \fn QVariant::QVariant(const QJsonValue &val)
1962
1963
    Constructs a new variant with a json value, \a val.
1964
*/
1965
1966
/*!
1967
    \since 5.0
1968
    \fn QVariant::QVariant(const QJsonObject &val)
1969
1970
    Constructs a new variant with a json object value, \a val.
1971
*/
1972
1973
/*!
1974
    \since 5.0
1975
    \fn QVariant::QVariant(const QJsonArray &val)
1976
1977
    Constructs a new variant with a json array value, \a val.
1978
*/
1979
1980
/*!
1981
    \since 5.0
1982
    \fn QVariant::QVariant(const QJsonDocument &val)
1983
1984
    Constructs a new variant with a json document value, \a val.
1985
*/
1986
1987
/*!
1988
  \fn QVariant::QVariant(const QByteArray &val)
1989
1990
    Constructs a new variant with a bytearray value, \a val.
1991
*/
1992
1993
/*!
1994
  \fn QVariant::QVariant(const QBitArray &val)
1995
1996
    Constructs a new variant with a bitarray value, \a val.
1997
*/
1998
1999
/*!
2000
  \fn QVariant::QVariant(const QPoint &val)
2001
2002
  Constructs a new variant with a point value of \a val.
2003
 */
2004
2005
/*!
2006
  \fn QVariant::QVariant(const QPointF &val)
2007
2008
  Constructs a new variant with a point value of \a val.
2009
 */
2010
2011
/*!
2012
  \fn QVariant::QVariant(const QRectF &val)
2013
2014
  Constructs a new variant with a rect value of \a val.
2015
 */
2016
2017
/*!
2018
  \fn QVariant::QVariant(const QLineF &val)
2019
2020
  Constructs a new variant with a line value of \a val.
2021
 */
2022
2023
/*!
2024
  \fn QVariant::QVariant(const QLine &val)
2025
2026
  Constructs a new variant with a line value of \a val.
2027
 */
2028
2029
/*!
2030
  \fn QVariant::QVariant(const QRect &val)
2031
2032
  Constructs a new variant with a rect value of \a val.
2033
 */
2034
2035
/*!
2036
  \fn QVariant::QVariant(const QSize &val)
2037
2038
  Constructs a new variant with a size value of \a val.
2039
 */
2040
2041
/*!
2042
  \fn QVariant::QVariant(const QSizeF &val)
2043
2044
  Constructs a new variant with a size value of \a val.
2045
 */
2046
2047
/*!
2048
  \fn QVariant::QVariant(const QUrl &val)
2049
2050
  Constructs a new variant with a url value of \a val.
2051
 */
2052
2053
/*!
2054
  \fn QVariant::QVariant(int val)
2055
2056
    Constructs a new variant with an integer value, \a val.
2057
*/
2058
2059
/*!
2060
  \fn QVariant::QVariant(uint val)
2061
2062
    Constructs a new variant with an unsigned integer value, \a val.
2063
*/
2064
2065
/*!
2066
  \fn QVariant::QVariant(qlonglong val)
2067
2068
    Constructs a new variant with a long long integer value, \a val.
2069
*/
2070
2071
/*!
2072
  \fn QVariant::QVariant(qulonglong val)
2073
2074
    Constructs a new variant with an unsigned long long integer value, \a val.
2075
*/
2076
2077
2078
/*!
2079
  \fn QVariant::QVariant(bool val)
2080
2081
    Constructs a new variant with a boolean value, \a val.
2082
*/
2083
2084
/*!
2085
  \fn QVariant::QVariant(double val)
2086
2087
    Constructs a new variant with a floating point value, \a val.
2088
*/
2089
2090
/*!
2091
  \fn QVariant::QVariant(float val)
2092
2093
    Constructs a new variant with a floating point value, \a val.
2094
    \since 4.6
2095
*/
2096
2097
/*!
2098
    \fn QVariant::QVariant(const QList<QVariant> &val)
2099
2100
    Constructs a new variant with a list value, \a val.
2101
*/
2102
2103
/*!
2104
  \fn QVariant::QVariant(QChar c)
2105
2106
  Constructs a new variant with a char value, \a c.
2107
*/
2108
2109
/*!
2110
  \fn QVariant::QVariant(const QLocale &l)
2111
2112
  Constructs a new variant with a locale value, \a l.
2113
*/
2114
2115
/*!
2116
  \fn QVariant::QVariant(const QRegExp &regExp)
2117
2118
  Constructs a new variant with the regexp value \a regExp.
2119
*/
2120
2121
/*!
2122
  \fn QVariant::QVariant(const QRegularExpression &re)
2123
2124
  \since 5.0
2125
2126
  Constructs a new variant with the regular expression value \a re.
2127
*/
2128
2129
QVariant::QVariant(Type type)
2130
0
{ create(type, nullptr); }
2131
QVariant::QVariant(int typeId, const void *copy)
2132
0
{ create(typeId, copy); d.is_null = false; }
2133
2134
/*!
2135
    \internal
2136
    flags is true if it is a pointer type
2137
 */
2138
QVariant::QVariant(int typeId, const void *copy, uint flags)
2139
0
{
2140
0
    if (flags) { //type is a pointer type
2141
0
        d.type = typeId;
2142
0
        d.data.ptr = *reinterpret_cast<void *const*>(copy);
2143
0
    } else {
2144
0
        create(typeId, copy);
2145
0
    }
2146
0
    d.is_null = false;
2147
0
}
2148
2149
QVariant::QVariant(int val)
2150
    : d(Int)
2151
0
{ d.data.i = val; }
2152
QVariant::QVariant(uint val)
2153
    : d(UInt)
2154
0
{ d.data.u = val; }
2155
QVariant::QVariant(qlonglong val)
2156
    : d(LongLong)
2157
0
{ d.data.ll = val; }
2158
QVariant::QVariant(qulonglong val)
2159
    : d(ULongLong)
2160
0
{ d.data.ull = val; }
2161
QVariant::QVariant(bool val)
2162
    : d(Bool)
2163
0
{ d.data.b = val; }
2164
QVariant::QVariant(double val)
2165
    : d(Double)
2166
0
{ d.data.d = val; }
2167
QVariant::QVariant(float val)
2168
    : d(QMetaType::Float)
2169
0
{ d.data.f = val; }
2170
2171
QVariant::QVariant(const QByteArray &val)
2172
    : d(ByteArray)
2173
0
{ v_construct<QByteArray>(&d, val); }
2174
QVariant::QVariant(const QBitArray &val)
2175
    : d(BitArray)
2176
0
{ v_construct<QBitArray>(&d, val);  }
2177
QVariant::QVariant(const QString &val)
2178
    : d(String)
2179
0
{ v_construct<QString>(&d, val);  }
2180
QVariant::QVariant(QChar val)
2181
    : d(Char)
2182
5
{ v_construct<QChar>(&d, val);  }
2183
QVariant::QVariant(QLatin1String val)
2184
    : d(String)
2185
0
{ v_construct<QString>(&d, val); }
2186
QVariant::QVariant(const QStringList &val)
2187
    : d(StringList)
2188
0
{ v_construct<QStringList>(&d, val); }
2189
2190
QVariant::QVariant(const QDate &val)
2191
    : d(Date)
2192
0
{ v_construct<QDate>(&d, val); }
2193
QVariant::QVariant(const QTime &val)
2194
    : d(Time)
2195
0
{ v_construct<QTime>(&d, val); }
2196
QVariant::QVariant(const QDateTime &val)
2197
    : d(DateTime)
2198
0
{ v_construct<QDateTime>(&d, val); }
2199
#if QT_CONFIG(easingcurve)
2200
QVariant::QVariant(const QEasingCurve &val)
2201
    : d(EasingCurve)
2202
0
{ v_construct<QEasingCurve>(&d, val); }
2203
#endif
2204
QVariant::QVariant(const QList<QVariant> &list)
2205
    : d(List)
2206
0
{ v_construct<QVariantList>(&d, list); }
2207
QVariant::QVariant(const QMap<QString, QVariant> &map)
2208
    : d(Map)
2209
0
{ v_construct<QVariantMap>(&d, map); }
2210
QVariant::QVariant(const QHash<QString, QVariant> &hash)
2211
    : d(Hash)
2212
0
{ v_construct<QVariantHash>(&d, hash); }
2213
#ifndef QT_NO_GEOM_VARIANT
2214
QVariant::QVariant(const QPoint &pt)
2215
    : d(Point)
2216
0
{ v_construct<QPoint>(&d, pt); }
2217
QVariant::QVariant(const QPointF &pt)
2218
    : d(PointF)
2219
0
{ v_construct<QPointF>(&d, pt); }
2220
QVariant::QVariant(const QRectF &r)
2221
    : d(RectF)
2222
0
{ v_construct<QRectF>(&d, r); }
2223
QVariant::QVariant(const QLineF &l)
2224
    : d(LineF)
2225
0
{ v_construct<QLineF>(&d, l); }
2226
QVariant::QVariant(const QLine &l)
2227
    : d(Line)
2228
0
{ v_construct<QLine>(&d, l); }
2229
QVariant::QVariant(const QRect &r)
2230
    : d(Rect)
2231
0
{ v_construct<QRect>(&d, r); }
2232
QVariant::QVariant(const QSize &s)
2233
    : d(Size)
2234
0
{ v_construct<QSize>(&d, s); }
2235
QVariant::QVariant(const QSizeF &s)
2236
    : d(SizeF)
2237
0
{ v_construct<QSizeF>(&d, s); }
2238
#endif
2239
#ifndef QT_BOOTSTRAPPED
2240
QVariant::QVariant(const QUrl &u)
2241
    : d(Url)
2242
0
{ v_construct<QUrl>(&d, u); }
2243
#endif
2244
QVariant::QVariant(const QLocale &l)
2245
    : d(Locale)
2246
0
{ v_construct<QLocale>(&d, l); }
2247
#ifndef QT_NO_REGEXP
2248
QVariant::QVariant(const QRegExp &regExp)
2249
    : d(RegExp)
2250
0
{ v_construct<QRegExp>(&d, regExp); }
2251
#endif // QT_NO_REGEXP
2252
#if QT_CONFIG(regularexpression)
2253
QVariant::QVariant(const QRegularExpression &re)
2254
    : d(RegularExpression)
2255
0
{ v_construct<QRegularExpression>(&d, re); }
2256
#endif // QT_CONFIG(regularexpression)
2257
QVariant::QVariant(const QUuid &uuid)
2258
    : d(Uuid)
2259
0
{ v_construct<QUuid>(&d, uuid); }
2260
#ifndef QT_BOOTSTRAPPED
2261
QVariant::QVariant(const QJsonValue &jsonValue)
2262
    : d(QMetaType::QJsonValue)
2263
0
{ v_construct<QJsonValue>(&d, jsonValue); }
2264
QVariant::QVariant(const QJsonObject &jsonObject)
2265
    : d(QMetaType::QJsonObject)
2266
0
{ v_construct<QJsonObject>(&d, jsonObject); }
2267
QVariant::QVariant(const QJsonArray &jsonArray)
2268
    : d(QMetaType::QJsonArray)
2269
0
{ v_construct<QJsonArray>(&d, jsonArray); }
2270
QVariant::QVariant(const QJsonDocument &jsonDocument)
2271
    : d(QMetaType::QJsonDocument)
2272
0
{ v_construct<QJsonDocument>(&d, jsonDocument); }
2273
#endif // QT_BOOTSTRAPPED
2274
#if QT_CONFIG(itemmodel)
2275
QVariant::QVariant(const QModelIndex &modelIndex)
2276
    : d(ModelIndex)
2277
0
{ v_construct<QModelIndex>(&d, modelIndex); }
2278
QVariant::QVariant(const QPersistentModelIndex &modelIndex)
2279
    : d(PersistentModelIndex)
2280
0
{ v_construct<QPersistentModelIndex>(&d, modelIndex); }
2281
#endif
2282
2283
/*!
2284
    Returns the storage type of the value stored in the variant.
2285
    Although this function is declared as returning QVariant::Type,
2286
    the return value should be interpreted as QMetaType::Type. In
2287
    particular, QVariant::UserType is returned here only if the value
2288
    is equal or greater than QMetaType::User.
2289
2290
    Note that return values in the ranges QVariant::Char through
2291
    QVariant::RegExp and QVariant::Font through QVariant::Transform
2292
    correspond to the values in the ranges QMetaType::QChar through
2293
    QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion.
2294
2295
    Pay particular attention when working with char and QChar
2296
    variants.  Note that there is no QVariant constructor specifically
2297
    for type char, but there is one for QChar. For a variant of type
2298
    QChar, this function returns QVariant::Char, which is the same as
2299
    QMetaType::QChar, but for a variant of type \c char, this function
2300
    returns QMetaType::Char, which is \e not the same as
2301
    QVariant::Char.
2302
2303
    Also note that the types \c void*, \c long, \c short, \c unsigned
2304
    \c long, \c unsigned \c short, \c unsigned \c char, \c float, \c
2305
    QObject*, and \c QWidget* are represented in QMetaType::Type but
2306
    not in QVariant::Type, and they can be returned by this function.
2307
    However, they are considered to be user defined types when tested
2308
    against QVariant::Type.
2309
2310
    To test whether an instance of QVariant contains a data type that
2311
    is compatible with the data type you are interested in, use
2312
    canConvert().
2313
*/
2314
2315
QVariant::Type QVariant::type() const
2316
0
{
2317
0
    return d.type >= QMetaType::User ? UserType : static_cast<Type>(d.type);
2318
0
}
2319
2320
/*!
2321
    Returns the storage type of the value stored in the variant. For
2322
    non-user types, this is the same as type().
2323
2324
    \sa type()
2325
*/
2326
2327
int QVariant::userType() const
2328
0
{
2329
0
    return d.type;
2330
0
}
2331
2332
/*!
2333
    Assigns the value of the variant \a variant to this variant.
2334
*/
2335
QVariant& QVariant::operator=(const QVariant &variant)
2336
0
{
2337
0
    if (this == &variant)
2338
0
        return *this;
2339
2340
0
    clear();
2341
0
    if (variant.d.is_shared) {
2342
0
        variant.d.data.shared->ref.ref();
2343
0
        d = variant.d;
2344
0
    } else if (variant.d.type > Char) {
2345
0
        d.type = variant.d.type;
2346
0
        handlerManager[d.type]->construct(&d, variant.constData());
2347
0
        d.is_null = variant.d.is_null;
2348
0
    } else {
2349
0
        d = variant.d;
2350
0
    }
2351
2352
0
    return *this;
2353
0
}
2354
2355
/*!
2356
    \fn void QVariant::swap(QVariant &other)
2357
    \since 4.8
2358
2359
    Swaps variant \a other with this variant. This operation is very
2360
    fast and never fails.
2361
*/
2362
2363
/*!
2364
    \fn void QVariant::detach()
2365
2366
    \internal
2367
*/
2368
2369
void QVariant::detach()
2370
0
{
2371
0
    if (!d.is_shared || d.data.shared->ref.loadRelaxed() == 1)
2372
0
        return;
2373
2374
0
    Private dd;
2375
0
    dd.type = d.type;
2376
0
    handlerManager[d.type]->construct(&dd, constData());
2377
0
    if (!d.data.shared->ref.deref())
2378
0
        handlerManager[d.type]->clear(&d);
2379
0
    d.data.shared = dd.data.shared;
2380
0
}
2381
2382
/*!
2383
    \fn bool QVariant::isDetached() const
2384
2385
    \internal
2386
*/
2387
2388
/*!
2389
    Returns the name of the type stored in the variant. The returned
2390
    strings describe the C++ datatype used to store the data: for
2391
    example, "QFont", "QString", or "QVariantList". An Invalid
2392
    variant returns 0.
2393
*/
2394
const char *QVariant::typeName() const
2395
0
{
2396
0
    return QMetaType::typeName(d.type);
2397
0
}
2398
2399
/*!
2400
    Convert this variant to type QMetaType::UnknownType and free up any resources
2401
    used.
2402
*/
2403
void QVariant::clear()
2404
0
{
2405
0
    if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
2406
0
        handlerManager[d.type]->clear(&d);
2407
0
    d.type = Invalid;
2408
0
    d.is_null = true;
2409
0
    d.is_shared = false;
2410
0
}
2411
2412
/*!
2413
    Converts the int representation of the storage type, \a typeId, to
2414
    its string representation.
2415
2416
    Returns \nullptr if the type is QMetaType::UnknownType or doesn't exist.
2417
*/
2418
const char *QVariant::typeToName(int typeId)
2419
0
{
2420
0
    return QMetaType::typeName(typeId);
2421
0
}
2422
2423
2424
/*!
2425
    Converts the string representation of the storage type given in \a
2426
    name, to its enum representation.
2427
2428
    If the string representation cannot be converted to any enum
2429
    representation, the variant is set to \c Invalid.
2430
*/
2431
QVariant::Type QVariant::nameToType(const char *name)
2432
0
{
2433
0
    int metaType = QMetaType::type(name);
2434
0
    return metaType <= int(UserType) ? QVariant::Type(metaType) : UserType;
2435
0
}
2436
2437
#ifndef QT_NO_DATASTREAM
2438
enum { MapFromThreeCount = 36 };
2439
static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] =
2440
{
2441
    QMetaType::UnknownType,
2442
    QMetaType::QVariantMap,
2443
    QMetaType::QVariantList,
2444
    QMetaType::QString,
2445
    QMetaType::QStringList,
2446
    QMetaType::QFont,
2447
    QMetaType::QPixmap,
2448
    QMetaType::QBrush,
2449
    QMetaType::QRect,
2450
    QMetaType::QSize,
2451
    QMetaType::QColor,
2452
    QMetaType::QPalette,
2453
    0, // ColorGroup
2454
    QMetaType::QIcon,
2455
    QMetaType::QPoint,
2456
    QMetaType::QImage,
2457
    QMetaType::Int,
2458
    QMetaType::UInt,
2459
    QMetaType::Bool,
2460
    QMetaType::Double,
2461
    0, // Buggy ByteArray, QByteArray never had id == 20
2462
    QMetaType::QPolygon,
2463
    QMetaType::QRegion,
2464
    QMetaType::QBitmap,
2465
    QMetaType::QCursor,
2466
    QMetaType::QSizePolicy,
2467
    QMetaType::QDate,
2468
    QMetaType::QTime,
2469
    QMetaType::QDateTime,
2470
    QMetaType::QByteArray,
2471
    QMetaType::QBitArray,
2472
    QMetaType::QKeySequence,
2473
    QMetaType::QPen,
2474
    QMetaType::LongLong,
2475
    QMetaType::ULongLong,
2476
#if QT_CONFIG(easingcurve)
2477
    QMetaType::QEasingCurve
2478
#endif
2479
};
2480
2481
/*!
2482
    Internal function for loading a variant from stream \a s. Use the
2483
    stream operators instead.
2484
2485
    \internal
2486
*/
2487
void QVariant::load(QDataStream &s)
2488
0
{
2489
0
    clear();
2490
2491
0
    quint32 typeId;
2492
0
    s >> typeId;
2493
0
    if (s.version() < QDataStream::Qt_4_0) {
2494
0
        if (typeId >= MapFromThreeCount)
2495
0
            return;
2496
0
        typeId = mapIdFromQt3ToCurrent[typeId];
2497
0
    } else if (s.version() < QDataStream::Qt_5_0) {
2498
0
        if (typeId == 127 /* QVariant::UserType */) {
2499
0
            typeId = QMetaType::User;
2500
0
        } else if (typeId >= 128 && typeId != QVariant::UserType) {
2501
            // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
2502
            // by moving all ids down by 97.
2503
0
            typeId -= 97;
2504
0
        } else if (typeId == 75 /* QSizePolicy */) {
2505
0
            typeId = QMetaType::QSizePolicy;
2506
0
        } else if (typeId > 75 && typeId <= 86) {
2507
            // and as a result these types received lower ids too
2508
            // QKeySequence QPen QTextLength QTextFormat QMatrix QTransform QMatrix4x4 QVector2D QVector3D QVector4D QQuaternion
2509
0
            typeId -=1;
2510
0
        }
2511
0
    }
2512
2513
0
    qint8 is_null = false;
2514
0
    if (s.version() >= QDataStream::Qt_4_2)
2515
0
        s >> is_null;
2516
0
    if (typeId == QVariant::UserType) {
2517
0
        QByteArray name;
2518
0
        s >> name;
2519
0
        typeId = QMetaType::type(name.constData());
2520
0
        if (typeId == QMetaType::UnknownType) {
2521
0
            s.setStatus(QDataStream::ReadCorruptData);
2522
0
            qWarning("QVariant::load: unknown user type with name %s.", name.constData());
2523
0
            return;
2524
0
        }
2525
0
    }
2526
0
    create(typeId, nullptr);
2527
0
    d.is_null = is_null;
2528
2529
0
    if (!isValid()) {
2530
0
        if (s.version() < QDataStream::Qt_5_0) {
2531
        // Since we wrote something, we should read something
2532
0
            QString x;
2533
0
            s >> x;
2534
0
        }
2535
0
        d.is_null = true;
2536
0
        return;
2537
0
    }
2538
2539
    // const cast is safe since we operate on a newly constructed variant
2540
0
    if (!QMetaType::load(s, d.type, const_cast<void *>(constData()))) {
2541
0
        s.setStatus(QDataStream::ReadCorruptData);
2542
0
        qWarning("QVariant::load: unable to load type %d.", d.type);
2543
0
    }
2544
0
}
2545
2546
/*!
2547
    Internal function for saving a variant to the stream \a s. Use the
2548
    stream operators instead.
2549
2550
    \internal
2551
*/
2552
void QVariant::save(QDataStream &s) const
2553
0
{
2554
0
    quint32 typeId = d.type >= QMetaType::User ? QMetaType::User : userType();
2555
0
    bool fakeUserType = false;
2556
0
    if (s.version() < QDataStream::Qt_4_0) {
2557
0
        int i;
2558
0
        for (i = 0; i <= MapFromThreeCount - 1; ++i) {
2559
0
            if (mapIdFromQt3ToCurrent[i] == typeId) {
2560
0
                typeId = i;
2561
0
                break;
2562
0
            }
2563
0
        }
2564
0
        if (i >= MapFromThreeCount) {
2565
0
            s << QVariant();
2566
0
            return;
2567
0
        }
2568
0
    } else if (s.version() < QDataStream::Qt_5_0) {
2569
0
        if (typeId == QMetaType::User) {
2570
0
            typeId = 127; // QVariant::UserType had this value in Qt4
2571
0
        } else if (typeId >= 128 - 97 && typeId <= LastCoreType) {
2572
            // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
2573
            // by moving all ids down by 97.
2574
0
            typeId += 97;
2575
0
        } else if (typeId == QMetaType::QSizePolicy) {
2576
0
            typeId = 75;
2577
0
        } else if (typeId >= QMetaType::QKeySequence && typeId <= QMetaType::QQuaternion) {
2578
            // and as a result these types received lower ids too
2579
0
            typeId +=1;
2580
0
        } else if (typeId == QMetaType::QPolygonF || typeId == QMetaType::QUuid) {
2581
            // These existed in Qt 4 only as a custom type
2582
0
            typeId = 127;
2583
0
            fakeUserType = true;
2584
0
        }
2585
0
    }
2586
0
    s << typeId;
2587
0
    if (s.version() >= QDataStream::Qt_4_2)
2588
0
        s << qint8(d.is_null);
2589
0
    if (d.type >= QVariant::UserType || fakeUserType) {
2590
0
        s << QMetaType::typeName(userType());
2591
0
    }
2592
2593
0
    if (!isValid()) {
2594
0
        if (s.version() < QDataStream::Qt_5_0)
2595
0
            s << QString();
2596
0
        return;
2597
0
    }
2598
2599
0
    if (!QMetaType::save(s, d.type, constData())) {
2600
0
        qWarning("QVariant::save: unable to save type '%s' (type id: %d).\n", QMetaType::typeName(d.type), d.type);
2601
0
        Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
2602
0
    }
2603
0
}
2604
2605
/*!
2606
    \since 4.4
2607
2608
    Reads a variant \a p from the stream \a s.
2609
2610
    \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2611
*/
2612
QDataStream& operator>>(QDataStream &s, QVariant &p)
2613
0
{
2614
0
    p.load(s);
2615
0
    return s;
2616
0
}
2617
2618
/*!
2619
    Writes a variant \a p to the stream \a s.
2620
2621
    \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2622
*/
2623
QDataStream& operator<<(QDataStream &s, const QVariant &p)
2624
0
{
2625
0
    p.save(s);
2626
0
    return s;
2627
0
}
2628
2629
/*!
2630
    Reads a variant type \a p in enum representation from the stream \a s.
2631
*/
2632
QDataStream& operator>>(QDataStream &s, QVariant::Type &p)
2633
0
{
2634
0
    quint32 u;
2635
0
    s >> u;
2636
0
    p = (QVariant::Type)u;
2637
2638
0
    return s;
2639
0
}
2640
2641
/*!
2642
    Writes a variant type \a p to the stream \a s.
2643
*/
2644
QDataStream& operator<<(QDataStream &s, const QVariant::Type p)
2645
0
{
2646
0
    s << static_cast<quint32>(p);
2647
2648
0
    return s;
2649
0
}
2650
2651
#endif //QT_NO_DATASTREAM
2652
2653
/*!
2654
    \fn bool QVariant::isValid() const
2655
2656
    Returns \c true if the storage type of this variant is not
2657
    QMetaType::UnknownType; otherwise returns \c false.
2658
*/
2659
2660
template <typename T>
2661
inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &handlerManager)
2662
10
{
2663
10
    const uint targetType = qMetaTypeId<T>();
2664
10
    if (d.type == targetType)
2665
0
        return *v_cast<T>(&d);
2666
2667
10
    T ret;
2668
10
    if (d.type >= QMetaType::User || targetType >= QMetaType::User) {
2669
0
        const void * const from = constData(d);
2670
0
        if (QMetaType::convert(from, d.type, &ret, targetType))
2671
0
            return ret;
2672
0
    }
2673
2674
10
    handlerManager[d.type]->convert(&d, targetType, &ret, nullptr);
2675
10
    return ret;
2676
10
}
Unexecuted instantiation: qvariant.cpp:QStringList qVariantToHelper<QStringList>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
qvariant.cpp:QString qVariantToHelper<QString>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Line
Count
Source
2662
10
{
2663
10
    const uint targetType = qMetaTypeId<T>();
2664
10
    if (d.type == targetType)
2665
0
        return *v_cast<T>(&d);
2666
2667
10
    T ret;
2668
10
    if (d.type >= QMetaType::User || targetType >= QMetaType::User) {
2669
0
        const void * const from = constData(d);
2670
0
        if (QMetaType::convert(from, d.type, &ret, targetType))
2671
0
            return ret;
2672
0
    }
2673
2674
10
    handlerManager[d.type]->convert(&d, targetType, &ret, nullptr);
2675
10
    return ret;
2676
10
}
Unexecuted instantiation: qvariant.cpp:QMap<QString, QVariant> qVariantToHelper<QMap<QString, QVariant> >(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QHash<QString, QVariant> qVariantToHelper<QHash<QString, QVariant> >(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QDate qVariantToHelper<QDate>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QTime qVariantToHelper<QTime>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QDateTime qVariantToHelper<QDateTime>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QEasingCurve qVariantToHelper<QEasingCurve>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QByteArray qVariantToHelper<QByteArray>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QPoint qVariantToHelper<QPoint>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QRect qVariantToHelper<QRect>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QSize qVariantToHelper<QSize>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QSizeF qVariantToHelper<QSizeF>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QRectF qVariantToHelper<QRectF>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QLineF qVariantToHelper<QLineF>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QLine qVariantToHelper<QLine>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QPointF qVariantToHelper<QPointF>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QUrl qVariantToHelper<QUrl>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QLocale qVariantToHelper<QLocale>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QRegExp qVariantToHelper<QRegExp>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QRegularExpression qVariantToHelper<QRegularExpression>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QModelIndex qVariantToHelper<QModelIndex>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QPersistentModelIndex qVariantToHelper<QPersistentModelIndex>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QUuid qVariantToHelper<QUuid>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QJsonValue qVariantToHelper<QJsonValue>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QJsonObject qVariantToHelper<QJsonObject>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QJsonArray qVariantToHelper<QJsonArray>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QJsonDocument qVariantToHelper<QJsonDocument>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QChar qVariantToHelper<QChar>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QBitArray qVariantToHelper<QBitArray>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
Unexecuted instantiation: qvariant.cpp:QList<QVariant> qVariantToHelper<QList<QVariant> >(QVariant::Private const&, (anonymous namespace)::HandlersManager const&)
2677
2678
/*!
2679
    \fn QStringList QVariant::toStringList() const
2680
2681
    Returns the variant as a QStringList if the variant has userType()
2682
    \l QMetaType::QStringList, \l QMetaType::QString, or
2683
    \l QMetaType::QVariantList of a type that can be converted to QString;
2684
    otherwise returns an empty list.
2685
2686
    \sa canConvert(int targetTypeId), convert()
2687
*/
2688
QStringList QVariant::toStringList() const
2689
0
{
2690
0
    return qVariantToHelper<QStringList>(d, handlerManager);
2691
0
}
2692
2693
/*!
2694
    Returns the variant as a QString if the variant has a userType()
2695
    including, but not limited to:
2696
2697
    \l QMetaType::QString, \l QMetaType::Bool, \l QMetaType::QByteArray,
2698
    \l QMetaType::QChar, \l QMetaType::QDate, \l QMetaType::QDateTime,
2699
    \l QMetaType::Double, \l QMetaType::Int, \l QMetaType::LongLong,
2700
    \l QMetaType::QStringList, \l QMetaType::QTime, \l QMetaType::UInt, or
2701
    \l QMetaType::ULongLong.
2702
2703
    Calling QVariant::toString() on an unsupported variant returns an empty
2704
    string.
2705
2706
    \sa canConvert(int targetTypeId), convert()
2707
*/
2708
QString QVariant::toString() const
2709
10
{
2710
10
    return qVariantToHelper<QString>(d, handlerManager);
2711
10
}
2712
2713
/*!
2714
    Returns the variant as a QMap<QString, QVariant> if the variant
2715
    has type() \l QMetaType::QVariantMap; otherwise returns an empty map.
2716
2717
    \sa canConvert(int targetTypeId), convert()
2718
*/
2719
QVariantMap QVariant::toMap() const
2720
0
{
2721
0
    return qVariantToHelper<QVariantMap>(d, handlerManager);
2722
0
}
2723
2724
/*!
2725
    Returns the variant as a QHash<QString, QVariant> if the variant
2726
    has type() \l QMetaType::QVariantHash; otherwise returns an empty map.
2727
2728
    \sa canConvert(int targetTypeId), convert()
2729
*/
2730
QVariantHash QVariant::toHash() const
2731
0
{
2732
0
    return qVariantToHelper<QVariantHash>(d, handlerManager);
2733
0
}
2734
2735
/*!
2736
    \fn QDate QVariant::toDate() const
2737
2738
    Returns the variant as a QDate if the variant has userType()
2739
    \l QMetaType::QDate, \l QMetaType::QDateTime, or \l QMetaType::QString;
2740
    otherwise returns an invalid date.
2741
2742
    If the type() is \l QMetaType::QString, an invalid date will be returned if
2743
    the string cannot be parsed as a Qt::ISODate format date.
2744
2745
    \sa canConvert(int targetTypeId), convert()
2746
*/
2747
QDate QVariant::toDate() const
2748
0
{
2749
0
    return qVariantToHelper<QDate>(d, handlerManager);
2750
0
}
2751
2752
/*!
2753
    \fn QTime QVariant::toTime() const
2754
2755
    Returns the variant as a QTime if the variant has userType()
2756
    \l QMetaType::QTime, \l QMetaType::QDateTime, or \l QMetaType::QString;
2757
    otherwise returns an invalid time.
2758
2759
    If the type() is \l QMetaType::QString, an invalid time will be returned if
2760
    the string cannot be parsed as a Qt::ISODate format time.
2761
2762
    \sa canConvert(int targetTypeId), convert()
2763
*/
2764
QTime QVariant::toTime() const
2765
0
{
2766
0
    return qVariantToHelper<QTime>(d, handlerManager);
2767
0
}
2768
2769
/*!
2770
    \fn QDateTime QVariant::toDateTime() const
2771
2772
    Returns the variant as a QDateTime if the variant has userType()
2773
    \l QMetaType::QDateTime, \l QMetaType::QDate, or \l QMetaType::QString;
2774
    otherwise returns an invalid date/time.
2775
2776
    If the type() is \l QMetaType::QString, an invalid date/time will be
2777
    returned if the string cannot be parsed as a Qt::ISODate format date/time.
2778
2779
    \sa canConvert(int targetTypeId), convert()
2780
*/
2781
QDateTime QVariant::toDateTime() const
2782
0
{
2783
0
    return qVariantToHelper<QDateTime>(d, handlerManager);
2784
0
}
2785
2786
/*!
2787
    \since 4.7
2788
    \fn QEasingCurve QVariant::toEasingCurve() const
2789
2790
    Returns the variant as a QEasingCurve if the variant has userType()
2791
    \l QMetaType::QEasingCurve; otherwise returns a default easing curve.
2792
2793
    \sa canConvert(int targetTypeId), convert()
2794
*/
2795
#if QT_CONFIG(easingcurve)
2796
QEasingCurve QVariant::toEasingCurve() const
2797
0
{
2798
0
    return qVariantToHelper<QEasingCurve>(d, handlerManager);
2799
0
}
2800
#endif
2801
2802
/*!
2803
    \fn QByteArray QVariant::toByteArray() const
2804
2805
    Returns the variant as a QByteArray if the variant has userType()
2806
    \l QMetaType::QByteArray or \l QMetaType::QString (converted using
2807
    QString::fromUtf8()); otherwise returns an empty byte array.
2808
2809
    \sa canConvert(int targetTypeId), convert()
2810
*/
2811
QByteArray QVariant::toByteArray() const
2812
0
{
2813
0
    return qVariantToHelper<QByteArray>(d, handlerManager);
2814
0
}
2815
2816
#ifndef QT_NO_GEOM_VARIANT
2817
/*!
2818
    \fn QPoint QVariant::toPoint() const
2819
2820
    Returns the variant as a QPoint if the variant has userType()
2821
    \l QMetaType::QPoint or \l QMetaType::QPointF; otherwise returns a null
2822
    QPoint.
2823
2824
    \sa canConvert(int targetTypeId), convert()
2825
*/
2826
QPoint QVariant::toPoint() const
2827
0
{
2828
0
    return qVariantToHelper<QPoint>(d, handlerManager);
2829
0
}
2830
2831
/*!
2832
    \fn QRect QVariant::toRect() const
2833
2834
    Returns the variant as a QRect if the variant has userType()
2835
    \l QMetaType::QRect; otherwise returns an invalid QRect.
2836
2837
    \sa canConvert(int targetTypeId), convert()
2838
*/
2839
QRect QVariant::toRect() const
2840
0
{
2841
0
    return qVariantToHelper<QRect>(d, handlerManager);
2842
0
}
2843
2844
/*!
2845
    \fn QSize QVariant::toSize() const
2846
2847
    Returns the variant as a QSize if the variant has userType()
2848
    \l QMetaType::QSize; otherwise returns an invalid QSize.
2849
2850
    \sa canConvert(int targetTypeId), convert()
2851
*/
2852
QSize QVariant::toSize() const
2853
0
{
2854
0
    return qVariantToHelper<QSize>(d, handlerManager);
2855
0
}
2856
2857
/*!
2858
    \fn QSizeF QVariant::toSizeF() const
2859
2860
    Returns the variant as a QSizeF if the variant has userType() \l
2861
    QMetaType::QSizeF; otherwise returns an invalid QSizeF.
2862
2863
    \sa canConvert(int targetTypeId), convert()
2864
*/
2865
QSizeF QVariant::toSizeF() const
2866
0
{
2867
0
    return qVariantToHelper<QSizeF>(d, handlerManager);
2868
0
}
2869
2870
/*!
2871
    \fn QRectF QVariant::toRectF() const
2872
2873
    Returns the variant as a QRectF if the variant has userType()
2874
    \l QMetaType::QRect or \l QMetaType::QRectF; otherwise returns an invalid
2875
    QRectF.
2876
2877
    \sa canConvert(int targetTypeId), convert()
2878
*/
2879
QRectF QVariant::toRectF() const
2880
0
{
2881
0
    return qVariantToHelper<QRectF>(d, handlerManager);
2882
0
}
2883
2884
/*!
2885
    \fn QLineF QVariant::toLineF() const
2886
2887
    Returns the variant as a QLineF if the variant has userType()
2888
    \l QMetaType::QLineF; otherwise returns an invalid QLineF.
2889
2890
    \sa canConvert(int targetTypeId), convert()
2891
*/
2892
QLineF QVariant::toLineF() const
2893
0
{
2894
0
    return qVariantToHelper<QLineF>(d, handlerManager);
2895
0
}
2896
2897
/*!
2898
    \fn QLine QVariant::toLine() const
2899
2900
    Returns the variant as a QLine if the variant has userType()
2901
    \l QMetaType::QLine; otherwise returns an invalid QLine.
2902
2903
    \sa canConvert(int targetTypeId), convert()
2904
*/
2905
QLine QVariant::toLine() const
2906
0
{
2907
0
    return qVariantToHelper<QLine>(d, handlerManager);
2908
0
}
2909
2910
/*!
2911
    \fn QPointF QVariant::toPointF() const
2912
2913
    Returns the variant as a QPointF if the variant has userType() \l
2914
    QMetaType::QPoint or \l QMetaType::QPointF; otherwise returns a null
2915
    QPointF.
2916
2917
    \sa canConvert(int targetTypeId), convert()
2918
*/
2919
QPointF QVariant::toPointF() const
2920
0
{
2921
0
    return qVariantToHelper<QPointF>(d, handlerManager);
2922
0
}
2923
2924
#endif // QT_NO_GEOM_VARIANT
2925
2926
#ifndef QT_BOOTSTRAPPED
2927
/*!
2928
    \fn QUrl QVariant::toUrl() const
2929
2930
    Returns the variant as a QUrl if the variant has userType()
2931
    \l QMetaType::QUrl; otherwise returns an invalid QUrl.
2932
2933
    \sa canConvert(int targetTypeId), convert()
2934
*/
2935
QUrl QVariant::toUrl() const
2936
0
{
2937
0
    return qVariantToHelper<QUrl>(d, handlerManager);
2938
0
}
2939
#endif
2940
2941
/*!
2942
    \fn QLocale QVariant::toLocale() const
2943
2944
    Returns the variant as a QLocale if the variant has userType()
2945
    \l QMetaType::QLocale; otherwise returns an invalid QLocale.
2946
2947
    \sa canConvert(int targetTypeId), convert()
2948
*/
2949
QLocale QVariant::toLocale() const
2950
0
{
2951
0
    return qVariantToHelper<QLocale>(d, handlerManager);
2952
0
}
2953
2954
/*!
2955
    \fn QRegExp QVariant::toRegExp() const
2956
    \since 4.1
2957
2958
    Returns the variant as a QRegExp if the variant has userType()
2959
    \l QMetaType::QRegExp; otherwise returns an empty QRegExp.
2960
2961
    \sa canConvert(int targetTypeId), convert()
2962
*/
2963
#ifndef QT_NO_REGEXP
2964
QRegExp QVariant::toRegExp() const
2965
0
{
2966
0
    return qVariantToHelper<QRegExp>(d, handlerManager);
2967
0
}
2968
#endif
2969
2970
#if QT_CONFIG(regularexpression)
2971
/*!
2972
    \fn QRegularExpression QVariant::toRegularExpression() const
2973
    \since 5.0
2974
2975
    Returns the variant as a QRegularExpression if the variant has userType() \l
2976
    QRegularExpression; otherwise returns an empty QRegularExpression.
2977
2978
    \sa canConvert(int targetTypeId), convert()
2979
*/
2980
QRegularExpression QVariant::toRegularExpression() const
2981
0
{
2982
0
    return qVariantToHelper<QRegularExpression>(d, handlerManager);
2983
0
}
2984
#endif // QT_CONFIG(regularexpression)
2985
2986
#if QT_CONFIG(itemmodel)
2987
/*!
2988
    \since 5.0
2989
2990
    Returns the variant as a QModelIndex if the variant has userType() \l
2991
    QModelIndex; otherwise returns a default constructed QModelIndex.
2992
2993
    \sa canConvert(int targetTypeId), convert(), toPersistentModelIndex()
2994
*/
2995
QModelIndex QVariant::toModelIndex() const
2996
0
{
2997
0
    return qVariantToHelper<QModelIndex>(d, handlerManager);
2998
0
}
2999
3000
/*!
3001
    \since 5.5
3002
3003
    Returns the variant as a QPersistentModelIndex if the variant has userType() \l
3004
    QPersistentModelIndex; otherwise returns a default constructed QPersistentModelIndex.
3005
3006
    \sa canConvert(int targetTypeId), convert(), toModelIndex()
3007
*/
3008
QPersistentModelIndex QVariant::toPersistentModelIndex() const
3009
0
{
3010
0
    return qVariantToHelper<QPersistentModelIndex>(d, handlerManager);
3011
0
}
3012
#endif // QT_CONFIG(itemmodel)
3013
3014
/*!
3015
    \since 5.0
3016
3017
    Returns the variant as a QUuid if the variant has type()
3018
    \l QMetaType::QUuid, \l QMetaType::QByteArray or \l QMetaType::QString;
3019
    otherwise returns a default-constructed QUuid.
3020
3021
    \sa canConvert(int targetTypeId), convert()
3022
*/
3023
QUuid QVariant::toUuid() const
3024
0
{
3025
0
    return qVariantToHelper<QUuid>(d, handlerManager);
3026
0
}
3027
3028
#ifndef QT_BOOTSTRAPPED
3029
/*!
3030
    \since 5.0
3031
3032
    Returns the variant as a QJsonValue if the variant has userType() \l
3033
    QJsonValue; otherwise returns a default constructed QJsonValue.
3034
3035
    \sa canConvert(int targetTypeId), convert()
3036
*/
3037
QJsonValue QVariant::toJsonValue() const
3038
0
{
3039
0
    return qVariantToHelper<QJsonValue>(d, handlerManager);
3040
0
}
3041
3042
/*!
3043
    \since 5.0
3044
3045
    Returns the variant as a QJsonObject if the variant has userType() \l
3046
    QJsonObject; otherwise returns a default constructed QJsonObject.
3047
3048
    \sa canConvert(int targetTypeId), convert()
3049
*/
3050
QJsonObject QVariant::toJsonObject() const
3051
0
{
3052
0
    return qVariantToHelper<QJsonObject>(d, handlerManager);
3053
0
}
3054
3055
/*!
3056
    \since 5.0
3057
3058
    Returns the variant as a QJsonArray if the variant has userType() \l
3059
    QJsonArray; otherwise returns a default constructed QJsonArray.
3060
3061
    \sa canConvert(int targetTypeId), convert()
3062
*/
3063
QJsonArray QVariant::toJsonArray() const
3064
0
{
3065
0
    return qVariantToHelper<QJsonArray>(d, handlerManager);
3066
0
}
3067
3068
/*!
3069
    \since 5.0
3070
3071
    Returns the variant as a QJsonDocument if the variant has userType() \l
3072
    QJsonDocument; otherwise returns a default constructed QJsonDocument.
3073
3074
    \sa canConvert(int targetTypeId), convert()
3075
*/
3076
QJsonDocument QVariant::toJsonDocument() const
3077
0
{
3078
0
    return qVariantToHelper<QJsonDocument>(d, handlerManager);
3079
0
}
3080
#endif // QT_BOOTSTRAPPED
3081
3082
/*!
3083
    \fn QChar QVariant::toChar() const
3084
3085
    Returns the variant as a QChar if the variant has userType()
3086
    \l QMetaType::QChar, \l QMetaType::Int, or \l QMetaType::UInt; otherwise
3087
    returns an invalid QChar.
3088
3089
    \sa canConvert(int targetTypeId), convert()
3090
*/
3091
QChar QVariant::toChar() const
3092
0
{
3093
0
    return qVariantToHelper<QChar>(d, handlerManager);
3094
0
}
3095
3096
/*!
3097
    Returns the variant as a QBitArray if the variant has userType()
3098
    \l QMetaType::QBitArray; otherwise returns an empty bit array.
3099
3100
    \sa canConvert(int targetTypeId), convert()
3101
*/
3102
QBitArray QVariant::toBitArray() const
3103
0
{
3104
0
    return qVariantToHelper<QBitArray>(d, handlerManager);
3105
0
}
3106
3107
template <typename T>
3108
inline T qNumVariantToHelper(const QVariant::Private &d,
3109
                             const HandlersManager &handlerManager, bool *ok, const T& val)
3110
0
{
3111
0
    const uint t = qMetaTypeId<T>();
3112
0
    if (ok)
3113
0
        *ok = true;
3114
3115
0
    if (d.type == t)
3116
0
        return val;
3117
3118
0
    T ret = 0;
3119
0
    if ((d.type >= QMetaType::User || t >= QMetaType::User)
3120
0
        && QMetaType::convert(constData(d), d.type, &ret, t))
3121
0
        return ret;
3122
3123
0
    if (!handlerManager[d.type]->convert(&d, t, &ret, ok) && ok)
3124
0
        *ok = false;
3125
0
    return ret;
3126
0
}
Unexecuted instantiation: qvariant.cpp:int qNumVariantToHelper<int>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&, bool*, int const&)
Unexecuted instantiation: qvariant.cpp:unsigned int qNumVariantToHelper<unsigned int>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&, bool*, unsigned int const&)
Unexecuted instantiation: qvariant.cpp:long long qNumVariantToHelper<long long>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&, bool*, long long const&)
Unexecuted instantiation: qvariant.cpp:unsigned long long qNumVariantToHelper<unsigned long long>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&, bool*, unsigned long long const&)
Unexecuted instantiation: qvariant.cpp:double qNumVariantToHelper<double>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&, bool*, double const&)
Unexecuted instantiation: qvariant.cpp:float qNumVariantToHelper<float>(QVariant::Private const&, (anonymous namespace)::HandlersManager const&, bool*, float const&)
3127
3128
/*!
3129
    Returns the variant as an int if the variant has userType()
3130
    \l QMetaType::Int, \l QMetaType::Bool, \l QMetaType::QByteArray,
3131
    \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::LongLong,
3132
    \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3133
    otherwise returns 0.
3134
3135
    If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3136
    converted to an int; otherwise \c{*}\a{ok} is set to false.
3137
3138
    \b{Warning:} If the value is convertible to a \l QMetaType::LongLong but is
3139
    too large to be represented in an int, the resulting arithmetic overflow
3140
    will not be reflected in \a ok. A simple workaround is to use
3141
    QString::toInt().
3142
3143
    \sa canConvert(int targetTypeId), convert()
3144
*/
3145
int QVariant::toInt(bool *ok) const
3146
0
{
3147
0
    return qNumVariantToHelper<int>(d, handlerManager, ok, d.data.i);
3148
0
}
3149
3150
/*!
3151
    Returns the variant as an unsigned int if the variant has userType()
3152
    \l QMetaType::UInt, \l QMetaType::Bool, \l QMetaType::QByteArray,
3153
    \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
3154
    \l QMetaType::LongLong, \l QMetaType::QString, or \l QMetaType::ULongLong;
3155
    otherwise returns 0.
3156
3157
    If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3158
    converted to an unsigned int; otherwise \c{*}\a{ok} is set to false.
3159
3160
    \b{Warning:} If the value is convertible to a \l QMetaType::ULongLong but is
3161
    too large to be represented in an unsigned int, the resulting arithmetic
3162
    overflow will not be reflected in \a ok. A simple workaround is to use
3163
    QString::toUInt().
3164
3165
    \sa canConvert(int targetTypeId), convert()
3166
*/
3167
uint QVariant::toUInt(bool *ok) const
3168
0
{
3169
0
    return qNumVariantToHelper<uint>(d, handlerManager, ok, d.data.u);
3170
0
}
3171
3172
/*!
3173
    Returns the variant as a long long int if the variant has userType()
3174
    \l QMetaType::LongLong, \l QMetaType::Bool, \l QMetaType::QByteArray,
3175
    \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
3176
    \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3177
    otherwise returns 0.
3178
3179
    If \a ok is non-null: \c{*}\c{ok} is set to true if the value could be
3180
    converted to an int; otherwise \c{*}\c{ok} is set to false.
3181
3182
    \sa canConvert(int targetTypeId), convert()
3183
*/
3184
qlonglong QVariant::toLongLong(bool *ok) const
3185
0
{
3186
0
    return qNumVariantToHelper<qlonglong>(d, handlerManager, ok, d.data.ll);
3187
0
}
3188
3189
/*!
3190
    Returns the variant as an unsigned long long int if the
3191
    variant has type() \l QMetaType::ULongLong, \l QMetaType::Bool,
3192
    \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::Double,
3193
    \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString, or
3194
    \l QMetaType::UInt; otherwise returns 0.
3195
3196
    If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3197
    converted to an int; otherwise \c{*}\a{ok} is set to false.
3198
3199
    \sa canConvert(int targetTypeId), convert()
3200
*/
3201
qulonglong QVariant::toULongLong(bool *ok) const
3202
0
{
3203
0
    return qNumVariantToHelper<qulonglong>(d, handlerManager, ok, d.data.ull);
3204
0
}
3205
3206
/*!
3207
    Returns the variant as a bool if the variant has userType() Bool.
3208
3209
    Returns \c true if the variant has userType() \l QMetaType::Bool,
3210
    \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
3211
    \l QMetaType::LongLong, \l QMetaType::UInt, or \l QMetaType::ULongLong and
3212
    the value is non-zero, or if the variant has type \l QMetaType::QString or
3213
    \l QMetaType::QByteArray and its lower-case content is not one of the
3214
    following: empty, "0" or "false"; otherwise returns \c false.
3215
3216
    \sa canConvert(int targetTypeId), convert()
3217
*/
3218
bool QVariant::toBool() const
3219
0
{
3220
0
    if (d.type == Bool)
3221
0
        return d.data.b;
3222
3223
0
    bool res = false;
3224
0
    handlerManager[d.type]->convert(&d, Bool, &res, nullptr);
3225
3226
0
    return res;
3227
0
}
3228
3229
/*!
3230
    Returns the variant as a double if the variant has userType()
3231
    \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
3232
    \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
3233
    \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3234
    otherwise returns 0.0.
3235
3236
    If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3237
    converted to a double; otherwise \c{*}\a{ok} is set to false.
3238
3239
    \sa canConvert(int targetTypeId), convert()
3240
*/
3241
double QVariant::toDouble(bool *ok) const
3242
0
{
3243
0
    return qNumVariantToHelper<double>(d, handlerManager, ok, d.data.d);
3244
0
}
3245
3246
/*!
3247
    Returns the variant as a float if the variant has userType()
3248
    \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
3249
    \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
3250
    \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3251
    otherwise returns 0.0.
3252
3253
    \since 4.6
3254
3255
    If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3256
    converted to a double; otherwise \c{*}\a{ok} is set to false.
3257
3258
    \sa canConvert(int targetTypeId), convert()
3259
*/
3260
float QVariant::toFloat(bool *ok) const
3261
0
{
3262
0
    return qNumVariantToHelper<float>(d, handlerManager, ok, d.data.f);
3263
0
}
3264
3265
/*!
3266
    Returns the variant as a qreal if the variant has userType()
3267
    \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
3268
    \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
3269
    \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3270
    otherwise returns 0.0.
3271
3272
    \since 4.6
3273
3274
    If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3275
    converted to a double; otherwise \c{*}\a{ok} is set to false.
3276
3277
    \sa canConvert(int targetTypeId), convert()
3278
*/
3279
qreal QVariant::toReal(bool *ok) const
3280
0
{
3281
0
    return qNumVariantToHelper<qreal>(d, handlerManager, ok, d.data.real);
3282
0
}
3283
3284
/*!
3285
    Returns the variant as a QVariantList if the variant has userType()
3286
    \l QMetaType::QVariantList or \l QMetaType::QStringList; otherwise returns
3287
    an empty list.
3288
3289
    \sa canConvert(int targetTypeId), convert()
3290
*/
3291
QVariantList QVariant::toList() const
3292
0
{
3293
0
    return qVariantToHelper<QVariantList>(d, handlerManager);
3294
0
}
3295
3296
3297
static const quint32 qCanConvertMatrix[QMetaType::LastCoreType + 1] =
3298
{
3299
/*Invalid*/     0,
3300
3301
/*Bool*/          1 << QMetaType::Double     | 1 << QMetaType::Int        | 1 << QMetaType::UInt
3302
                | 1 << QMetaType::LongLong   | 1 << QMetaType::ULongLong  | 1 << QMetaType::QByteArray
3303
                | 1 << QMetaType::QString     | 1 << QMetaType::QChar,
3304
3305
/*Int*/           1 << QMetaType::UInt       | 1 << QMetaType::QString     | 1 << QMetaType::Double
3306
                | 1 << QMetaType::Bool       | 1 << QMetaType::LongLong   | 1 << QMetaType::ULongLong
3307
                | 1 << QMetaType::QChar       | 1 << QMetaType::QByteArray  | 1 << QMetaType::Int,
3308
3309
/*UInt*/          1 << QMetaType::Int        | 1 << QMetaType::QString     | 1 << QMetaType::Double
3310
                | 1 << QMetaType::Bool       | 1 << QMetaType::LongLong   | 1 << QMetaType::ULongLong
3311
                | 1 << QMetaType::QChar       | 1 << QMetaType::QByteArray,
3312
3313
/*LLong*/         1 << QMetaType::Int        | 1 << QMetaType::QString     | 1 << QMetaType::Double
3314
                | 1 << QMetaType::Bool       | 1 << QMetaType::UInt       | 1 << QMetaType::ULongLong
3315
                | 1 << QMetaType::QChar       | 1 << QMetaType::QByteArray,
3316
3317
/*ULlong*/        1 << QMetaType::Int        | 1 << QMetaType::QString     | 1 << QMetaType::Double
3318
                | 1 << QMetaType::Bool       | 1 << QMetaType::UInt       | 1 << QMetaType::LongLong
3319
                | 1 << QMetaType::QChar       | 1 << QMetaType::QByteArray,
3320
3321
/*double*/        1 << QMetaType::Int        | 1 << QMetaType::QString     | 1 << QMetaType::ULongLong
3322
                | 1 << QMetaType::Bool       | 1 << QMetaType::UInt       | 1 << QMetaType::LongLong
3323
                | 1 << QMetaType::QByteArray,
3324
3325
/*QChar*/         1 << QMetaType::Int        | 1 << QMetaType::UInt       | 1 << QMetaType::LongLong
3326
                | 1 << QMetaType::ULongLong,
3327
3328
/*QMap*/          0,
3329
3330
/*QList*/         1 << QMetaType::QStringList,
3331
3332
/*QString*/       1 << QMetaType::QStringList | 1 << QMetaType::QByteArray  | 1 << QMetaType::Int
3333
                | 1 << QMetaType::UInt       | 1 << QMetaType::Bool       | 1 << QMetaType::Double
3334
                | 1 << QMetaType::QDate       | 1 << QMetaType::QTime       | 1 << QMetaType::QDateTime
3335
                | 1 << QMetaType::LongLong   | 1 << QMetaType::ULongLong  | 1 << QMetaType::QChar
3336
                | 1 << QMetaType::QUrl        | 1 << QMetaType::QUuid,
3337
3338
/*QStringList*/   1 << QMetaType::QVariantList       | 1 << QMetaType::QString,
3339
3340
/*QByteArray*/    1 << QMetaType::QString     | 1 << QMetaType::Int        | 1 << QMetaType::UInt | 1 << QMetaType::Bool
3341
                | 1 << QMetaType::Double     | 1 << QMetaType::LongLong   | 1 << QMetaType::ULongLong
3342
                | 1 << QMetaType::QUuid,
3343
3344
/*QBitArray*/     0,
3345
3346
/*QDate*/         1 << QMetaType::QString     | 1 << QMetaType::QDateTime,
3347
3348
/*QTime*/         1 << QMetaType::QString     | 1 << QMetaType::QDateTime,
3349
3350
/*QDateTime*/     1 << QMetaType::QString     | 1 << QMetaType::QDate,
3351
3352
/*QUrl*/          1 << QMetaType::QString,
3353
3354
/*QLocale*/       0,
3355
3356
/*QRect*/         1 << QMetaType::QRectF,
3357
3358
/*QRectF*/        1 << QMetaType::QRect,
3359
3360
/*QSize*/         1 << QMetaType::QSizeF,
3361
3362
/*QSizeF*/        1 << QMetaType::QSize,
3363
3364
/*QLine*/         1 << QMetaType::QLineF,
3365
3366
/*QLineF*/        1 << QMetaType::QLine,
3367
3368
/*QPoint*/        1 << QMetaType::QPointF,
3369
3370
/*QPointF*/       1 << QMetaType::QPoint,
3371
3372
/*QRegExp*/       0,
3373
3374
/*QHash*/         0,
3375
3376
/*QEasingCurve*/  0,
3377
3378
/*QUuid*/         1 << QMetaType::QString     | 1 << QMetaType::QByteArray,
3379
};
3380
static const size_t qCanConvertMatrixMaximumTargetType = 8 * sizeof(*qCanConvertMatrix);
3381
3382
#ifndef QT_BOOTSTRAPPED
3383
/*
3384
    Returns \c true if from inherits to.
3385
*/
3386
static bool canConvertMetaObject(const QMetaObject *from, const QMetaObject *to)
3387
0
{
3388
0
    if (from && to == &QObject::staticMetaObject)
3389
0
        return true;
3390
3391
0
    while (from) {
3392
0
        if (from == to)
3393
0
            return true;
3394
0
        from = from->superClass();
3395
0
    }
3396
3397
0
    return false;
3398
0
}
3399
#endif
3400
3401
static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject)
3402
0
{
3403
0
#ifndef QT_BOOTSTRAPPED
3404
0
    QMetaType toType(toId);
3405
0
    if ((QMetaType::typeFlags(fromId) & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
3406
0
        if (!fromObject)
3407
0
            return true;
3408
0
        return canConvertMetaObject(fromObject->metaObject(), toType.metaObject());
3409
0
    }
3410
#else
3411
    Q_UNUSED(fromId);
3412
    Q_UNUSED(toId);
3413
    Q_UNUSED(fromObject);
3414
#endif
3415
0
    return false;
3416
0
}
3417
3418
3419
/*!
3420
    Returns \c true if the variant's type can be cast to the requested
3421
    type, \a targetTypeId. Such casting is done automatically when calling the
3422
    toInt(), toBool(), ... methods.
3423
3424
    The following casts are done automatically:
3425
3426
    \table
3427
    \header \li Type \li Automatically Cast To
3428
    \row \li \l QMetaType::Bool \li \l QMetaType::QChar, \l QMetaType::Double,
3429
        \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString,
3430
        \l QMetaType::UInt, \l QMetaType::ULongLong
3431
    \row \li \l QMetaType::QByteArray \li \l QMetaType::Double,
3432
        \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString,
3433
        \l QMetaType::UInt, \l QMetaType::ULongLong, \l QMetaType::QUuid
3434
    \row \li \l QMetaType::QChar \li \l QMetaType::Bool, \l QMetaType::Int,
3435
        \l QMetaType::UInt, \l QMetaType::LongLong, \l QMetaType::ULongLong
3436
    \row \li \l QMetaType::QColor \li \l QMetaType::QString
3437
    \row \li \l QMetaType::QDate \li \l QMetaType::QDateTime,
3438
        \l QMetaType::QString
3439
    \row \li \l QMetaType::QDateTime \li \l QMetaType::QDate,
3440
        \l QMetaType::QString, \l QMetaType::QTime
3441
    \row \li \l QMetaType::Double \li \l QMetaType::Bool, \l QMetaType::Int,
3442
        \l QMetaType::LongLong, \l QMetaType::QString, \l QMetaType::UInt,
3443
        \l QMetaType::ULongLong
3444
    \row \li \l QMetaType::QFont \li \l QMetaType::QString
3445
    \row \li \l QMetaType::Int \li \l QMetaType::Bool, \l QMetaType::QChar,
3446
        \l QMetaType::Double, \l QMetaType::LongLong, \l QMetaType::QString,
3447
        \l QMetaType::UInt, \l QMetaType::ULongLong
3448
    \row \li \l QMetaType::QKeySequence \li \l QMetaType::Int,
3449
        \l QMetaType::QString
3450
    \row \li \l QMetaType::QVariantList \li \l QMetaType::QStringList (if the
3451
        list's items can be converted to QStrings)
3452
    \row \li \l QMetaType::LongLong \li \l QMetaType::Bool,
3453
        \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::Double,
3454
        \l QMetaType::Int, \l QMetaType::QString, \l QMetaType::UInt,
3455
        \l QMetaType::ULongLong
3456
    \row \li \l QMetaType::QPoint \li QMetaType::QPointF
3457
    \row \li \l QMetaType::QRect \li QMetaType::QRectF
3458
    \row \li \l QMetaType::QString \li \l QMetaType::Bool,
3459
        \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::QColor,
3460
        \l QMetaType::QDate, \l QMetaType::QDateTime, \l QMetaType::Double,
3461
        \l QMetaType::QFont, \l QMetaType::Int, \l QMetaType::QKeySequence,
3462
        \l QMetaType::LongLong, \l QMetaType::QStringList, \l QMetaType::QTime,
3463
        \l QMetaType::UInt, \l QMetaType::ULongLong, \l QMetaType::QUuid
3464
    \row \li \l QMetaType::QStringList \li \l QMetaType::QVariantList,
3465
        \l QMetaType::QString (if the list contains exactly one item)
3466
    \row \li \l QMetaType::QTime \li \l QMetaType::QString
3467
    \row \li \l QMetaType::UInt \li \l QMetaType::Bool, \l QMetaType::QChar,
3468
        \l QMetaType::Double, \l QMetaType::Int, \l QMetaType::LongLong,
3469
        \l QMetaType::QString, \l QMetaType::ULongLong
3470
    \row \li \l QMetaType::ULongLong \li \l QMetaType::Bool,
3471
        \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
3472
        \l QMetaType::LongLong, \l QMetaType::QString, \l QMetaType::UInt
3473
    \row \li \l QMetaType::QUuid \li \l QMetaType::QByteArray, \l QMetaType::QString
3474
    \endtable
3475
3476
    A QVariant containing a pointer to a type derived from QObject will also return true for this
3477
    function if a qobject_cast to the type described by \a targetTypeId would succeed. Note that
3478
    this only works for QObject subclasses which use the Q_OBJECT macro.
3479
3480
    A QVariant containing a sequential container will also return true for this
3481
    function if the \a targetTypeId is QVariantList. It is possible to iterate over
3482
    the contents of the container without extracting it as a (copied) QVariantList:
3483
3484
    \snippet code/src_corelib_kernel_qvariant.cpp 9
3485
3486
    This requires that the value_type of the container is itself a metatype.
3487
3488
    Similarly, a QVariant containing a sequential container will also return true for this
3489
    function the \a targetTypeId is QVariantHash or QVariantMap. It is possible to iterate over
3490
    the contents of the container without extracting it as a (copied) QVariantHash or QVariantMap:
3491
3492
    \snippet code/src_corelib_kernel_qvariant.cpp 10
3493
3494
    \sa convert(), QSequentialIterable, Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(), QAssociativeIterable,
3495
        Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE()
3496
*/
3497
bool QVariant::canConvert(int targetTypeId) const
3498
0
{
3499
0
    if (d.type == targetTypeId)
3500
0
        return true;
3501
3502
0
#if QT_CONFIG(itemmodel)
3503
0
    if ((targetTypeId == QMetaType::QModelIndex && d.type == QMetaType::QPersistentModelIndex)
3504
0
        || (targetTypeId == QMetaType::QPersistentModelIndex && d.type == QMetaType::QModelIndex))
3505
0
        return true;
3506
0
#endif
3507
3508
0
    if (targetTypeId == QMetaType::QVariantList
3509
0
            && (d.type == QMetaType::QVariantList
3510
0
              || d.type == QMetaType::QStringList
3511
0
              || d.type == QMetaType::QByteArrayList
3512
0
              || QMetaType::hasRegisteredConverterFunction(d.type,
3513
0
                    qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>()))) {
3514
0
        return true;
3515
0
    }
3516
3517
0
    if ((targetTypeId == QMetaType::QVariantHash || targetTypeId == QMetaType::QVariantMap)
3518
0
            && (d.type == QMetaType::QVariantMap
3519
0
              || d.type == QMetaType::QVariantHash
3520
0
              || QMetaType::hasRegisteredConverterFunction(d.type,
3521
0
                    qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()))) {
3522
0
        return true;
3523
0
    }
3524
3525
0
    if (targetTypeId == qMetaTypeId<QPair<QVariant, QVariant> >() &&
3526
0
              QMetaType::hasRegisteredConverterFunction(d.type,
3527
0
                    qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
3528
0
        return true;
3529
0
    }
3530
3531
0
    if ((d.type >= QMetaType::User || targetTypeId >= QMetaType::User)
3532
0
        && QMetaType::hasRegisteredConverterFunction(d.type, targetTypeId)) {
3533
0
        return true;
3534
0
    }
3535
3536
    // TODO Reimplement this function, currently it works but it is a historical mess.
3537
0
    uint currentType = d.type;
3538
0
    if (currentType == QMetaType::SChar || currentType == QMetaType::Char)
3539
0
        currentType = QMetaType::UInt;
3540
0
    if (targetTypeId == QMetaType::SChar || currentType == QMetaType::Char)
3541
0
        targetTypeId = QMetaType::UInt;
3542
0
    if (currentType == QMetaType::Short || currentType == QMetaType::UShort)
3543
0
        currentType = QMetaType::Int;
3544
0
    if (targetTypeId == QMetaType::Short || currentType == QMetaType::UShort)
3545
0
        targetTypeId = QMetaType::Int;
3546
0
    if (currentType == QMetaType::Float)
3547
0
        currentType = QMetaType::Double;
3548
0
    if (targetTypeId == QMetaType::Float)
3549
0
        targetTypeId = QMetaType::Double;
3550
3551
0
    if (currentType == uint(targetTypeId))
3552
0
        return true;
3553
3554
0
    if (targetTypeId < 0)
3555
0
        return false;
3556
0
    if (targetTypeId >= QMetaType::User) {
3557
0
        if (QMetaType::typeFlags(targetTypeId) & QMetaType::IsEnumeration) {
3558
0
            targetTypeId = QMetaType::Int;
3559
0
        } else {
3560
0
            return canConvertMetaObject(currentType, targetTypeId, d.data.o);
3561
0
        }
3562
0
    }
3563
3564
0
    if (currentType == QMetaType::QJsonValue || targetTypeId == QMetaType::QJsonValue) {
3565
0
        switch (currentType == QMetaType::QJsonValue ? targetTypeId : currentType) {
3566
0
        case QMetaType::Nullptr:
3567
0
        case QMetaType::QString:
3568
0
        case QMetaType::Bool:
3569
0
        case QMetaType::Int:
3570
0
        case QMetaType::UInt:
3571
0
        case QMetaType::Double:
3572
0
        case QMetaType::Float:
3573
0
        case QMetaType::ULong:
3574
0
        case QMetaType::Long:
3575
0
        case QMetaType::LongLong:
3576
0
        case QMetaType::ULongLong:
3577
0
        case QMetaType::UShort:
3578
0
        case QMetaType::UChar:
3579
0
        case QMetaType::Char:
3580
0
        case QMetaType::SChar:
3581
0
        case QMetaType::Short:
3582
0
        case QMetaType::QVariantList:
3583
0
        case QMetaType::QVariantMap:
3584
0
        case QMetaType::QVariantHash:
3585
0
        case QMetaType::QCborValue:
3586
0
        case QMetaType::QCborArray:
3587
0
        case QMetaType::QCborMap:
3588
0
            return true;
3589
0
        default:
3590
0
            return false;
3591
0
        }
3592
0
    }
3593
0
    if (currentType == QMetaType::QJsonArray)
3594
0
        return targetTypeId == QMetaType::QVariantList || targetTypeId == QMetaType::QCborValue
3595
0
                || targetTypeId == QMetaType::QCborArray;
3596
0
    if (currentType == QMetaType::QJsonObject)
3597
0
        return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash
3598
0
                || targetTypeId == QMetaType::QCborValue || targetTypeId == QMetaType::QCborMap;
3599
3600
0
    if (currentType == QMetaType::QCborValue || targetTypeId == QMetaType::QCborValue) {
3601
0
        switch (currentType == QMetaType::QCborValue ? targetTypeId : currentType) {
3602
0
        case QMetaType::UnknownType:
3603
0
        case QMetaType::Nullptr:
3604
0
        case QMetaType::Bool:
3605
0
        case QMetaType::Int:
3606
0
        case QMetaType::UInt:
3607
0
        case QMetaType::Double:
3608
0
        case QMetaType::Float:
3609
0
        case QMetaType::ULong:
3610
0
        case QMetaType::Long:
3611
0
        case QMetaType::LongLong:
3612
0
        case QMetaType::ULongLong:
3613
0
        case QMetaType::UShort:
3614
0
        case QMetaType::UChar:
3615
0
        case QMetaType::Char:
3616
0
        case QMetaType::SChar:
3617
0
        case QMetaType::Short:
3618
0
        case QMetaType::QString:
3619
0
        case QMetaType::QByteArray:
3620
0
        case QMetaType::QDateTime:
3621
0
        case QMetaType::QUrl:
3622
0
        case QMetaType::QRegularExpression:
3623
0
        case QMetaType::QUuid:
3624
0
        case QMetaType::QVariantList:
3625
0
        case QMetaType::QVariantMap:
3626
0
        case QMetaType::QVariantHash:
3627
0
        case QMetaType::QJsonValue:
3628
0
        case QMetaType::QJsonArray:
3629
0
        case QMetaType::QJsonObject:
3630
0
        case QMetaType::QJsonDocument:
3631
0
        case QMetaType::QCborArray:
3632
0
        case QMetaType::QCborMap:
3633
0
        case QMetaType::QCborSimpleType:
3634
0
            return true;
3635
0
        default:
3636
0
            return false;
3637
0
        }
3638
0
    }
3639
0
    if (currentType == QMetaType::QCborArray)
3640
0
        return targetTypeId == QMetaType::QVariantList || targetTypeId == QMetaType::QCborValue
3641
0
                || targetTypeId == QMetaType::QJsonArray;
3642
0
    if (currentType == QMetaType::QCborMap)
3643
0
        return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash
3644
0
                || targetTypeId == QMetaType::QCborValue || targetTypeId == QMetaType::QJsonObject;
3645
3646
    // FIXME It should be LastCoreType intead of Uuid
3647
0
    if (currentType > int(QMetaType::QUuid) || targetTypeId > int(QMetaType::QUuid)) {
3648
0
        switch (uint(targetTypeId)) {
3649
0
        case QVariant::Int:
3650
0
            if (currentType == QVariant::KeySequence)
3651
0
                return true;
3652
0
            Q_FALLTHROUGH();
3653
0
        case QVariant::UInt:
3654
0
        case QVariant::LongLong:
3655
0
        case QVariant::ULongLong:
3656
0
               return currentType == QMetaType::ULong
3657
0
                   || currentType == QMetaType::Long
3658
0
                   || currentType == QMetaType::UShort
3659
0
                   || currentType == QMetaType::UChar
3660
0
                   || currentType == QMetaType::Char
3661
0
                   || currentType == QMetaType::SChar
3662
0
                   || currentType == QMetaType::Short
3663
0
                   || QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration;
3664
0
        case QVariant::Image:
3665
0
            return currentType == QVariant::Pixmap || currentType == QVariant::Bitmap;
3666
0
        case QVariant::Pixmap:
3667
0
            return currentType == QVariant::Image || currentType == QVariant::Bitmap
3668
0
                              || currentType == QVariant::Brush;
3669
0
        case QVariant::Bitmap:
3670
0
            return currentType == QVariant::Pixmap || currentType == QVariant::Image;
3671
0
        case QVariant::ByteArray:
3672
0
            return currentType == QVariant::Color || currentType == QMetaType::Nullptr
3673
0
                              || ((QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration) && QMetaType::metaObjectForType(currentType));
3674
0
        case QVariant::String:
3675
0
            return currentType == QVariant::KeySequence || currentType == QVariant::Font
3676
0
                              || currentType == QVariant::Color || currentType == QMetaType::Nullptr
3677
0
                              || ((QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration) && QMetaType::metaObjectForType(currentType));
3678
0
        case QVariant::KeySequence:
3679
0
            return currentType == QVariant::String || currentType == QVariant::Int;
3680
0
        case QVariant::Font:
3681
0
            return currentType == QVariant::String;
3682
0
        case QVariant::Color:
3683
0
            return currentType == QVariant::String || currentType == QVariant::ByteArray
3684
0
                              || currentType == QVariant::Brush;
3685
0
        case QVariant::Brush:
3686
0
            return currentType == QVariant::Color || currentType == QVariant::Pixmap;
3687
0
        case QMetaType::Long:
3688
0
        case QMetaType::Char:
3689
0
        case QMetaType::SChar:
3690
0
        case QMetaType::UChar:
3691
0
        case QMetaType::ULong:
3692
0
        case QMetaType::Short:
3693
0
        case QMetaType::UShort:
3694
0
            return currentType == QVariant::Int
3695
0
                || (currentType < qCanConvertMatrixMaximumTargetType
3696
0
                    && qCanConvertMatrix[QVariant::Int] & (1U << currentType))
3697
0
                || QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration;
3698
0
        case QMetaType::QObjectStar:
3699
0
            return canConvertMetaObject(currentType, targetTypeId, d.data.o);
3700
0
        default:
3701
0
            return false;
3702
0
        }
3703
0
    }
3704
3705
0
    if (targetTypeId == String && currentType == StringList)
3706
0
        return v_cast<QStringList>(&d)->count() == 1;
3707
0
    return currentType < qCanConvertMatrixMaximumTargetType
3708
0
        && qCanConvertMatrix[targetTypeId] & (1U << currentType);
3709
0
}
3710
3711
/*!
3712
    Casts the variant to the requested type, \a targetTypeId. If the cast cannot be
3713
    done, the variant is still changed to the requested type, but is left in a cleared
3714
    null state similar to that constructed by QVariant(Type).
3715
3716
    Returns \c true if the current type of the variant was successfully cast;
3717
    otherwise returns \c false.
3718
3719
    A QVariant containing a pointer to a type derived from QObject will also convert
3720
    and return true for this function if a qobject_cast to the type described
3721
    by \a targetTypeId would succeed. Note that this only works for QObject subclasses
3722
    which use the Q_OBJECT macro.
3723
3724
    \note converting QVariants that are null due to not being initialized or having
3725
    failed a previous conversion will always fail, changing the type, remaining null,
3726
    and returning \c false.
3727
3728
    \sa canConvert(int targetTypeId), clear()
3729
*/
3730
3731
bool QVariant::convert(int targetTypeId)
3732
0
{
3733
0
    if (d.type == uint(targetTypeId))
3734
0
        return true;
3735
3736
0
    QVariant oldValue = *this;
3737
3738
0
    clear();
3739
0
    if (!oldValue.canConvert(targetTypeId))
3740
0
        return false;
3741
3742
0
    create(targetTypeId, nullptr);
3743
    // Fail if the value is not initialized or was forced null by a previous failed convert.
3744
0
    if (oldValue.d.is_null && oldValue.d.type != QMetaType::Nullptr)
3745
0
        return false;
3746
3747
0
    if ((QMetaType::typeFlags(oldValue.userType()) & QMetaType::PointerToQObject) && (QMetaType::typeFlags(targetTypeId) & QMetaType::PointerToQObject)) {
3748
0
        create(targetTypeId, &oldValue.d.data.o);
3749
0
        return true;
3750
0
    }
3751
3752
0
    bool isOk = true;
3753
0
    int converterType = std::max(oldValue.userType(), targetTypeId);
3754
0
    if (!handlerManager[converterType]->convert(&oldValue.d, targetTypeId, data(), &isOk))
3755
0
        isOk = false;
3756
0
    d.is_null = !isOk;
3757
0
    return isOk;
3758
0
}
3759
3760
/*!
3761
  \fn bool QVariant::convert(const int type, void *ptr) const
3762
  \internal
3763
  Created for qvariant_cast() usage
3764
*/
3765
bool QVariant::convert(const int type, void *ptr) const
3766
0
{
3767
0
    return handlerManager[type]->convert(&d, type, ptr, nullptr);
3768
0
}
3769
3770
3771
/*!
3772
    \fn bool operator==(const QVariant &v1, const QVariant &v2)
3773
3774
    \relates QVariant
3775
3776
    Returns \c true if \a v1 and \a v2 are equal; otherwise returns \c false.
3777
3778
    If \a v1 and \a v2 have the same \l{QVariant::}{type()}, the
3779
    type's equality operator is used for comparison. If not, it is
3780
    attempted to \l{QVariant::}{convert()} \a v2 to the same type as
3781
    \a v1. See \l{QVariant::}{canConvert()} for a list of possible
3782
    conversions.
3783
3784
    The result of the function is not affected by the result of QVariant::isNull,
3785
    which means that two values can be equal even if one of them is null and
3786
    another is not.
3787
3788
    \warning To make this function work with a custom type registered with
3789
    qRegisterMetaType(), its comparison operator must be registered using
3790
    QMetaType::registerComparators().
3791
*/
3792
/*!
3793
    \fn bool operator!=(const QVariant &v1, const QVariant &v2)
3794
3795
    \relates QVariant
3796
3797
    Returns \c false if \a v1 and \a v2 are equal; otherwise returns \c true.
3798
3799
    \warning To make this function work with a custom type registered with
3800
    qRegisterMetaType(), its comparison operator must be registered using
3801
    QMetaType::registerComparators().
3802
*/
3803
3804
/*! \fn bool QVariant::operator==(const QVariant &v) const
3805
3806
    Compares this QVariant with \a v and returns \c true if they are
3807
    equal; otherwise returns \c false.
3808
3809
    QVariant uses the equality operator of the type() it contains to
3810
    check for equality. QVariant will try to convert() \a v if its
3811
    type is not the same as this variant's type. See canConvert() for
3812
    a list of possible conversions.
3813
3814
    \warning To make this function work with a custom type registered with
3815
    qRegisterMetaType(), its comparison operator must be registered using
3816
    QMetaType::registerComparators().
3817
*/
3818
3819
/*!
3820
    \fn bool QVariant::operator!=(const QVariant &v) const
3821
3822
    Compares this QVariant with \a v and returns \c true if they are not
3823
    equal; otherwise returns \c false.
3824
3825
    \warning To make this function work with a custom type registered with
3826
    qRegisterMetaType(), its comparison operator must be registered using
3827
    QMetaType::registerComparators().
3828
*/
3829
3830
/*!
3831
    \fn bool QVariant::operator<(const QVariant &v) const
3832
    \obsolete
3833
3834
    Compares this QVariant with \a v and returns \c true if this is less than \a v.
3835
3836
    \note Comparability might not be availabe for the type stored in this QVariant
3837
    or in \a v.
3838
3839
    \warning To make this function work with a custom type registered with
3840
    qRegisterMetaType(), its comparison operator must be registered using
3841
    QMetaType::registerComparators().
3842
3843
    This operator is deprecated as it cannot establish a total order required
3844
    for most use of this operator, which is the reason you cannot use QVariant
3845
    as the key of a QMap.
3846
*/
3847
3848
/*!
3849
    \fn bool QVariant::operator<=(const QVariant &v) const
3850
    \obsolete
3851
3852
    Compares this QVariant with \a v and returns \c true if this is less or equal than \a v.
3853
3854
    \note Comparability might not be available for the type stored in this QVariant
3855
    or in \a v.
3856
3857
    \warning To make this function work with a custom type registered with
3858
    qRegisterMetaType(), its comparison operator must be registered using
3859
    QMetaType::registerComparators().
3860
3861
    This operator is deprecated as it cannot establish a total order.
3862
*/
3863
3864
/*!
3865
    \fn bool QVariant::operator>(const QVariant &v) const
3866
    \obsolete
3867
3868
    Compares this QVariant with \a v and returns \c true if this is larger than \a v.
3869
3870
    \note Comparability might not be available for the type stored in this QVariant
3871
    or in \a v.
3872
3873
    \warning To make this function work with a custom type registered with
3874
    qRegisterMetaType(), its comparison operator must be registered using
3875
    QMetaType::registerComparators().
3876
3877
    This operator is deprecated as it cannot establish a total order.
3878
*/
3879
3880
/*!
3881
    \fn bool QVariant::operator>=(const QVariant &v) const
3882
    \obsolete
3883
3884
    Compares this QVariant with \a v and returns \c true if this is larger or equal than \a v.
3885
3886
    \note Comparability might not be available for the type stored in this QVariant
3887
    or in \a v.
3888
3889
    \warning To make this function work with a custom type registered with
3890
    qRegisterMetaType(), its comparison operator must be registered using
3891
    QMetaType::registerComparators().
3892
3893
    This operator is deprecated as it cannot establish a total order.
3894
*/
3895
3896
static bool qIsNumericType(uint tp)
3897
0
{
3898
0
    static const qulonglong numericTypeBits =
3899
0
            Q_UINT64_C(1) << QMetaType::Bool |
3900
0
            Q_UINT64_C(1) << QMetaType::Double |
3901
0
            Q_UINT64_C(1) << QMetaType::Float |
3902
0
            Q_UINT64_C(1) << QMetaType::Char |
3903
0
            Q_UINT64_C(1) << QMetaType::SChar |
3904
0
            Q_UINT64_C(1) << QMetaType::UChar |
3905
0
            Q_UINT64_C(1) << QMetaType::Short |
3906
0
            Q_UINT64_C(1) << QMetaType::UShort |
3907
0
            Q_UINT64_C(1) << QMetaType::Int |
3908
0
            Q_UINT64_C(1) << QMetaType::UInt |
3909
0
            Q_UINT64_C(1) << QMetaType::Long |
3910
0
            Q_UINT64_C(1) << QMetaType::ULong |
3911
0
            Q_UINT64_C(1) << QMetaType::LongLong |
3912
0
            Q_UINT64_C(1) << QMetaType::ULongLong;
3913
0
    return tp < (CHAR_BIT * sizeof numericTypeBits) ? numericTypeBits & (Q_UINT64_C(1) << tp) : false;
3914
0
}
3915
3916
static bool qIsFloatingPoint(uint tp)
3917
0
{
3918
0
    return tp == QMetaType::Double || tp == QMetaType::Float;
3919
0
}
3920
3921
static int normalizeLowerRanks(uint tp)
3922
0
{
3923
0
    static const qulonglong numericTypeBits =
3924
0
            Q_UINT64_C(1) << QMetaType::Bool |
3925
0
            Q_UINT64_C(1) << QMetaType::Char |
3926
0
            Q_UINT64_C(1) << QMetaType::SChar |
3927
0
            Q_UINT64_C(1) << QMetaType::UChar |
3928
0
            Q_UINT64_C(1) << QMetaType::Short |
3929
0
            Q_UINT64_C(1) << QMetaType::UShort;
3930
0
    return numericTypeBits & (Q_UINT64_C(1) << tp) ? uint(QMetaType::Int) : tp;
3931
0
}
3932
3933
static int normalizeLong(uint tp)
3934
0
{
3935
0
    const uint IntType = sizeof(long) == sizeof(int) ? QMetaType::Int : QMetaType::LongLong;
3936
0
    const uint UIntType = sizeof(ulong) == sizeof(uint) ? QMetaType::UInt : QMetaType::ULongLong;
3937
0
    return tp == QMetaType::Long ? IntType :
3938
0
           tp == QMetaType::ULong ? UIntType : tp;
3939
0
}
3940
3941
static int numericTypePromotion(uint t1, uint t2)
3942
0
{
3943
0
    Q_ASSERT(qIsNumericType(t1));
3944
0
    Q_ASSERT(qIsNumericType(t2));
3945
3946
    // C++ integral ranks: (4.13 Integer conversion rank [conv.rank])
3947
    //   bool < signed char < short < int < long < long long
3948
    //   unsigneds have the same rank as their signed counterparts
3949
    // C++ integral promotion rules (4.5 Integral Promotions [conv.prom])
3950
    // - any type with rank less than int can be converted to int or unsigned int
3951
    // 5 Expressions [expr] paragraph 9:
3952
    // - if either operand is double, the other shall be converted to double
3953
    // -     "       "        float,   "          "         "         float
3954
    // - if both operands have the same type, no further conversion is needed.
3955
    // - if both are signed or if both are unsigned, convert to the one with highest rank
3956
    // - if the unsigned has higher or same rank, convert the signed to the unsigned one
3957
    // - if the signed can represent all values of the unsigned, convert to the signed
3958
    // - otherwise, convert to the unsigned corresponding to the rank of the signed
3959
3960
    // floating point: we deviate from the C++ standard by always using qreal
3961
0
    if (qIsFloatingPoint(t1) || qIsFloatingPoint(t2))
3962
0
        return QMetaType::QReal;
3963
3964
    // integral rules:
3965
    // for all platforms we support, int can always hold the values of lower-ranked types
3966
0
    t1 = normalizeLowerRanks(t1);
3967
0
    t2 = normalizeLowerRanks(t2);
3968
3969
    // normalize long / ulong: in all platforms we run, they're either the same as int or as long long
3970
0
    t1 = normalizeLong(t1);
3971
0
    t2 = normalizeLong(t2);
3972
3973
    // implement the other rules
3974
    // the four possibilities are Int, UInt, LongLong and ULongLong
3975
    // if any of the two is ULongLong, then it wins (highest rank, unsigned)
3976
    // otherwise, if one of the two is LongLong, then the other is either LongLong too or lower-ranked
3977
    // otherwise, if one of the two is UInt, then the other is either UInt too or Int
3978
0
    if (t1 == QMetaType::ULongLong || t2 == QMetaType::ULongLong)
3979
0
        return QMetaType::ULongLong;
3980
0
    if (t1 == QMetaType::LongLong || t2 == QMetaType::LongLong)
3981
0
        return QMetaType::LongLong;
3982
0
    if (t1 == QMetaType::UInt || t2 == QMetaType::UInt)
3983
0
        return QMetaType::UInt;
3984
0
    return QMetaType::Int;
3985
0
}
3986
3987
static int integralCompare(uint promotedType, const QVariant::Private *d1, const QVariant::Private *d2)
3988
0
{
3989
    // use toLongLong to retrieve the data, it gets us all the bits
3990
0
    bool ok;
3991
0
    qlonglong l1 = qConvertToNumber(d1, &ok);
3992
0
    Q_ASSERT(ok);
3993
3994
0
    qlonglong l2 = qConvertToNumber(d2, &ok);
3995
0
    Q_ASSERT(ok);
3996
3997
0
    if (promotedType == QMetaType::Int)
3998
0
        return int(l1) < int(l2) ? -1 : int(l1) == int(l2) ? 0 : 1;
3999
0
    if (promotedType == QMetaType::UInt)
4000
0
        return uint(l1) < uint(l2) ? -1 : uint(l1) == uint(l2) ? 0 : 1;
4001
0
    if (promotedType == QMetaType::LongLong)
4002
0
        return l1 < l2 ? -1 : l1 == l2 ? 0 : 1;
4003
0
    if (promotedType == QMetaType::ULongLong)
4004
0
        return qulonglong(l1) < qulonglong(l2) ? -1 : qulonglong(l1) == qulonglong(l2) ? 0 : 1;
4005
4006
0
    Q_UNREACHABLE();
4007
0
    return 0;
4008
0
}
4009
4010
static int numericCompare(const QVariant::Private *d1, const QVariant::Private *d2)
4011
0
{
4012
0
    uint promotedType = numericTypePromotion(d1->type, d2->type);
4013
0
    if (promotedType != QMetaType::QReal)
4014
0
        return integralCompare(promotedType, d1, d2);
4015
4016
    // qreal comparisons
4017
0
    bool ok;
4018
0
    qreal r1 = qConvertToRealNumber(d1, &ok);
4019
0
    Q_ASSERT(ok);
4020
0
    qreal r2 = qConvertToRealNumber(d2, &ok);
4021
0
    Q_ASSERT(ok);
4022
0
    if (r1 == r2)
4023
0
        return 0;
4024
4025
    // only do fuzzy comparisons for finite, non-zero numbers
4026
0
    int c1 = qFpClassify(r1);
4027
0
    int c2 = qFpClassify(r2);
4028
0
    if ((c1 == FP_NORMAL || c1 == FP_SUBNORMAL) && (c2 == FP_NORMAL || c2 == FP_SUBNORMAL)) {
4029
0
        if (qFuzzyCompare(r1, r2))
4030
0
            return 0;
4031
0
    }
4032
4033
0
    return r1 < r2 ? -1 : 1;
4034
0
}
4035
4036
/*!
4037
    \internal
4038
 */
4039
bool QVariant::cmp(const QVariant &v) const
4040
0
{
4041
0
    auto cmp_helper = [] (const QVariant::Private &d1, const QVariant::Private &d2)
4042
0
    {
4043
0
        Q_ASSERT(d1.type == d2.type);
4044
0
        if (d1.type >= QMetaType::User) {
4045
0
            int result;
4046
0
            if (QMetaType::equals(QT_PREPEND_NAMESPACE(constData(d1)), QT_PREPEND_NAMESPACE(constData(d2)), d1.type, &result))
4047
0
                return result == 0;
4048
0
        }
4049
0
        return handlerManager[d1.type]->compare(&d1, &d2);
4050
0
    };
4051
4052
    // try numerics first, with C++ type promotion rules (no conversion)
4053
0
    if (qIsNumericType(d.type) && qIsNumericType(v.d.type))
4054
0
        return numericCompare(&d, &v.d) == 0;
4055
4056
0
    if (d.type == v.d.type)
4057
0
        return cmp_helper(d, v.d);
4058
4059
0
    QVariant v1 = *this;
4060
0
    QVariant v2 = v;
4061
0
    if (v2.canConvert(v1.d.type)) {
4062
0
        if (!v2.convert(v1.d.type))
4063
0
            return false;
4064
0
    } else {
4065
        // try the opposite conversion, it might work
4066
0
        qSwap(v1, v2);
4067
0
        if (!v2.convert(v1.d.type))
4068
0
            return false;
4069
0
    }
4070
0
    return cmp_helper(v1.d, v2.d);
4071
0
}
4072
4073
/*!
4074
    \internal
4075
 */
4076
int QVariant::compare(const QVariant &v) const
4077
0
{
4078
    // try numerics first, with C++ type promotion rules (no conversion)
4079
0
    if (qIsNumericType(d.type) && qIsNumericType(v.d.type))
4080
0
        return numericCompare(&d, &v.d);
4081
4082
    // check for equality next, as more types implement operator== than operator<
4083
0
    if (cmp(v))
4084
0
        return 0;
4085
4086
0
    const QVariant *v1 = this;
4087
0
    const QVariant *v2 = &v;
4088
0
    QVariant converted1;
4089
0
    QVariant converted2;
4090
4091
0
    if (d.type != v.d.type) {
4092
        // if both types differ, try to convert
4093
0
        if (v2->canConvert(v1->d.type)) {
4094
0
            converted2 = *v2;
4095
0
            if (converted2.convert(v1->d.type))
4096
0
                v2 = &converted2;
4097
0
        }
4098
0
        if (v1->d.type != v2->d.type && v1->canConvert(v2->d.type)) {
4099
0
            converted1 = *v1;
4100
0
            if (converted1.convert(v2->d.type))
4101
0
                v1 = &converted1;
4102
0
        }
4103
0
        if (v1->d.type != v2->d.type) {
4104
            // if conversion fails, default to toString
4105
0
            int r = v1->toString().compare(v2->toString(), Qt::CaseInsensitive);
4106
0
            if (r == 0) {
4107
                // cmp(v) returned false, so we should try to agree with it.
4108
0
                return (v1->d.type < v2->d.type) ? -1 : 1;
4109
0
            }
4110
0
            return r;
4111
0
        }
4112
4113
        // did we end up with two numerics? If so, restart
4114
0
        if (qIsNumericType(v1->d.type) && qIsNumericType(v2->d.type))
4115
0
            return v1->compare(*v2);
4116
0
    }
4117
0
    if (v1->d.type >= QMetaType::User) {
4118
0
        int result;
4119
0
        if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(d)), QT_PREPEND_NAMESPACE(constData(v2->d)), d.type, &result))
4120
0
            return result;
4121
0
    }
4122
0
    switch (v1->d.type) {
4123
0
    case QVariant::Date:
4124
0
        return v1->toDate() < v2->toDate() ? -1 : 1;
4125
0
    case QVariant::Time:
4126
0
        return v1->toTime() < v2->toTime() ? -1 : 1;
4127
0
    case QVariant::DateTime:
4128
0
        return v1->toDateTime() < v2->toDateTime() ? -1 : 1;
4129
0
    case QVariant::StringList:
4130
0
        return v1->toStringList() < v2->toStringList() ? -1 : 1;
4131
0
    }
4132
0
    int r = v1->toString().compare(v2->toString(), Qt::CaseInsensitive);
4133
0
    if (r == 0) {
4134
        // cmp(v) returned false, so we should try to agree with it.
4135
0
        return (d.type < v.d.type) ? -1 : 1;
4136
0
    }
4137
0
    return r;
4138
0
}
4139
4140
/*!
4141
    \internal
4142
 */
4143
4144
const void *QVariant::constData() const
4145
0
{
4146
0
    return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr);
4147
0
}
4148
4149
/*!
4150
    \fn const void* QVariant::data() const
4151
4152
    \internal
4153
*/
4154
4155
/*!
4156
    \internal
4157
*/
4158
void* QVariant::data()
4159
0
{
4160
0
    detach();
4161
0
    return const_cast<void *>(constData());
4162
0
}
4163
4164
4165
/*!
4166
    Returns \c true if this is a null variant, false otherwise. A variant is
4167
    considered null if it contains no initialized value, or the contained value
4168
    is \nullptr or is an instance of a built-in type that has an isNull
4169
    method, in which case the result would be the same as calling isNull on the
4170
    wrapped object.
4171
4172
    \warning Null variants is not a single state and two null variants may easily
4173
    return \c false on the == operator if they do not contain similar null values.
4174
4175
    \sa convert(int)
4176
*/
4177
bool QVariant::isNull() const
4178
8
{
4179
8
    return handlerManager[d.type]->isNull(&d);
4180
8
}
4181
4182
#ifndef QT_NO_DEBUG_STREAM
4183
QDebug operator<<(QDebug dbg, const QVariant &v)
4184
0
{
4185
0
    QDebugStateSaver saver(dbg);
4186
0
    const uint typeId = v.d.type;
4187
0
    dbg.nospace() << "QVariant(";
4188
0
    if (typeId != QMetaType::UnknownType) {
4189
0
        dbg << QMetaType::typeName(typeId) << ", ";
4190
0
        bool userStream = false;
4191
0
        bool canConvertToString = false;
4192
0
        if (typeId >= QMetaType::User) {
4193
0
            userStream = QMetaType::debugStream(dbg, constData(v.d), typeId);
4194
0
            canConvertToString = v.canConvert<QString>();
4195
0
        }
4196
0
        if (!userStream && canConvertToString)
4197
0
            dbg << v.toString();
4198
0
        else if (!userStream)
4199
0
            handlerManager[typeId]->debugStream(dbg, v);
4200
0
    } else {
4201
0
        dbg << "Invalid";
4202
0
    }
4203
0
    dbg << ')';
4204
0
    return dbg;
4205
0
}
4206
4207
QDebug operator<<(QDebug dbg, const QVariant::Type p)
4208
0
{
4209
0
    QDebugStateSaver saver(dbg);
4210
0
    dbg.nospace() << "QVariant::"
4211
0
                  << (int(p) != int(QMetaType::UnknownType)
4212
0
                     ? QMetaType::typeName(p)
4213
0
                     : "Invalid");
4214
0
    return dbg;
4215
0
}
4216
#endif
4217
4218
4219
/*! \fn template<typename T> void QVariant::setValue(const T &value)
4220
4221
    Stores a copy of \a value. If \c{T} is a type that QVariant
4222
    doesn't support, QMetaType is used to store the value. A compile
4223
    error will occur if QMetaType doesn't handle the type.
4224
4225
    Example:
4226
4227
    \snippet code/src_corelib_kernel_qvariant.cpp 4
4228
4229
    \sa value(), fromValue(), canConvert()
4230
 */
4231
4232
/*! \fn template<typename T> T QVariant::value() const
4233
4234
    Returns the stored value converted to the template type \c{T}.
4235
    Call canConvert() to find out whether a type can be converted.
4236
    If the value cannot be converted, a \l{default-constructed value}
4237
    will be returned.
4238
4239
    If the type \c{T} is supported by QVariant, this function behaves
4240
    exactly as toString(), toInt() etc.
4241
4242
    Example:
4243
4244
    \snippet code/src_corelib_kernel_qvariant.cpp 5
4245
4246
    If the QVariant contains a pointer to a type derived from QObject then
4247
    \c{T} may be any QObject type. If the pointer stored in the QVariant can be
4248
    qobject_cast to T, then that result is returned. Otherwise \nullptr is
4249
    returned. Note that this only works for QObject subclasses which use the
4250
    Q_OBJECT macro.
4251
4252
    If the QVariant contains a sequential container and \c{T} is QVariantList, the
4253
    elements of the container will be converted into \l {QVariant}s and returned as a QVariantList.
4254
4255
    \snippet code/src_corelib_kernel_qvariant.cpp 9
4256
4257
    \sa setValue(), fromValue(), canConvert(), Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE()
4258
*/
4259
4260
/*! \fn bool QVariant::canConvert() const
4261
4262
    Returns \c true if the variant can be converted to the template type \c{T},
4263
    otherwise false.
4264
4265
    Example:
4266
4267
    \snippet code/src_corelib_kernel_qvariant.cpp 6
4268
4269
    A QVariant containing a pointer to a type derived from QObject will also return true for this
4270
    function if a qobject_cast to the template type \c{T} would succeed. Note that this only works
4271
    for QObject subclasses which use the Q_OBJECT macro.
4272
4273
    \sa convert()
4274
*/
4275
4276
/*! \fn template<typename T> static QVariant QVariant::fromValue(const T &value)
4277
4278
    Returns a QVariant containing a copy of \a value. Behaves
4279
    exactly like setValue() otherwise.
4280
4281
    Example:
4282
4283
    \snippet code/src_corelib_kernel_qvariant.cpp 7
4284
4285
    \note If you are working with custom types, you should use
4286
    the Q_DECLARE_METATYPE() macro to register your custom type.
4287
4288
    \sa setValue(), value()
4289
*/
4290
4291
/*! \fn template<typename... Types> QVariant QVariant::fromStdVariant(const std::variant<Types...> &value)
4292
    \since 5.11
4293
4294
    Returns a QVariant with the type and value of the active variant of \a value. If
4295
    the active type is std::monostate a default QVariant is returned.
4296
4297
    \note With this method you do not need to register the variant as a Qt metatype,
4298
    since the std::variant is resolved before being stored. The component types
4299
    should be registered however.
4300
4301
    \sa fromValue()
4302
*/
4303
4304
#if QT_DEPRECATED_SINCE(5, 14)
4305
/*!
4306
    \fn template<typename T> QVariant qVariantFromValue(const T &value)
4307
    \relates QVariant
4308
    \obsolete
4309
4310
    Returns a variant containing a copy of the given \a value
4311
    with template type \c{T}.
4312
4313
    This function is equivalent to QVariant::fromValue(\a value).
4314
4315
    \note This function was provided as a workaround for MSVC 6
4316
    which did not support member template functions. It is advised
4317
    to use the other form in new code.
4318
4319
    For example, a QObject pointer can be stored in a variant with the
4320
    following code:
4321
4322
    \snippet code/src_corelib_kernel_qvariant.cpp 8
4323
4324
    \sa QVariant::fromValue()
4325
*/
4326
4327
/*! \fn template<typename T> void qVariantSetValue(QVariant &variant, const T &value)
4328
    \relates QVariant
4329
    \obsolete
4330
4331
    Sets the contents of the given \a variant to a copy of the
4332
    \a value with the specified template type \c{T}.
4333
4334
    This function is equivalent to QVariant::setValue(\a value).
4335
4336
    \note This function was provided as a workaround for MSVC 6
4337
    which did not support member template functions. It is advised
4338
    to use the other form in new code.
4339
4340
    \sa QVariant::setValue()
4341
*/
4342
#endif
4343
4344
/*!
4345
    \fn template<typename T> T qvariant_cast(const QVariant &value)
4346
    \relates QVariant
4347
4348
    Returns the given \a value converted to the template type \c{T}.
4349
4350
    This function is equivalent to QVariant::value().
4351
4352
    \sa QVariant::value()
4353
*/
4354
4355
/*! \fn template<typename T> T qVariantValue(const QVariant &value)
4356
    \relates QVariant
4357
    \obsolete
4358
4359
    Returns the given \a value converted to the template type \c{T}.
4360
4361
    This function is equivalent to
4362
    \l{QVariant::value()}{QVariant::value}<T>(\a value).
4363
4364
    \note This function was provided as a workaround for MSVC 6
4365
    which did not support member template functions. It is advised
4366
    to use the other form in new code.
4367
4368
    \sa QVariant::value(), qvariant_cast()
4369
*/
4370
4371
/*! \fn bool qVariantCanConvert(const QVariant &value)
4372
    \relates QVariant
4373
    \obsolete
4374
4375
    Returns \c true if the given \a value can be converted to the
4376
    template type specified; otherwise returns \c false.
4377
4378
    This function is equivalent to QVariant::canConvert(\a value).
4379
4380
    \note This function was provided as a workaround for MSVC 6
4381
    which did not support member template functions. It is advised
4382
    to use the other form in new code.
4383
4384
    \sa QVariant::canConvert()
4385
*/
4386
4387
/*!
4388
    \typedef QVariantList
4389
    \relates QVariant
4390
4391
    Synonym for QList<QVariant>.
4392
*/
4393
4394
/*!
4395
    \typedef QVariantMap
4396
    \relates QVariant
4397
4398
    Synonym for QMap<QString, QVariant>.
4399
*/
4400
4401
/*!
4402
    \typedef QVariantHash
4403
    \relates QVariant
4404
    \since 4.5
4405
4406
    Synonym for QHash<QString, QVariant>.
4407
*/
4408
4409
/*!
4410
    \typedef QVariant::DataPtr
4411
    \internal
4412
*/
4413
/*! \typedef QVariant::f_construct
4414
  \internal
4415
*/
4416
4417
/*! \typedef QVariant::f_clear
4418
  \internal
4419
*/
4420
4421
/*! \typedef QVariant::f_null
4422
  \internal
4423
*/
4424
4425
/*! \typedef QVariant::f_load
4426
  \internal
4427
*/
4428
4429
/*! \typedef QVariant::f_save
4430
  \internal
4431
*/
4432
4433
/*! \typedef QVariant::f_compare
4434
  \internal
4435
*/
4436
4437
/*! \typedef QVariant::f_convert
4438
  \internal
4439
*/
4440
4441
/*! \typedef QVariant::f_canConvert
4442
  \internal
4443
*/
4444
4445
/*! \typedef QVariant::f_debugStream
4446
  \internal
4447
*/
4448
4449
/*!
4450
    \fn DataPtr &QVariant::data_ptr()
4451
    \internal
4452
*/
4453
4454
/*!
4455
    \fn const DataPtr &QVariant::data_ptr() const
4456
    \internal
4457
*/
4458
4459
/*!
4460
    \class QSequentialIterable
4461
    \since 5.2
4462
    \inmodule QtCore
4463
    \brief The QSequentialIterable class is an iterable interface for a container in a QVariant.
4464
4465
    This class allows several methods of accessing the elements of a container held within
4466
    a QVariant. An instance of QSequentialIterable can be extracted from a QVariant if it can
4467
    be converted to a QVariantList.
4468
4469
    \snippet code/src_corelib_kernel_qvariant.cpp 9
4470
4471
    The container itself is not copied before iterating over it.
4472
4473
    \sa QVariant
4474
*/
4475
4476
/*!
4477
    \internal
4478
*/
4479
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
4480
QSequentialIterable::QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl)
4481
#else
4482
QSequentialIterable::QSequentialIterable(const QtMetaTypePrivate::QSequentialIterableImpl &impl)
4483
#endif
4484
  : m_impl(impl)
4485
0
{
4486
0
}
4487
4488
QSequentialIterable::const_iterator::const_iterator(const QSequentialIterable &iter, QAtomicInt *ref_)
4489
  : m_impl(iter.m_impl), ref(ref_)
4490
0
{
4491
0
    ref->ref();
4492
0
}
4493
4494
QSequentialIterable::const_iterator::const_iterator(const QtMetaTypePrivate::QSequentialIterableImpl &impl, QAtomicInt *ref_)
4495
  : m_impl(impl), ref(ref_)
4496
0
{
4497
0
    ref->ref();
4498
0
}
4499
4500
void QSequentialIterable::const_iterator::begin()
4501
0
{
4502
0
    m_impl.moveToBegin();
4503
0
}
4504
4505
void QSequentialIterable::const_iterator::end()
4506
0
{
4507
0
    m_impl.moveToEnd();
4508
0
}
4509
4510
/*! \fn QSequentialIterable::const_iterator QSequentialIterable::begin() const
4511
4512
    Returns a QSequentialIterable::const_iterator for the beginning of the container. This
4513
    can be used in stl-style iteration.
4514
4515
    \sa end()
4516
*/
4517
QSequentialIterable::const_iterator QSequentialIterable::begin() const
4518
0
{
4519
0
    const_iterator it(*this, new QAtomicInt(0));
4520
0
    it.begin();
4521
0
    return it;
4522
0
}
4523
4524
/*!
4525
    Returns a QSequentialIterable::const_iterator for the end of the container. This
4526
    can be used in stl-style iteration.
4527
4528
    \sa begin()
4529
*/
4530
QSequentialIterable::const_iterator QSequentialIterable::end() const
4531
0
{
4532
0
    const_iterator it(*this, new QAtomicInt(0));
4533
0
    it.end();
4534
0
    return it;
4535
0
}
4536
4537
0
static const QVariant variantFromVariantDataHelper(const QtMetaTypePrivate::VariantData &d) {
4538
0
    QVariant v;
4539
0
    if (d.metaTypeId == qMetaTypeId<QVariant>())
4540
0
        v =  *reinterpret_cast<const QVariant*>(d.data);
4541
0
    else
4542
0
        v = QVariant(d.metaTypeId, d.data, d.flags & ~QVariantConstructionFlags::ShouldDeleteVariantData);
4543
0
    if (d.flags & QVariantConstructionFlags::ShouldDeleteVariantData)
4544
0
        QMetaType::destroy(d.metaTypeId, const_cast<void *>(d.data));
4545
0
    return v;
4546
0
}
4547
4548
/*!
4549
    Returns the element at position \a idx in the container.
4550
*/
4551
QVariant QSequentialIterable::at(int idx) const
4552
0
{
4553
0
    const QtMetaTypePrivate::VariantData d = m_impl.at(idx);
4554
0
    return variantFromVariantDataHelper(d);
4555
0
}
4556
4557
/*!
4558
    Returns the number of elements in the container.
4559
*/
4560
int QSequentialIterable::size() const
4561
0
{
4562
0
    return m_impl.size();
4563
0
}
4564
4565
/*!
4566
    Returns whether it is possible to iterate over the container in reverse. This
4567
    corresponds to the std::bidirectional_iterator_tag iterator trait of the
4568
    const_iterator of the container.
4569
*/
4570
bool QSequentialIterable::canReverseIterate() const
4571
0
{
4572
0
    return m_impl._iteratorCapabilities & QtMetaTypePrivate::BiDirectionalCapability;
4573
0
}
4574
4575
/*!
4576
    \class QSequentialIterable::const_iterator
4577
    \since 5.2
4578
    \inmodule QtCore
4579
    \brief The QSequentialIterable::const_iterator allows iteration over a container in a QVariant.
4580
4581
    A QSequentialIterable::const_iterator can only be created by a QSequentialIterable instance,
4582
    and can be used in a way similar to other stl-style iterators.
4583
4584
    \snippet code/src_corelib_kernel_qvariant.cpp 9
4585
4586
    \sa QSequentialIterable
4587
*/
4588
4589
4590
/*!
4591
    Destroys the QSequentialIterable::const_iterator.
4592
*/
4593
0
QSequentialIterable::const_iterator::~const_iterator() {
4594
0
    if (!ref->deref()) {
4595
0
        m_impl.destroyIter();
4596
0
        delete ref;
4597
0
    }
4598
0
}
4599
4600
/*!
4601
    Creates a copy of \a other.
4602
*/
4603
QSequentialIterable::const_iterator::const_iterator(const const_iterator &other)
4604
  : m_impl(other.m_impl), ref(other.ref)
4605
0
{
4606
0
    ref->ref();
4607
0
}
4608
4609
/*!
4610
    Assigns \a other to this.
4611
*/
4612
QSequentialIterable::const_iterator&
4613
QSequentialIterable::const_iterator::operator=(const const_iterator &other)
4614
0
{
4615
0
    other.ref->ref();
4616
0
    if (!ref->deref()) {
4617
0
        m_impl.destroyIter();
4618
0
        delete ref;
4619
0
    }
4620
0
    m_impl = other.m_impl;
4621
0
    ref = other.ref;
4622
0
    return *this;
4623
0
}
4624
4625
/*!
4626
    Returns the current item, converted to a QVariant.
4627
*/
4628
const QVariant QSequentialIterable::const_iterator::operator*() const
4629
0
{
4630
0
    const QtMetaTypePrivate::VariantData d = m_impl.getCurrent();
4631
0
    return variantFromVariantDataHelper(d);
4632
0
}
4633
4634
/*!
4635
    Returns \c true if \a other points to the same item as this
4636
    iterator; otherwise returns \c false.
4637
4638
    \sa operator!=()
4639
*/
4640
bool QSequentialIterable::const_iterator::operator==(const const_iterator &other) const
4641
0
{
4642
0
    return m_impl.equal(other.m_impl);
4643
0
}
4644
4645
/*!
4646
    Returns \c true if \a other points to a different item than this
4647
    iterator; otherwise returns \c false.
4648
4649
    \sa operator==()
4650
*/
4651
bool QSequentialIterable::const_iterator::operator!=(const const_iterator &other) const
4652
0
{
4653
0
    return !m_impl.equal(other.m_impl);
4654
0
}
4655
4656
/*!
4657
    The prefix ++ operator (\c{++it}) advances the iterator to the
4658
    next item in the container and returns an iterator to the new current
4659
    item.
4660
4661
    Calling this function on QSequentialIterable::end() leads to undefined results.
4662
4663
    \sa operator--()
4664
*/
4665
QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator++()
4666
0
{
4667
0
    m_impl.advance(1);
4668
0
    return *this;
4669
0
}
4670
4671
/*!
4672
    \overload
4673
4674
    The postfix ++ operator (\c{it++}) advances the iterator to the
4675
    next item in the container and returns an iterator to the previously
4676
    current item.
4677
*/
4678
QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator++(int)
4679
0
{
4680
0
    QtMetaTypePrivate::QSequentialIterableImpl impl;
4681
0
    impl.copy(m_impl);
4682
0
    m_impl.advance(1);
4683
0
    return const_iterator(impl, new QAtomicInt(0));
4684
0
}
4685
4686
/*!
4687
    The prefix -- operator (\c{--it}) makes the preceding item
4688
    current and returns an iterator to the new current item.
4689
4690
    Calling this function on QSequentialIterable::begin() leads to undefined results.
4691
4692
    If the container in the QVariant does not support bi-directional iteration, calling this function
4693
    leads to undefined results.
4694
4695
    \sa operator++(), canReverseIterate()
4696
*/
4697
QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator--()
4698
0
{
4699
0
    m_impl.advance(-1);
4700
0
    return *this;
4701
0
}
4702
4703
/*!
4704
    \overload
4705
4706
    The postfix -- operator (\c{it--}) makes the preceding item
4707
    current and returns an iterator to the previously current item.
4708
4709
    If the container in the QVariant does not support bi-directional iteration, calling this function
4710
    leads to undefined results.
4711
4712
    \sa canReverseIterate()
4713
*/
4714
QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator--(int)
4715
0
{
4716
0
    QtMetaTypePrivate::QSequentialIterableImpl impl;
4717
0
    impl.copy(m_impl);
4718
0
    m_impl.advance(-1);
4719
0
    return const_iterator(impl, new QAtomicInt(0));
4720
0
}
4721
4722
/*!
4723
    Advances the iterator by \a j items.
4724
4725
    \sa operator-=(), operator+()
4726
*/
4727
QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator+=(int j)
4728
0
{
4729
0
    m_impl.advance(j);
4730
0
    return *this;
4731
0
}
4732
4733
/*!
4734
    Makes the iterator go back by \a j items.
4735
4736
    If the container in the QVariant does not support bi-directional iteration, calling this function
4737
    leads to undefined results.
4738
4739
    \sa operator+=(), operator-(), canReverseIterate()
4740
*/
4741
QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator-=(int j)
4742
0
{
4743
0
    m_impl.advance(-j);
4744
0
    return *this;
4745
0
}
4746
4747
/*!
4748
    Returns an iterator to the item at \a j positions forward from
4749
    this iterator.
4750
4751
    \sa operator-(), operator+=()
4752
*/
4753
QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator+(int j) const
4754
0
{
4755
0
    QtMetaTypePrivate::QSequentialIterableImpl impl;
4756
0
    impl.copy(m_impl);
4757
0
    impl.advance(j);
4758
0
    return const_iterator(impl, new QAtomicInt(0));
4759
0
}
4760
4761
/*!
4762
    Returns an iterator to the item at \a j positions backward from
4763
    this iterator.
4764
4765
    If the container in the QVariant does not support bi-directional iteration, calling this function
4766
    leads to undefined results.
4767
4768
    \sa operator+(), operator-=(), canReverseIterate()
4769
*/
4770
QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator-(int j) const
4771
0
{
4772
0
    QtMetaTypePrivate::QSequentialIterableImpl impl;
4773
0
    impl.copy(m_impl);
4774
0
    impl.advance(-j);
4775
0
    return const_iterator(impl, new QAtomicInt(0));
4776
0
}
4777
4778
/*!
4779
    \class QAssociativeIterable
4780
    \since 5.2
4781
    \inmodule QtCore
4782
    \brief The QAssociativeIterable class is an iterable interface for an associative container in a QVariant.
4783
4784
    This class allows several methods of accessing the elements of an associative container held within
4785
    a QVariant. An instance of QAssociativeIterable can be extracted from a QVariant if it can
4786
    be converted to a QVariantHash or QVariantMap.
4787
4788
    \snippet code/src_corelib_kernel_qvariant.cpp 10
4789
4790
    The container itself is not copied before iterating over it.
4791
4792
    \sa QVariant
4793
*/
4794
4795
/*!
4796
    \internal
4797
*/
4798
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
4799
QAssociativeIterable::QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl)
4800
#else
4801
QAssociativeIterable::QAssociativeIterable(const QtMetaTypePrivate::QAssociativeIterableImpl &impl)
4802
#endif
4803
  : m_impl(impl)
4804
0
{
4805
0
}
4806
4807
QAssociativeIterable::const_iterator::const_iterator(const QAssociativeIterable &iter, QAtomicInt *ref_)
4808
  : m_impl(iter.m_impl), ref(ref_)
4809
0
{
4810
0
    ref->ref();
4811
0
}
4812
4813
QAssociativeIterable::const_iterator::const_iterator(const QtMetaTypePrivate::QAssociativeIterableImpl &impl, QAtomicInt *ref_)
4814
  : m_impl(impl), ref(ref_)
4815
0
{
4816
0
    ref->ref();
4817
0
}
4818
4819
void QAssociativeIterable::const_iterator::begin()
4820
0
{
4821
0
    m_impl.begin();
4822
0
}
4823
4824
void QAssociativeIterable::const_iterator::end()
4825
0
{
4826
0
    m_impl.end();
4827
0
}
4828
4829
void QAssociativeIterable::const_iterator::find(const QVariant &key)
4830
0
{
4831
0
    Q_ASSERT(key.userType() == m_impl._metaType_id_key);
4832
0
    const QtMetaTypePrivate::VariantData dkey(key.userType(), key.constData(), 0 /*key.flags()*/);
4833
0
    m_impl.find(dkey);
4834
0
}
4835
4836
/*!
4837
    Returns a QAssociativeIterable::const_iterator for the beginning of the container. This
4838
    can be used in stl-style iteration.
4839
4840
    \sa end()
4841
*/
4842
QAssociativeIterable::const_iterator QAssociativeIterable::begin() const
4843
0
{
4844
0
    const_iterator it(*this, new QAtomicInt(0));
4845
0
    it.begin();
4846
0
    return it;
4847
0
}
4848
4849
/*!
4850
    Returns a QAssociativeIterable::const_iterator for the end of the container. This
4851
    can be used in stl-style iteration.
4852
4853
    \sa begin()
4854
*/
4855
QAssociativeIterable::const_iterator QAssociativeIterable::end() const
4856
0
{
4857
0
    const_iterator it(*this, new QAtomicInt(0));
4858
0
    it.end();
4859
0
    return it;
4860
0
}
4861
4862
/*!
4863
    \since 5.5
4864
4865
    Returns a QAssociativeIterable::const_iterator for the given key \a key
4866
    in the container, if the types are convertible.
4867
4868
    If the key is not found, returns end().
4869
4870
    This can be used in stl-style iteration.
4871
4872
    \sa begin(), end(), value()
4873
*/
4874
QAssociativeIterable::const_iterator QAssociativeIterable::find(const QVariant &key) const
4875
0
{
4876
0