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:
operator [](const uint typeId) const98     const QVariant::Handler *operator[] (const uint typeId) const
99     {
100         return Handlers[QModulesPrivate::moduleForType(typeId)];
101     }
102 
registerHandler(const QModulesPrivate::Names name,const QVariant::Handler * handler)103     void registerHandler(const QModulesPrivate::Names name, const QVariant::Handler *handler)
104     {
105         Handlers[name] = handler;
106     }
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 
construct(QVariant::Private * x,const void * copy)121 static void construct(QVariant::Private *x, const void *copy)
122 {
123     QVariantConstructor<CoreTypesFilter> constructor(x, copy);
124     QMetaTypeSwitcher::switcher<void>(constructor, x->type);
125 }
126 
clear(QVariant::Private * d)127 static void clear(QVariant::Private *d)
128 {
129     QVariantDestructor<CoreTypesFilter> cleaner(d);
130     QMetaTypeSwitcher::switcher<void>(cleaner, d->type);
131 }
132 
isNull(const QVariant::Private * d)133 static bool isNull(const QVariant::Private *d)
134 {
135     QVariantIsNull<CoreTypesFilter> isNull(d);
136     return QMetaTypeSwitcher::switcher<bool>(isNull, d->type);
137 }
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  */
compare(const QVariant::Private * a,const QVariant::Private * b)145 static bool compare(const QVariant::Private *a, const QVariant::Private *b)
146 {
147     QVariantComparator<CoreTypesFilter> comparator(a, b);
148     return QMetaTypeSwitcher::switcher<bool>(comparator, a->type);
149 }
150 
151 /*!
152   \internal
153  */
qMetaTypeNumber(const QVariant::Private * d)154 static qlonglong qMetaTypeNumber(const QVariant::Private *d)
155 {
156     switch (d->type) {
157     case QMetaType::Int:
158         return d->data.i;
159     case QMetaType::LongLong:
160         return d->data.ll;
161     case QMetaType::Char:
162         return qlonglong(d->data.c);
163     case QMetaType::SChar:
164         return qlonglong(d->data.sc);
165     case QMetaType::Short:
166         return qlonglong(d->data.s);
167     case QMetaType::Long:
168         return qlonglong(d->data.l);
169     case QMetaType::Float:
170         return qRound64(d->data.f);
171     case QMetaType::Double:
172         return qRound64(d->data.d);
173 #ifndef QT_BOOTSTRAPPED
174     case QMetaType::QJsonValue:
175         return v_cast<QJsonValue>(d)->toDouble();
176     case QMetaType::QCborValue:
177         return v_cast<QCborValue>(d)->toInteger();
178 #endif
179     }
180     Q_ASSERT(false);
181     return 0;
182 }
183 
qMetaTypeUNumber(const QVariant::Private * d)184 static qulonglong qMetaTypeUNumber(const QVariant::Private *d)
185 {
186     switch (d->type) {
187     case QMetaType::UInt:
188         return d->data.u;
189     case QMetaType::ULongLong:
190         return d->data.ull;
191     case QMetaType::UChar:
192         return d->data.uc;
193     case QMetaType::UShort:
194         return d->data.us;
195     case QMetaType::ULong:
196         return d->data.ul;
197     }
198     Q_ASSERT(false);
199     return 0;
200 }
201 
qConvertToNumber(const QVariant::Private * d,bool * ok)202 static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
203 {
204     *ok = true;
205 
206     switch (uint(d->type)) {
207     case QMetaType::QString:
208         return v_cast<QString>(d)->toLongLong(ok);
209     case QMetaType::QChar:
210         return v_cast<QChar>(d)->unicode();
211     case QMetaType::QByteArray:
212         return v_cast<QByteArray>(d)->toLongLong(ok);
213     case QMetaType::Bool:
214         return qlonglong(d->data.b);
215 #ifndef QT_BOOTSTRAPPED
216     case QMetaType::QCborValue:
217         if (!v_cast<QCborValue>(d)->isInteger() && !v_cast<QCborValue>(d)->isDouble())
218             break;
219         return qMetaTypeNumber(d);
220     case QMetaType::QJsonValue:
221         if (!v_cast<QJsonValue>(d)->isDouble())
222             break;
223         Q_FALLTHROUGH();
224 #endif
225     case QMetaType::Double:
226     case QMetaType::Int:
227     case QMetaType::Char:
228     case QMetaType::SChar:
229     case QMetaType::Short:
230     case QMetaType::Long:
231     case QMetaType::Float:
232     case QMetaType::LongLong:
233         return qMetaTypeNumber(d);
234     case QMetaType::ULongLong:
235     case QMetaType::UInt:
236     case QMetaType::UChar:
237     case QMetaType::UShort:
238     case QMetaType::ULong:
239 
240         return qlonglong(qMetaTypeUNumber(d));
241     }
242 
243     QMetaType typeInfo(d->type);
244     if (typeInfo.flags() & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
245         switch (typeInfo.sizeOf()) {
246         case 1:
247             return d->is_shared ? *reinterpret_cast<signed char *>(d->data.shared->ptr) : d->data.sc;
248         case 2:
249             return d->is_shared ? *reinterpret_cast<qint16 *>(d->data.shared->ptr) : d->data.s;
250         case 4:
251             return d->is_shared ? *reinterpret_cast<qint32 *>(d->data.shared->ptr) : d->data.i;
252         case 8:
253             return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->ptr) : d->data.ll;
254         }
255     }
256 
257     *ok = false;
258     return Q_INT64_C(0);
259 }
260 
qConvertToRealNumber(const QVariant::Private * d,bool * ok)261 static qreal qConvertToRealNumber(const QVariant::Private *d, bool *ok)
262 {
263     *ok = true;
264     switch (uint(d->type)) {
265     case QMetaType::Double:
266         return qreal(d->data.d);
267     case QMetaType::Float:
268         return qreal(d->data.f);
269     case QMetaType::ULongLong:
270     case QMetaType::UInt:
271     case QMetaType::UChar:
272     case QMetaType::UShort:
273     case QMetaType::ULong:
274         return qreal(qMetaTypeUNumber(d));
275 #ifndef QT_BOOTSTRAPPED
276     case QMetaType::QCborValue:
277         return v_cast<QCborValue>(d)->toDouble();
278     case QMetaType::QJsonValue:
279         return v_cast<QJsonValue>(d)->toDouble();
280 #endif
281     default:
282         // includes enum conversion as well as invalid types
283         return qreal(qConvertToNumber(d, ok));
284     }
285 }
286 
qConvertToUnsignedNumber(const QVariant::Private * d,bool * ok)287 static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
288 {
289     *ok = true;
290 
291     switch (uint(d->type)) {
292     case QMetaType::QString:
293         return v_cast<QString>(d)->toULongLong(ok);
294     case QMetaType::QChar:
295         return v_cast<QChar>(d)->unicode();
296     case QMetaType::QByteArray:
297         return v_cast<QByteArray>(d)->toULongLong(ok);
298     case QMetaType::Bool:
299         return qulonglong(d->data.b);
300 #ifndef QT_BOOTSTRAPPED
301     case QMetaType::QCborValue:
302         if (v_cast<QCborValue>(d)->isDouble())
303             return qulonglong(qConvertToRealNumber(d, ok));
304         if (!v_cast<QCborValue>(d)->isInteger())
305             return false;
306         return qulonglong(qMetaTypeNumber(d));
307     case QMetaType::QJsonValue:
308         if (!v_cast<QJsonValue>(d)->isDouble())
309             break;
310         Q_FALLTHROUGH();
311 #endif
312     case QMetaType::Double:
313     case QMetaType::Int:
314     case QMetaType::Char:
315     case QMetaType::SChar:
316     case QMetaType::Short:
317     case QMetaType::Long:
318     case QMetaType::Float:
319     case QMetaType::LongLong:
320         return qulonglong(qMetaTypeNumber(d));
321     case QMetaType::ULongLong:
322     case QMetaType::UInt:
323     case QMetaType::UChar:
324     case QMetaType::UShort:
325     case QMetaType::ULong:
326         return qMetaTypeUNumber(d);
327     }
328 
329     QMetaType typeInfo(d->type);
330     if (typeInfo.flags() & QMetaType::IsEnumeration) {
331         switch (typeInfo.sizeOf()) {
332         case 1:
333             return d->is_shared ? *reinterpret_cast<uchar *>(d->data.shared->ptr) : d->data.uc;
334         case 2:
335             return d->is_shared ? *reinterpret_cast<quint16 *>(d->data.shared->ptr) : d->data.us;
336         case 4:
337             return d->is_shared ? *reinterpret_cast<quint32 *>(d->data.shared->ptr) : d->data.u;
338         case 8:
339             return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->ptr) : d->data.ull;
340         }
341     }
342 
343     *ok = false;
344     return Q_UINT64_C(0);
345 }
346 
347 template<typename TInput, typename LiteralWrapper>
qt_convertToBool(const QVariant::Private * const d)348 inline bool qt_convertToBool(const QVariant::Private *const d)
349 {
350     TInput str = v_cast<TInput>(d)->toLower();
351     return !(str.isEmpty() || str == LiteralWrapper("0") || str == LiteralWrapper("false"));
352 }
353 
354 /*!
355  \internal
356  Returns the internal data pointer from \a d.
357  */
358 
constData(const QVariant::Private & d)359 static const void *constData(const QVariant::Private &d)
360 {
361     return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.c);
362 }
363 
364 #ifndef QT_NO_QOBJECT
365 /*!
366   \internal
367   returns a QMetaEnum for a given meta tape type id if possible
368 */
metaEnumFromType(int type)369 static QMetaEnum metaEnumFromType(int type)
370 {
371     QMetaType t(type);
372     if (t.flags() & QMetaType::IsEnumeration) {
373         if (const QMetaObject *metaObject = t.metaObject()) {
374             const char *enumName = QMetaType::typeName(type);
375             const char *lastColon = std::strrchr(enumName, ':');
376             if (lastColon)
377                 enumName = lastColon + 1;
378             return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
379         }
380     }
381     return QMetaEnum();
382 }
383 #endif
384 
385 /*!
386  \internal
387 
388  Converts \a d to type \a t, which is placed in \a result.
389  */
convert(const QVariant::Private * d,int t,void * result,bool * ok)390 static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
391 {
392     Q_ASSERT(d->type != uint(t));
393     Q_ASSERT(result);
394 
395     if (d->type >= QMetaType::User || t >= QMetaType::User) {
396         const bool isOk = QMetaType::convert(constData(*d), d->type, result, t);
397         if (ok)
398             *ok = isOk;
399         if (isOk)
400             return true;
401     }
402 
403     bool dummy;
404     if (!ok)
405         ok = &dummy;
406 
407     switch (uint(t)) {
408 #ifndef QT_BOOTSTRAPPED
409     case QMetaType::QUrl:
410         switch (d->type) {
411         case QMetaType::QString:
412             *static_cast<QUrl *>(result) = QUrl(*v_cast<QString>(d));
413             break;
414         case QMetaType::QCborValue:
415             if (v_cast<QCborValue>(d)->isUrl()) {
416                 *static_cast<QUrl *>(result) = v_cast<QCborValue>(d)->toUrl();
417                 break;
418             }
419             return false;
420         default:
421             return false;
422         }
423         break;
424 #endif // QT_BOOTSTRAPPED
425 #if QT_CONFIG(itemmodel)
426     case QMetaType::QModelIndex:
427         switch (d->type) {
428         case QMetaType::QPersistentModelIndex:
429             *static_cast<QModelIndex *>(result) = QModelIndex(*v_cast<QPersistentModelIndex>(d));
430             break;
431         default:
432             return false;
433         }
434         break;
435     case QMetaType::QPersistentModelIndex:
436         switch (d->type) {
437         case QMetaType::QModelIndex:
438             *static_cast<QPersistentModelIndex *>(result) = QPersistentModelIndex(*v_cast<QModelIndex>(d));
439             break;
440         default:
441             return false;
442         }
443         break;
444 #endif // QT_CONFIG(itemmodel)
445     case QMetaType::QString: {
446         QString *str = static_cast<QString *>(result);
447         switch (d->type) {
448         case QMetaType::QChar:
449             *str = *v_cast<QChar>(d);
450             break;
451         case QMetaType::Char:
452         case QMetaType::SChar:
453         case QMetaType::UChar:
454             *str = QChar::fromLatin1(d->data.c);
455             break;
456         case QMetaType::Short:
457         case QMetaType::Long:
458         case QMetaType::Int:
459         case QMetaType::LongLong:
460             *str = QString::number(qMetaTypeNumber(d));
461             break;
462         case QMetaType::UInt:
463         case QMetaType::ULongLong:
464         case QMetaType::UShort:
465         case QMetaType::ULong:
466             *str = QString::number(qMetaTypeUNumber(d));
467             break;
468         case QMetaType::Float:
469             *str = QString::number(d->data.f, 'g', QLocale::FloatingPointShortest);
470             break;
471         case QMetaType::Double:
472             *str = QString::number(d->data.d, 'g', QLocale::FloatingPointShortest);
473             break;
474 #if QT_CONFIG(datestring)
475         case QMetaType::QDate:
476             *str = v_cast<QDate>(d)->toString(Qt::ISODate);
477             break;
478         case QMetaType::QTime:
479             *str = v_cast<QTime>(d)->toString(Qt::ISODateWithMs);
480             break;
481         case QMetaType::QDateTime:
482             *str = v_cast<QDateTime>(d)->toString(Qt::ISODateWithMs);
483             break;
484 #endif
485         case QMetaType::Bool:
486             *str = d->data.b ? QStringLiteral("true") : QStringLiteral("false");
487             break;
488         case QMetaType::QByteArray:
489             *str = QString::fromUtf8(v_cast<QByteArray>(d)->constData());
490             break;
491         case QMetaType::QStringList:
492             if (v_cast<QStringList>(d)->count() == 1)
493                 *str = v_cast<QStringList>(d)->at(0);
494             break;
495 #ifndef QT_BOOTSTRAPPED
496         case QMetaType::QUrl:
497             *str = v_cast<QUrl>(d)->toString();
498             break;
499         case QMetaType::QJsonValue:
500             if (v_cast<QJsonValue>(d)->isString())
501                 *str = v_cast<QJsonValue>(d)->toString();
502             else if (!v_cast<QJsonValue>(d)->isNull())
503                 return false;
504             break;
505         case QMetaType::QCborValue:
506             if (v_cast<QCborValue>(d)->isContainer() || v_cast<QCborValue>(d)->isTag())
507                 return false;
508             *str = v_cast<QCborValue>(d)->toVariant().toString();
509             break;
510 #endif
511         case QMetaType::QUuid:
512             *str = v_cast<QUuid>(d)->toString();
513             break;
514         case QMetaType::Nullptr:
515             *str = QString();
516             break;
517         default:
518 #ifndef QT_NO_QOBJECT
519             {
520                 QMetaEnum en = metaEnumFromType(d->type);
521                 if (en.isValid()) {
522                     *str = QString::fromUtf8(en.valueToKey(qConvertToNumber(d, ok)));
523                     return *ok;
524                 }
525             }
526 #endif
527             return false;
528         }
529         break;
530     }
531     case QMetaType::QChar: {
532         QChar *c = static_cast<QChar *>(result);
533         switch (d->type) {
534         case QMetaType::Int:
535         case QMetaType::LongLong:
536         case QMetaType::Char:
537         case QMetaType::SChar:
538         case QMetaType::Short:
539         case QMetaType::Long:
540         case QMetaType::Float:
541             *c = QChar(ushort(qMetaTypeNumber(d)));
542             break;
543         case QMetaType::UInt:
544         case QMetaType::ULongLong:
545         case QMetaType::UChar:
546         case QMetaType::UShort:
547         case QMetaType::ULong:
548             *c = QChar(ushort(qMetaTypeUNumber(d)));
549             break;
550         default:
551             return false;
552         }
553         break;
554     }
555 #ifndef QT_NO_GEOM_VARIANT
556     case QMetaType::QSize: {
557         QSize *s = static_cast<QSize *>(result);
558         switch (d->type) {
559         case QMetaType::QSizeF:
560             *s = v_cast<QSizeF>(d)->toSize();
561             break;
562         default:
563             return false;
564         }
565         break;
566     }
567 
568     case QMetaType::QSizeF: {
569         QSizeF *s = static_cast<QSizeF *>(result);
570         switch (d->type) {
571         case QMetaType::QSize:
572             *s = QSizeF(*(v_cast<QSize>(d)));
573             break;
574         default:
575             return false;
576         }
577         break;
578     }
579 
580     case QMetaType::QLine: {
581         QLine *s = static_cast<QLine *>(result);
582         switch (d->type) {
583         case QMetaType::QLineF:
584             *s = v_cast<QLineF>(d)->toLine();
585             break;
586         default:
587             return false;
588         }
589         break;
590     }
591 
592     case QMetaType::QLineF: {
593         QLineF *s = static_cast<QLineF *>(result);
594         switch (d->type) {
595         case QMetaType::QLine:
596             *s = QLineF(*(v_cast<QLine>(d)));
597             break;
598         default:
599             return false;
600         }
601         break;
602     }
603 #endif
604     case QMetaType::QStringList:
605         if (d->type == QMetaType::QVariantList) {
606             QStringList *slst = static_cast<QStringList *>(result);
607             const QVariantList *list = v_cast<QVariantList >(d);
608             const int size = list->size();
609             slst->reserve(size);
610             for (int i = 0; i < size; ++i)
611                 slst->append(list->at(i).toString());
612         } else if (d->type == QMetaType::QString) {
613             QStringList *slst = static_cast<QStringList *>(result);
614             *slst = QStringList(*v_cast<QString>(d));
615         } else {
616             return false;
617         }
618         break;
619     case QMetaType::QDate: {
620         QDate *dt = static_cast<QDate *>(result);
621         if (d->type == QMetaType::QDateTime)
622             *dt = v_cast<QDateTime>(d)->date();
623 #if QT_CONFIG(datestring)
624         else if (d->type == QMetaType::QString)
625             *dt = QDate::fromString(*v_cast<QString>(d), Qt::ISODate);
626 #endif
627         else
628             return false;
629 
630         return dt->isValid();
631     }
632     case QMetaType::QTime: {
633         QTime *t = static_cast<QTime *>(result);
634         switch (d->type) {
635         case QMetaType::QDateTime:
636             *t = v_cast<QDateTime>(d)->time();
637             break;
638 #if QT_CONFIG(datestring)
639         case QMetaType::QString:
640             *t = QTime::fromString(*v_cast<QString>(d), Qt::ISODate);
641             break;
642 #endif
643         default:
644             return false;
645         }
646         return t->isValid();
647     }
648     case QMetaType::QDateTime: {
649         QDateTime *dt = static_cast<QDateTime *>(result);
650         switch (d->type) {
651 #if QT_CONFIG(datestring)
652         case QMetaType::QString:
653             *dt = QDateTime::fromString(*v_cast<QString>(d), Qt::ISODate);
654             break;
655 #  ifndef QT_BOOTSTRAPPED
656         case QMetaType::QCborValue:
657             if (v_cast<QCborValue>(d)->isDateTime())
658                 *dt = v_cast<QCborValue>(d)->toDateTime();
659             else
660                 return false;
661             break;
662 #  endif
663 #endif
664         case QMetaType::QDate:
665             *dt = v_cast<QDate>(d)->startOfDay();
666             break;
667         default:
668             return false;
669         }
670         return dt->isValid();
671     }
672     case QMetaType::QByteArray: {
673         QByteArray *ba = static_cast<QByteArray *>(result);
674         switch (d->type) {
675         case QMetaType::QString:
676             *ba = v_cast<QString>(d)->toUtf8();
677             break;
678         case QMetaType::Double:
679             *ba = QByteArray::number(d->data.d, 'g', QLocale::FloatingPointShortest);
680             break;
681         case QMetaType::Float:
682             *ba = QByteArray::number(d->data.f, 'g', QLocale::FloatingPointShortest);
683             break;
684         case QMetaType::Char:
685         case QMetaType::SChar:
686         case QMetaType::UChar:
687             *ba = QByteArray(1, d->data.c);
688             break;
689         case QMetaType::Int:
690         case QMetaType::LongLong:
691         case QMetaType::Short:
692         case QMetaType::Long:
693             *ba = QByteArray::number(qMetaTypeNumber(d));
694             break;
695         case QMetaType::UInt:
696         case QMetaType::ULongLong:
697         case QMetaType::UShort:
698         case QMetaType::ULong:
699             *ba = QByteArray::number(qMetaTypeUNumber(d));
700             break;
701         case QMetaType::Bool:
702             *ba = QByteArray(d->data.b ? "true" : "false");
703             break;
704         case QMetaType::QUuid:
705             *ba = v_cast<QUuid>(d)->toByteArray();
706             break;
707         case QMetaType::Nullptr:
708             *ba = QByteArray();
709             break;
710 #ifndef QT_BOOTSTRAPPED
711         case QMetaType::QCborValue:
712             if (v_cast<QCborValue>(d)->isByteArray())
713                 *ba = v_cast<QCborValue>(d)->toByteArray();
714             else
715                 return false;
716             break;
717 #endif
718         default:
719 #ifndef QT_NO_QOBJECT
720             {
721                 QMetaEnum en = metaEnumFromType(d->type);
722                 if (en.isValid()) {
723                     *ba = en.valueToKey(qConvertToNumber(d, ok));
724                     return *ok;
725                 }
726             }
727 #endif
728             return false;
729         }
730     }
731     break;
732     case QMetaType::Short:
733         *static_cast<short *>(result) = short(qConvertToNumber(d, ok));
734         return *ok;
735     case QMetaType::Long:
736         *static_cast<long *>(result) = long(qConvertToNumber(d, ok));
737         return *ok;
738     case QMetaType::UShort:
739         *static_cast<ushort *>(result) = ushort(qConvertToUnsignedNumber(d, ok));
740         return *ok;
741     case QMetaType::ULong:
742         *static_cast<ulong *>(result) = ulong(qConvertToUnsignedNumber(d, ok));
743         return *ok;
744     case QMetaType::Int:
745         *static_cast<int *>(result) = int(qConvertToNumber(d, ok));
746         return *ok;
747     case QMetaType::UInt:
748         *static_cast<uint *>(result) = uint(qConvertToUnsignedNumber(d, ok));
749         return *ok;
750     case QMetaType::LongLong:
751         *static_cast<qlonglong *>(result) = qConvertToNumber(d, ok);
752         return *ok;
753     case QMetaType::ULongLong: {
754         *static_cast<qulonglong *>(result) = qConvertToUnsignedNumber(d, ok);
755         return *ok;
756     }
757     case QMetaType::SChar: {
758         signed char s = qConvertToNumber(d, ok);
759         *static_cast<signed char*>(result) = s;
760         return *ok;
761     }
762     case QMetaType::UChar: {
763         *static_cast<uchar *>(result) = qConvertToUnsignedNumber(d, ok);
764         return *ok;
765     }
766     case QMetaType::Bool: {
767         bool *b = static_cast<bool *>(result);
768         switch(d->type) {
769         case QMetaType::QByteArray:
770             *b = qt_convertToBool<QByteArray, const char*>(d);
771             break;
772         case QMetaType::QString:
773             *b = qt_convertToBool<QString, QLatin1String>(d);
774             break;
775         case QMetaType::QChar:
776             *b = !v_cast<QChar>(d)->isNull();
777             break;
778         case QMetaType::Double:
779         case QMetaType::Int:
780         case QMetaType::LongLong:
781         case QMetaType::Char:
782         case QMetaType::SChar:
783         case QMetaType::Short:
784         case QMetaType::Long:
785         case QMetaType::Float:
786             *b = qMetaTypeNumber(d) != Q_INT64_C(0);
787             break;
788         case QMetaType::UInt:
789         case QMetaType::ULongLong:
790         case QMetaType::UChar:
791         case QMetaType::UShort:
792         case QMetaType::ULong:
793             *b = qMetaTypeUNumber(d) != Q_UINT64_C(0);
794             break;
795 #ifndef QT_BOOTSTRAPPED
796         case QMetaType::QCborValue:
797             *b = v_cast<QCborValue>(d)->toBool();
798             if (!v_cast<QCborValue>(d)->isBool())
799                 return false;
800             break;
801         case QMetaType::QJsonValue:
802             *b = v_cast<QJsonValue>(d)->toBool(false);
803             if (!v_cast<QJsonValue>(d)->isBool())
804                 return false;
805             break;
806 #endif
807         default:
808             *b = false;
809             return false;
810         }
811         break;
812     }
813     case QMetaType::Double: {
814         double *f = static_cast<double *>(result);
815         switch (d->type) {
816         case QMetaType::QString:
817             *f = v_cast<QString>(d)->toDouble(ok);
818             break;
819         case QMetaType::QByteArray:
820             *f = v_cast<QByteArray>(d)->toDouble(ok);
821             break;
822         case QMetaType::Bool:
823             *f = double(d->data.b);
824             break;
825         case QMetaType::Float:
826             *f = double(d->data.f);
827             break;
828         case QMetaType::LongLong:
829         case QMetaType::Int:
830         case QMetaType::Char:
831         case QMetaType::SChar:
832         case QMetaType::Short:
833         case QMetaType::Long:
834             *f = double(qMetaTypeNumber(d));
835             break;
836         case QMetaType::UInt:
837         case QMetaType::ULongLong:
838         case QMetaType::UChar:
839         case QMetaType::UShort:
840         case QMetaType::ULong:
841             *f = double(qMetaTypeUNumber(d));
842             break;
843 #ifndef QT_BOOTSTRAPPED
844         case QMetaType::QCborValue:
845             *f = v_cast<QCborValue>(d)->toDouble();
846             if (!v_cast<QCborValue>(d)->isDouble())
847                 return false;
848             break;
849         case QMetaType::QJsonValue:
850             *f = v_cast<QJsonValue>(d)->toDouble(0.0);
851             if (!v_cast<QJsonValue>(d)->isDouble())
852                 return false;
853             break;
854 #endif
855         default:
856             *f = 0.0;
857             return false;
858         }
859         break;
860     }
861     case QMetaType::Float: {
862         float *f = static_cast<float *>(result);
863         switch (d->type) {
864         case QMetaType::QString:
865             *f = v_cast<QString>(d)->toFloat(ok);
866             break;
867         case QMetaType::QByteArray:
868             *f = v_cast<QByteArray>(d)->toFloat(ok);
869             break;
870         case QMetaType::Bool:
871             *f = float(d->data.b);
872             break;
873         case QMetaType::Double:
874             *f = float(d->data.d);
875             break;
876         case QMetaType::LongLong:
877         case QMetaType::Int:
878         case QMetaType::Char:
879         case QMetaType::SChar:
880         case QMetaType::Short:
881         case QMetaType::Long:
882             *f = float(qMetaTypeNumber(d));
883             break;
884         case QMetaType::UInt:
885         case QMetaType::ULongLong:
886         case QMetaType::UChar:
887         case QMetaType::UShort:
888         case QMetaType::ULong:
889             *f = float(qMetaTypeUNumber(d));
890             break;
891 #ifndef QT_BOOTSTRAPPED
892         case QMetaType::QCborValue:
893             *f = v_cast<QCborValue>(d)->toDouble();
894             if (!v_cast<QCborValue>(d)->isDouble())
895                 return false;
896             break;
897         case QMetaType::QJsonValue:
898             *f = v_cast<QJsonValue>(d)->toDouble(0.0);
899             if (!v_cast<QJsonValue>(d)->isDouble())
900                 return false;
901             break;
902 #endif
903         default:
904             *f = 0.0f;
905             return false;
906         }
907         break;
908     }
909     case QMetaType::QVariantList:
910         if (d->type == QMetaType::QStringList) {
911             QVariantList *lst = static_cast<QVariantList *>(result);
912             const QStringList *slist = v_cast<QStringList>(d);
913             const int size = slist->size();
914             lst->reserve(size);
915             for (int i = 0; i < size; ++i)
916                 lst->append(QVariant(slist->at(i)));
917         } else if (qstrcmp(QMetaType::typeName(d->type), "QList<QVariant>") == 0) {
918             *static_cast<QVariantList *>(result) =
919                 *static_cast<QList<QVariant> *>(d->data.shared->ptr);
920 #ifndef QT_BOOTSTRAPPED
921         } else if (d->type == QMetaType::QCborValue) {
922             if (!v_cast<QCborValue>(d)->isArray())
923                 return false;
924             *static_cast<QVariantList *>(result) = v_cast<QCborValue>(d)->toArray().toVariantList();
925         } else if (d->type == QMetaType::QCborArray) {
926             *static_cast<QVariantList *>(result) = v_cast<QCborArray>(d)->toVariantList();
927         } else if (d->type == QMetaType::QJsonValue) {
928             if (!v_cast<QJsonValue>(d)->isArray())
929                 return false;
930             *static_cast<QVariantList *>(result) = v_cast<QJsonValue>(d)->toArray().toVariantList();
931         } else if (d->type == QMetaType::QJsonArray) {
932             *static_cast<QVariantList *>(result) = v_cast<QJsonArray>(d)->toVariantList();
933 #endif
934         } else {
935             return false;
936         }
937         break;
938     case QMetaType::QVariantMap:
939         if (qstrcmp(QMetaType::typeName(d->type), "QMap<QString, QVariant>") == 0) {
940             *static_cast<QVariantMap *>(result) =
941                 *static_cast<QMap<QString, QVariant> *>(d->data.shared->ptr);
942         } else if (d->type == QMetaType::QVariantHash) {
943             QVariantMap *map = static_cast<QVariantMap *>(result);
944             const QVariantHash *hash = v_cast<QVariantHash>(d);
945             const auto end = hash->end();
946             for (auto it = hash->begin(); it != end; ++it)
947                 static_cast<QMultiMap<QString, QVariant> *>(map)->insert(it.key(), it.value());
948 #ifndef QT_BOOTSTRAPPED
949         } else if (d->type == QMetaType::QCborValue) {
950             if (!v_cast<QCborValue>(d)->isMap())
951                 return false;
952             *static_cast<QVariantMap *>(result) = v_cast<QCborValue>(d)->toMap().toVariantMap();
953         } else if (d->type == QMetaType::QCborMap) {
954             *static_cast<QVariantMap *>(result) = v_cast<QCborMap>(d)->toVariantMap();
955         } else if (d->type == QMetaType::QJsonValue) {
956             if (!v_cast<QJsonValue>(d)->isObject())
957                 return false;
958             *static_cast<QVariantMap *>(result) = v_cast<QJsonValue>(d)->toObject().toVariantMap();
959         } else if (d->type == QMetaType::QJsonObject) {
960             *static_cast<QVariantMap *>(result) = v_cast<QJsonObject>(d)->toVariantMap();
961 #endif
962         } else {
963             return false;
964         }
965         break;
966     case QMetaType::QVariantHash:
967         if (qstrcmp(QMetaType::typeName(d->type), "QHash<QString, QVariant>") == 0) {
968             *static_cast<QVariantHash *>(result) =
969                 *static_cast<QHash<QString, QVariant> *>(d->data.shared->ptr);
970         } else if (d->type == QMetaType::QVariantMap) {
971             QVariantHash *hash = static_cast<QVariantHash *>(result);
972             const QVariantMap *map = v_cast<QVariantMap>(d);
973             const auto end = map->end();
974             for (auto it = map->begin(); it != end; ++it)
975                 static_cast<QMultiHash<QString, QVariant> *>(hash)->insert(it.key(), it.value());
976 #ifndef QT_BOOTSTRAPPED
977         } else if (d->type == QMetaType::QCborValue) {
978             if (!v_cast<QCborValue>(d)->isMap())
979                 return false;
980             *static_cast<QVariantHash *>(result) = v_cast<QCborValue>(d)->toMap().toVariantHash();
981         } else if (d->type == QMetaType::QCborMap) {
982             *static_cast<QVariantHash *>(result) = v_cast<QCborMap>(d)->toVariantHash();
983         } else if (d->type == QMetaType::QJsonValue) {
984             if (!v_cast<QJsonValue>(d)->isObject())
985                 return false;
986             *static_cast<QVariantHash *>(result) = v_cast<QJsonValue>(d)->toObject().toVariantHash();
987         } else if (d->type == QMetaType::QJsonObject) {
988             *static_cast<QVariantHash *>(result) = v_cast<QJsonObject>(d)->toVariantHash();
989 #endif
990         } else {
991             return false;
992         }
993         break;
994 #ifndef QT_NO_GEOM_VARIANT
995     case QMetaType::QRect:
996         if (d->type == QMetaType::QRectF)
997             *static_cast<QRect *>(result) = (v_cast<QRectF>(d))->toRect();
998         else
999             return false;
1000         break;
1001     case QMetaType::QRectF:
1002         if (d->type == QMetaType::QRect)
1003             *static_cast<QRectF *>(result) = *v_cast<QRect>(d);
1004         else
1005             return false;
1006         break;
1007     case QMetaType::QPointF:
1008         if (d->type == QMetaType::QPoint)
1009             *static_cast<QPointF *>(result) = *v_cast<QPoint>(d);
1010         else
1011             return false;
1012         break;
1013     case QMetaType::QPoint:
1014         if (d->type == QMetaType::QPointF)
1015             *static_cast<QPoint *>(result) = (v_cast<QPointF>(d))->toPoint();
1016         else
1017             return false;
1018         break;
1019     case QMetaType::Char:
1020     {
1021         *static_cast<qint8 *>(result) = qint8(qConvertToNumber(d, ok));
1022         return *ok;
1023     }
1024 #endif
1025     case QMetaType::QUuid:
1026         switch (d->type) {
1027         case QMetaType::QString:
1028             *static_cast<QUuid *>(result) = QUuid(*v_cast<QString>(d));
1029             break;
1030         case QMetaType::QByteArray:
1031             *static_cast<QUuid *>(result) = QUuid(*v_cast<QByteArray>(d));
1032             break;
1033 #ifndef QT_BOOTSTRAPPED
1034         case QMetaType::QCborValue:
1035             if (!v_cast<QCborValue>(d)->isUuid())
1036                 return false;
1037             *static_cast<QUuid *>(result) = v_cast<QCborValue>(d)->toUuid();
1038             break;
1039 #endif
1040         default:
1041             return false;
1042         }
1043         break;
1044     case QMetaType::Nullptr:
1045         *static_cast<std::nullptr_t *>(result) = nullptr;
1046         if (QMetaType::typeFlags(t) & (QMetaType::PointerToGadget | QMetaType::PointerToQObject)
1047                 || d->type == QMetaType::VoidStar) {
1048             if (v_cast<const void *>(d) == nullptr)
1049                 break;
1050         }
1051 #ifndef QT_BOOTSTRAPPED
1052         if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isNull())
1053             break;
1054 #endif
1055         return false;
1056 
1057 #ifndef QT_BOOTSTRAPPED
1058 #if QT_CONFIG(regularexpression)
1059     case QMetaType::QRegularExpression:
1060         if (d->type != QMetaType::QCborValue || !v_cast<QCborValue>(d)->isRegularExpression())
1061             return false;
1062         *static_cast<QRegularExpression *>(result) = v_cast<QCborValue>(d)->toRegularExpression();
1063         break;
1064 #endif
1065     case QMetaType::QJsonValue:
1066         switch (d->type) {
1067         case QMetaType::Nullptr:
1068             *static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Null);
1069             break;
1070         case QMetaType::Bool:
1071             *static_cast<QJsonValue *>(result) = QJsonValue(d->data.b);
1072             break;
1073         case QMetaType::Int:
1074         case QMetaType::UInt:
1075         case QMetaType::Double:
1076         case QMetaType::Float:
1077         case QMetaType::ULong:
1078         case QMetaType::Long:
1079         case QMetaType::LongLong:
1080         case QMetaType::ULongLong:
1081         case QMetaType::UShort:
1082         case QMetaType::UChar:
1083         case QMetaType::Char:
1084         case QMetaType::SChar:
1085         case QMetaType::Short:
1086             *static_cast<QJsonValue *>(result) = QJsonValue(qConvertToRealNumber(d, ok));
1087             Q_ASSERT(ok);
1088             break;
1089         case QMetaType::QString:
1090             *static_cast<QJsonValue *>(result) = QJsonValue(*v_cast<QString>(d));
1091             break;
1092         case QMetaType::QStringList:
1093             *static_cast<QJsonValue *>(result) = QJsonValue(QJsonArray::fromStringList(*v_cast<QStringList>(d)));
1094             break;
1095         case QMetaType::QVariantList:
1096             *static_cast<QJsonValue *>(result) = QJsonValue(QJsonArray::fromVariantList(*v_cast<QVariantList>(d)));
1097             break;
1098         case QMetaType::QVariantMap:
1099             *static_cast<QJsonValue *>(result) = QJsonValue(QJsonObject::fromVariantMap(*v_cast<QVariantMap>(d)));
1100             break;
1101         case QMetaType::QVariantHash:
1102             *static_cast<QJsonValue *>(result) = QJsonValue(QJsonObject::fromVariantHash(*v_cast<QVariantHash>(d)));
1103             break;
1104         case QMetaType::QJsonObject:
1105             *static_cast<QJsonValue *>(result) = *v_cast<QJsonObject>(d);
1106             break;
1107         case QMetaType::QJsonArray:
1108             *static_cast<QJsonValue *>(result) = *v_cast<QJsonArray>(d);
1109             break;
1110         case QMetaType::QJsonDocument: {
1111             QJsonDocument doc = *v_cast<QJsonDocument>(d);
1112             *static_cast<QJsonValue *>(result) = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1113             break;
1114         }
1115         case QMetaType::QCborValue:
1116             *static_cast<QJsonValue *>(result) = v_cast<QCborValue>(d)->toJsonValue();
1117             break;
1118         case QMetaType::QCborMap:
1119             *static_cast<QJsonValue *>(result) = v_cast<QCborMap>(d)->toJsonObject();
1120             break;
1121         case QMetaType::QCborArray:
1122             *static_cast<QJsonValue *>(result) = v_cast<QCborArray>(d)->toJsonArray();
1123             break;
1124         default:
1125             *static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Undefined);
1126             return false;
1127         }
1128         break;
1129     case QMetaType::QJsonArray:
1130         switch (d->type) {
1131         case QMetaType::QStringList:
1132             *static_cast<QJsonArray *>(result) = QJsonArray::fromStringList(*v_cast<QStringList>(d));
1133             break;
1134         case QMetaType::QVariantList:
1135             *static_cast<QJsonArray *>(result) = QJsonArray::fromVariantList(*v_cast<QVariantList>(d));
1136             break;
1137         case QMetaType::QJsonValue:
1138             if (!v_cast<QJsonValue>(d)->isArray())
1139                 return false;
1140             *static_cast<QJsonArray *>(result) = v_cast<QJsonValue>(d)->toArray();
1141             break;
1142         case QMetaType::QJsonDocument:
1143             if (!v_cast<QJsonDocument>(d)->isArray())
1144                 return false;
1145             *static_cast<QJsonArray *>(result) = v_cast<QJsonDocument>(d)->array();
1146             break;
1147         case QMetaType::QCborValue:
1148             if (!v_cast<QCborValue>(d)->isArray())
1149                 return false;
1150             *static_cast<QJsonArray *>(result) = v_cast<QCborValue>(d)->toArray().toJsonArray();
1151             break;
1152         case QMetaType::QCborArray:
1153             *static_cast<QJsonArray *>(result) = v_cast<QCborArray>(d)->toJsonArray();
1154             break;
1155         default:
1156             return false;
1157         }
1158         break;
1159     case QMetaType::QJsonObject:
1160         switch (d->type) {
1161         case QMetaType::QVariantMap:
1162             *static_cast<QJsonObject *>(result) = QJsonObject::fromVariantMap(*v_cast<QVariantMap>(d));
1163             break;
1164         case QMetaType::QVariantHash:
1165             *static_cast<QJsonObject *>(result) = QJsonObject::fromVariantHash(*v_cast<QVariantHash>(d));
1166             break;
1167         case QMetaType::QJsonValue:
1168             if (!v_cast<QJsonValue>(d)->isObject())
1169                 return false;
1170             *static_cast<QJsonObject *>(result) = v_cast<QJsonValue>(d)->toObject();
1171             break;
1172         case QMetaType::QJsonDocument:
1173             if (v_cast<QJsonDocument>(d)->isArray())
1174                 return false;
1175             *static_cast<QJsonObject *>(result) = v_cast<QJsonDocument>(d)->object();
1176             break;
1177         case QMetaType::QCborValue:
1178             if (!v_cast<QCborValue>(d)->isMap())
1179                 return false;
1180             *static_cast<QJsonObject *>(result) = v_cast<QCborValue>(d)->toMap().toJsonObject();
1181             break;
1182         case QMetaType::QCborMap:
1183             *static_cast<QJsonObject *>(result) = v_cast<QCborMap>(d)->toJsonObject();
1184             break;
1185         default:
1186             return false;
1187         }
1188         break;
1189     case QMetaType::QCborSimpleType:
1190         if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isSimpleType()) {
1191             *static_cast<QCborSimpleType *>(result) = v_cast<QCborValue>(d)->toSimpleType();
1192             break;
1193         }
1194         return false;
1195     case QMetaType::QCborValue:
1196         switch (d->type) {
1197         case QMetaType::Nullptr:
1198             *static_cast<QCborValue *>(result) = QCborValue(QCborValue::Null);
1199             break;
1200         case QMetaType::Bool:
1201             *static_cast<QCborValue *>(result) = QCborValue(d->data.b);
1202             break;
1203         case QMetaType::Int:
1204         case QMetaType::UInt:
1205         case QMetaType::ULong:
1206         case QMetaType::Long:
1207         case QMetaType::LongLong:
1208         case QMetaType::ULongLong:
1209         case QMetaType::UShort:
1210         case QMetaType::UChar:
1211         case QMetaType::Char:
1212         case QMetaType::SChar:
1213         case QMetaType::Short:
1214             *static_cast<QCborValue *>(result) = QCborValue(qConvertToNumber(d, ok));
1215             Q_ASSERT(ok);
1216             break;
1217         case QMetaType::Double:
1218         case QMetaType::Float:
1219             *static_cast<QCborValue *>(result) = QCborValue(qConvertToRealNumber(d, ok));
1220             Q_ASSERT(ok);
1221             break;
1222         case QMetaType::QString:
1223             *static_cast<QCborValue *>(result) = *v_cast<QString>(d);
1224             break;
1225         case QMetaType::QStringList:
1226             *static_cast<QCborValue *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
1227             break;
1228         case QMetaType::QByteArray:
1229             *static_cast<QCborValue *>(result) = *v_cast<QByteArray>(d);
1230             break;
1231         case QMetaType::QDate:
1232             *static_cast<QCborValue *>(result) = QCborValue(v_cast<QDate>(d)->startOfDay());
1233             break;
1234         case QMetaType::QDateTime:
1235             *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QDateTime>(d));
1236             break;
1237         case QMetaType::QUrl:
1238             *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUrl>(d));
1239             break;
1240 #if QT_CONFIG(regularexpression)
1241         case QMetaType::QRegularExpression:
1242             *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QRegularExpression>(d));
1243             break;
1244 #endif
1245         case QMetaType::QUuid:
1246             *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUuid>(d));
1247             break;
1248         case QMetaType::QVariantList:
1249             *static_cast<QCborValue *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
1250             break;
1251         case QMetaType::QVariantMap:
1252             *static_cast<QCborValue *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
1253             break;
1254         case QMetaType::QVariantHash:
1255             *static_cast<QCborValue *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
1256             break;
1257         case QMetaType::QJsonValue:
1258             *static_cast<QCborValue *>(result) = QCborValue::fromJsonValue(*v_cast<QJsonValue>(d));
1259             break;
1260         case QMetaType::QJsonObject:
1261             *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
1262             break;
1263         case QMetaType::QJsonArray:
1264             *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
1265             break;
1266         case QMetaType::QJsonDocument: {
1267             QJsonDocument doc = *v_cast<QJsonDocument>(d);
1268             if (doc.isArray())
1269                 *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(doc.array());
1270             else
1271                 *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(doc.object());
1272             break;
1273         }
1274         case QMetaType::QCborSimpleType:
1275             *static_cast<QCborValue *>(result) = *v_cast<QCborSimpleType>(d);
1276             break;
1277         case QMetaType::QCborMap:
1278             *static_cast<QCborValue *>(result) = *v_cast<QCborMap>(d);
1279             break;
1280         case QMetaType::QCborArray:
1281             *static_cast<QCborValue *>(result) = *v_cast<QCborArray>(d);
1282             break;
1283         default:
1284             *static_cast<QCborValue *>(result) = {};
1285             return false;
1286         }
1287         break;
1288     case QMetaType::QCborArray:
1289         switch (d->type) {
1290         case QMetaType::QStringList:
1291             *static_cast<QCborArray *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
1292             break;
1293         case QMetaType::QVariantList:
1294             *static_cast<QCborArray *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
1295             break;
1296         case QMetaType::QCborValue:
1297             if (!v_cast<QCborValue>(d)->isArray())
1298                 return false;
1299             *static_cast<QCborArray *>(result) = v_cast<QCborValue>(d)->toArray();
1300             break;
1301         case QMetaType::QJsonDocument:
1302             if (!v_cast<QJsonDocument>(d)->isArray())
1303                 return false;
1304             *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonDocument>(d)->array());
1305             break;
1306         case QMetaType::QJsonValue:
1307             if (!v_cast<QJsonValue>(d)->isArray())
1308                 return false;
1309             *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonValue>(d)->toArray());
1310             break;
1311         case QMetaType::QJsonArray:
1312             *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
1313             break;
1314         default:
1315             return false;
1316         }
1317         break;
1318     case QMetaType::QCborMap:
1319         switch (d->type) {
1320         case QMetaType::QVariantMap:
1321             *static_cast<QCborMap *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
1322             break;
1323         case QMetaType::QVariantHash:
1324             *static_cast<QCborMap *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
1325             break;
1326         case QMetaType::QCborValue:
1327             if (!v_cast<QCborValue>(d)->isMap())
1328                 return false;
1329             *static_cast<QCborMap *>(result) = v_cast<QCborValue>(d)->toMap();
1330             break;
1331         case QMetaType::QJsonDocument:
1332             if (v_cast<QJsonDocument>(d)->isArray())
1333                 return false;
1334             *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonDocument>(d)->object());
1335             break;
1336         case QMetaType::QJsonValue:
1337             if (!v_cast<QJsonValue>(d)->isObject())
1338                 return false;
1339             *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonValue>(d)->toObject());
1340             break;
1341         case QMetaType::QJsonObject:
1342             *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
1343             break;
1344         default:
1345             return false;
1346         }
1347         break;
1348 #endif
1349 
1350     default:
1351 #ifndef QT_NO_QOBJECT
1352         if (d->type == QMetaType::QString || d->type == QMetaType::QByteArray) {
1353             QMetaEnum en = metaEnumFromType(t);
1354             if (en.isValid()) {
1355                 QByteArray keys = (d->type == QMetaType::QString) ? v_cast<QString>(d)->toUtf8() : *v_cast<QByteArray>(d);
1356                 int value = en.keysToValue(keys.constData(), ok);
1357                 if (*ok) {
1358                     switch (QMetaType::sizeOf(t)) {
1359                     case 1:
1360                         *static_cast<signed char *>(result) = value;
1361                         return true;
1362                     case 2:
1363                         *static_cast<qint16 *>(result) = value;
1364                         return true;
1365                     case 4:
1366                         *static_cast<qint32 *>(result) = value;
1367                         return true;
1368                     case 8:
1369                         *static_cast<qint64 *>(result) = value;
1370                         return true;
1371                     }
1372                 }
1373             }
1374         }
1375 #endif
1376         if (QMetaType::typeFlags(t) & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
1377             qlonglong value = qConvertToNumber(d, ok);
1378             if (*ok) {
1379                 switch (QMetaType::sizeOf(t)) {
1380                 case 1:
1381                     *static_cast<signed char *>(result) = value;
1382                     return true;
1383                 case 2:
1384                     *static_cast<qint16 *>(result) = value;
1385                     return true;
1386                 case 4:
1387                     *static_cast<qint32 *>(result) = value;
1388                     return true;
1389                 case 8:
1390                     *static_cast<qint64 *>(result) = value;
1391                     return true;
1392                 }
1393             }
1394             return *ok;
1395         }
1396         return false;
1397     }
1398     return true;
1399 }
1400 
1401 #if !defined(QT_NO_DEBUG_STREAM)
streamDebug(QDebug dbg,const QVariant & v)1402 static void streamDebug(QDebug dbg, const QVariant &v)
1403 {
1404     QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
1405     QVariantDebugStream<CoreTypesFilter> stream(dbg, d);
1406     QMetaTypeSwitcher::switcher<void>(stream, d->type);
1407 }
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 
dummyConstruct(QVariant::Private *,const void *)1428 static void dummyConstruct(QVariant::Private *, const void *) { Q_ASSERT_X(false, "QVariant", "Trying to construct an unknown type"); }
dummyClear(QVariant::Private *)1429 static void dummyClear(QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to clear an unknown type"); }
dummyIsNull(const QVariant::Private * d)1430 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; }
dummyCompare(const QVariant::Private *,const QVariant::Private *)1431 static bool dummyCompare(const QVariant::Private *, const QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to compare an unknown types"); return false; }
dummyConvert(const QVariant::Private *,int,void *,bool *)1432 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)
dummyStreamDebug(QDebug,const QVariant &)1434 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 
customConstruct(QVariant::Private * d,const void * copy)1454 static void customConstruct(QVariant::Private *d, const void *copy)
1455 {
1456     const QMetaType type(d->type);
1457     const uint size = type.sizeOf();
1458     if (!size) {
1459         qWarning("Trying to construct an instance of an invalid type, type id: %i", d->type);
1460         d->type = QMetaType::UnknownType;
1461         return;
1462     }
1463 
1464     // this logic should match with QVariantIntegrator::CanUseInternalSpace
1465     if (size <= sizeof(QVariant::Private::Data)
1466             && (type.flags() & (QMetaType::MovableType | QMetaType::IsEnumeration))) {
1467         type.construct(&d->data.ptr, copy);
1468         d->is_null = d->data.ptr == nullptr;
1469         d->is_shared = false;
1470     } else {
1471         // Private::Data contains long long, and long double is the biggest standard type.
1472         const size_t maxAlignment =
1473             qMax(Q_ALIGNOF(QVariant::Private::Data), Q_ALIGNOF(long double));
1474         const size_t s = sizeof(QVariant::PrivateShared);
1475         const size_t offset = s + ((s * maxAlignment - s) % maxAlignment);
1476         void *data = operator new(offset + size);
1477         void *ptr = static_cast<char *>(data) + offset;
1478         type.construct(ptr, copy);
1479         d->is_null = ptr == nullptr;
1480         d->is_shared = true;
1481         d->data.shared = new (data) QVariant::PrivateShared(ptr);
1482     }
1483 }
1484 
customClear(QVariant::Private * d)1485 static void customClear(QVariant::Private *d)
1486 {
1487     if (!d->is_shared) {
1488         QMetaType::destruct(d->type, &d->data.ptr);
1489     } else {
1490         QMetaType::destruct(d->type, d->data.shared->ptr);
1491         d->data.shared->~PrivateShared();
1492         operator delete(d->data.shared);
1493     }
1494 }
1495 
customIsNull(const QVariant::Private * d)1496 static bool customIsNull(const QVariant::Private *d)
1497 {
1498     if (d->is_null)
1499         return true;
1500     const char *const typeName = QMetaType::typeName(d->type);
1501     if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(d->type)))
1502         qFatal("QVariant::isNull: type %d unknown to QVariant.", d->type);
1503     uint typeNameLen = qstrlen(typeName);
1504     if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*') {
1505         const void *d_ptr = d->is_shared ? d->data.shared->ptr : &(d->data.ptr);
1506         return *static_cast<void *const *>(d_ptr) == nullptr;
1507     }
1508     return false;
1509 }
1510 
customCompare(const QVariant::Private * a,const QVariant::Private * b)1511 static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
1512 {
1513     const char *const typeName = QMetaType::typeName(a->type);
1514     if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(a->type)))
1515         qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
1516 
1517     const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data.ptr);
1518     const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data.ptr);
1519 
1520     uint typeNameLen = qstrlen(typeName);
1521     if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*')
1522         return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
1523 
1524     if (a->is_null && b->is_null)
1525         return true;
1526 
1527     return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
1528 }
1529 
customConvert(const QVariant::Private * d,int t,void * result,bool * ok)1530 static bool customConvert(const QVariant::Private *d, int t, void *result, bool *ok)
1531 {
1532     if (d->type >= QMetaType::User || t >= QMetaType::User) {
1533         if (QMetaType::convert(constData(*d), d->type, result, t)) {
1534             if (ok)
1535                 *ok = true;
1536             return true;
1537         }
1538     }
1539     return convert(d, t, result, ok);
1540 }
1541 
1542 #if !defined(QT_NO_DEBUG_STREAM)
customStreamDebug(QDebug dbg,const QVariant & variant)1543 static void customStreamDebug(QDebug dbg, const QVariant &variant) {
1544 #ifndef QT_BOOTSTRAPPED
1545     QMetaType::TypeFlags flags = QMetaType::typeFlags(variant.userType());
1546     if (flags & QMetaType::PointerToQObject)
1547         dbg.nospace() << qvariant_cast<QObject*>(variant);
1548 #else
1549     Q_UNUSED(dbg);
1550     Q_UNUSED(variant);
1551 #endif
1552 }
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 
qcoreVariantHandler()1581 Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler()
1582 {
1583     return &qt_kernel_variant_handler;
1584 }
1585 
registerHandler(const int name,const QVariant::Handler * handler)1586 Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names */name, const QVariant::Handler *handler)
1587 {
1588     handlerManager.registerHandler(static_cast<QModulesPrivate::Names>(name), handler);
1589 }
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 
create(int type,const void * copy)1808 void QVariant::create(int type, const void *copy)
1809 {
1810     d.type = type;
1811     handlerManager[type]->construct(&d, copy);
1812 }
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 
~QVariant()1825 QVariant::~QVariant()
1826 {
1827     if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
1828         handlerManager[d.type]->clear(&d);
1829 }
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 
QVariant(const QVariant & p)1838 QVariant::QVariant(const QVariant &p)
1839     : d(p.d)
1840 {
1841     if (d.is_shared) {
1842         d.data.shared->ref.ref();
1843     } else if (p.d.type > Char) {
1844         handlerManager[d.type]->construct(&d, p.constData());
1845         d.is_null = p.d.is_null;
1846     }
1847 }
1848 
1849 #ifndef QT_NO_DATASTREAM
1850 /*!
1851     Reads the variant from the data stream, \a s.
1852 */
QVariant(QDataStream & s)1853 QVariant::QVariant(QDataStream &s)
1854 {
1855     d.is_null = true;
1856     s >> *this;
1857 }
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
QVariant(const char * val)1888 QVariant::QVariant(const char *val)
1889 {
1890     QString s = QString::fromUtf8(val);
1891     create(String, &s);
1892 }
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 
QVariant(Type type)2129 QVariant::QVariant(Type type)
2130 { create(type, nullptr); }
QVariant(int typeId,const void * copy)2131 QVariant::QVariant(int typeId, const void *copy)
2132 { create(typeId, copy); d.is_null = false; }
2133 
2134 /*!
2135     \internal
2136     flags is true if it is a pointer type
2137  */
QVariant(int typeId,const void * copy,uint flags)2138 QVariant::QVariant(int typeId, const void *copy, uint flags)
2139 {
2140     if (flags) { //type is a pointer type
2141         d.type = typeId;
2142         d.data.ptr = *reinterpret_cast<void *const*>(copy);
2143     } else {
2144         create(typeId, copy);
2145     }
2146     d.is_null = false;
2147 }
2148 
QVariant(int val)2149 QVariant::QVariant(int val)
2150     : d(Int)
2151 { d.data.i = val; }
QVariant(uint val)2152 QVariant::QVariant(uint val)
2153     : d(UInt)
2154 { d.data.u = val; }
QVariant(qlonglong val)2155 QVariant::QVariant(qlonglong val)
2156     : d(LongLong)
2157 { d.data.ll = val; }
QVariant(qulonglong val)2158 QVariant::QVariant(qulonglong val)
2159     : d(ULongLong)
2160 { d.data.ull = val; }
QVariant(bool val)2161 QVariant::QVariant(bool val)
2162     : d(Bool)
2163 { d.data.b = val; }
QVariant(double val)2164 QVariant::QVariant(double val)
2165     : d(Double)
2166 { d.data.d = val; }
QVariant(float val)2167 QVariant::QVariant(float val)
2168     : d(QMetaType::Float)
2169 { d.data.f = val; }
2170 
QVariant(const QByteArray & val)2171 QVariant::QVariant(const QByteArray &val)
2172     : d(ByteArray)
2173 { v_construct<QByteArray>(&d, val); }
QVariant(const QBitArray & val)2174 QVariant::QVariant(const QBitArray &val)
2175     : d(BitArray)
2176 { v_construct<QBitArray>(&d, val);  }
QVariant(const QString & val)2177 QVariant::QVariant(const QString &val)
2178     : d(String)
2179 { v_construct<QString>(&d, val);  }
QVariant(QChar val)2180 QVariant::QVariant(QChar val)
2181     : d(Char)
2182 { v_construct<QChar>(&d, val);  }
QVariant(QLatin1String val)2183 QVariant::QVariant(QLatin1String val)
2184     : d(String)
2185 { v_construct<QString>(&d, val); }
QVariant(const QStringList & val)2186 QVariant::QVariant(const QStringList &val)
2187     : d(StringList)
2188 { v_construct<QStringList>(&d, val); }
2189 
QVariant(const QDate & val)2190 QVariant::QVariant(const QDate &val)
2191     : d(Date)
2192 { v_construct<QDate>(&d, val); }
QVariant(const QTime & val)2193 QVariant::QVariant(const QTime &val)
2194     : d(Time)
2195 { v_construct<QTime>(&d, val); }
QVariant(const QDateTime & val)2196 QVariant::QVariant(const QDateTime &val)
2197     : d(DateTime)
2198 { v_construct<QDateTime>(&d, val); }
2199 #if QT_CONFIG(easingcurve)
QVariant(const QEasingCurve & val)2200 QVariant::QVariant(const QEasingCurve &val)
2201     : d(EasingCurve)
2202 { v_construct<QEasingCurve>(&d, val); }
2203 #endif
QVariant(const QList<QVariant> & list)2204 QVariant::QVariant(const QList<QVariant> &list)
2205     : d(List)
2206 { v_construct<QVariantList>(&d, list); }
QVariant(const QMap<QString,QVariant> & map)2207 QVariant::QVariant(const QMap<QString, QVariant> &map)
2208     : d(Map)
2209 { v_construct<QVariantMap>(&d, map); }
QVariant(const QHash<QString,QVariant> & hash)2210 QVariant::QVariant(const QHash<QString, QVariant> &hash)
2211     : d(Hash)
2212 { v_construct<QVariantHash>(&d, hash); }
2213 #ifndef QT_NO_GEOM_VARIANT
QVariant(const QPoint & pt)2214 QVariant::QVariant(const QPoint &pt)
2215     : d(Point)
2216 { v_construct<QPoint>(&d, pt); }
QVariant(const QPointF & pt)2217 QVariant::QVariant(const QPointF &pt)
2218     : d(PointF)
2219 { v_construct<QPointF>(&d, pt); }
QVariant(const QRectF & r)2220 QVariant::QVariant(const QRectF &r)
2221     : d(RectF)
2222 { v_construct<QRectF>(&d, r); }
QVariant(const QLineF & l)2223 QVariant::QVariant(const QLineF &l)
2224     : d(LineF)
2225 { v_construct<QLineF>(&d, l); }
QVariant(const QLine & l)2226 QVariant::QVariant(const QLine &l)
2227     : d(Line)
2228 { v_construct<QLine>(&d, l); }
QVariant(const QRect & r)2229 QVariant::QVariant(const QRect &r)
2230     : d(Rect)
2231 { v_construct<QRect>(&d, r); }
QVariant(const QSize & s)2232 QVariant::QVariant(const QSize &s)
2233     : d(Size)
2234 { v_construct<QSize>(&d, s); }
QVariant(const QSizeF & s)2235 QVariant::QVariant(const QSizeF &s)
2236     : d(SizeF)
2237 { v_construct<QSizeF>(&d, s); }
2238 #endif
2239 #ifndef QT_BOOTSTRAPPED
QVariant(const QUrl & u)2240 QVariant::QVariant(const QUrl &u)
2241     : d(Url)
2242 { v_construct<QUrl>(&d, u); }
2243 #endif
QVariant(const QLocale & l)2244 QVariant::QVariant(const QLocale &l)
2245     : d(Locale)
2246 { v_construct<QLocale>(&d, l); }
2247 #ifndef QT_NO_REGEXP
QVariant(const QRegExp & regExp)2248 QVariant::QVariant(const QRegExp &regExp)
2249     : d(RegExp)
2250 { v_construct<QRegExp>(&d, regExp); }
2251 #endif // QT_NO_REGEXP
2252 #if QT_CONFIG(regularexpression)
QVariant(const QRegularExpression & re)2253 QVariant::QVariant(const QRegularExpression &re)
2254     : d(RegularExpression)
2255 { v_construct<QRegularExpression>(&d, re); }
2256 #endif // QT_CONFIG(regularexpression)
QVariant(const QUuid & uuid)2257 QVariant::QVariant(const QUuid &uuid)
2258     : d(Uuid)
2259 { v_construct<QUuid>(&d, uuid); }
2260 #ifndef QT_BOOTSTRAPPED
QVariant(const QJsonValue & jsonValue)2261 QVariant::QVariant(const QJsonValue &jsonValue)
2262     : d(QMetaType::QJsonValue)
2263 { v_construct<QJsonValue>(&d, jsonValue); }
QVariant(const QJsonObject & jsonObject)2264 QVariant::QVariant(const QJsonObject &jsonObject)
2265     : d(QMetaType::QJsonObject)
2266 { v_construct<QJsonObject>(&d, jsonObject); }
QVariant(const QJsonArray & jsonArray)2267 QVariant::QVariant(const QJsonArray &jsonArray)
2268     : d(QMetaType::QJsonArray)
2269 { v_construct<QJsonArray>(&d, jsonArray); }
QVariant(const QJsonDocument & jsonDocument)2270 QVariant::QVariant(const QJsonDocument &jsonDocument)
2271     : d(QMetaType::QJsonDocument)
2272 { v_construct<QJsonDocument>(&d, jsonDocument); }
2273 #endif // QT_BOOTSTRAPPED
2274 #if QT_CONFIG(itemmodel)
QVariant(const QModelIndex & modelIndex)2275 QVariant::QVariant(const QModelIndex &modelIndex)
2276     : d(ModelIndex)
2277 { v_construct<QModelIndex>(&d, modelIndex); }
QVariant(const QPersistentModelIndex & modelIndex)2278 QVariant::QVariant(const QPersistentModelIndex &modelIndex)
2279     : d(PersistentModelIndex)
2280 { 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 
type() const2315 QVariant::Type QVariant::type() const
2316 {
2317     return d.type >= QMetaType::User ? UserType : static_cast<Type>(d.type);
2318 }
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 
userType() const2327 int QVariant::userType() const
2328 {
2329     return d.type;
2330 }
2331 
2332 /*!
2333     Assigns the value of the variant \a variant to this variant.
2334 */
operator =(const QVariant & variant)2335 QVariant& QVariant::operator=(const QVariant &variant)
2336 {
2337     if (this == &variant)
2338         return *this;
2339 
2340     clear();
2341     if (variant.d.is_shared) {
2342         variant.d.data.shared->ref.ref();
2343         d = variant.d;
2344     } else if (variant.d.type > Char) {
2345         d.type = variant.d.type;
2346         handlerManager[d.type]->construct(&d, variant.constData());
2347         d.is_null = variant.d.is_null;
2348     } else {
2349         d = variant.d;
2350     }
2351 
2352     return *this;
2353 }
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 
detach()2369 void QVariant::detach()
2370 {
2371     if (!d.is_shared || d.data.shared->ref.loadRelaxed() == 1)
2372         return;
2373 
2374     Private dd;
2375     dd.type = d.type;
2376     handlerManager[d.type]->construct(&dd, constData());
2377     if (!d.data.shared->ref.deref())
2378         handlerManager[d.type]->clear(&d);
2379     d.data.shared = dd.data.shared;
2380 }
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 */
typeName() const2394 const char *QVariant::typeName() const
2395 {
2396     return QMetaType::typeName(d.type);
2397 }
2398 
2399 /*!
2400     Convert this variant to type QMetaType::UnknownType and free up any resources
2401     used.
2402 */
clear()2403 void QVariant::clear()
2404 {
2405     if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
2406         handlerManager[d.type]->clear(&d);
2407     d.type = Invalid;
2408     d.is_null = true;
2409     d.is_shared = false;
2410 }
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 */
typeToName(int typeId)2418 const char *QVariant::typeToName(int typeId)
2419 {
2420     return QMetaType::typeName(typeId);
2421 }
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 */
nameToType(const char * name)2431 QVariant::Type QVariant::nameToType(const char *name)
2432 {
2433     int metaType = QMetaType::type(name);
2434     return metaType <= int(UserType) ? QVariant::Type(metaType) : UserType;
2435 }
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 */
load(QDataStream & s)2487 void QVariant::load(QDataStream &s)
2488 {
2489     clear();
2490 
2491     quint32 typeId;
2492     s >> typeId;
2493     if (s.version() < QDataStream::Qt_4_0) {
2494         if (typeId >= MapFromThreeCount)
2495             return;
2496         typeId = mapIdFromQt3ToCurrent[typeId];
2497     } else if (s.version() < QDataStream::Qt_5_0) {
2498         if (typeId == 127 /* QVariant::UserType */) {
2499             typeId = QMetaType::User;
2500         } 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             typeId -= 97;
2504         } else if (typeId == 75 /* QSizePolicy */) {
2505             typeId = QMetaType::QSizePolicy;
2506         } 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             typeId -=1;
2510         }
2511     }
2512 
2513     qint8 is_null = false;
2514     if (s.version() >= QDataStream::Qt_4_2)
2515         s >> is_null;
2516     if (typeId == QVariant::UserType) {
2517         QByteArray name;
2518         s >> name;
2519         typeId = QMetaType::type(name.constData());
2520         if (typeId == QMetaType::UnknownType) {
2521             s.setStatus(QDataStream::ReadCorruptData);
2522             qWarning("QVariant::load: unknown user type with name %s.", name.constData());
2523             return;
2524         }
2525     }
2526     create(typeId, nullptr);
2527     d.is_null = is_null;
2528 
2529     if (!isValid()) {
2530         if (s.version() < QDataStream::Qt_5_0) {
2531         // Since we wrote something, we should read something
2532             QString x;
2533             s >> x;
2534         }
2535         d.is_null = true;
2536         return;
2537     }
2538 
2539     // const cast is safe since we operate on a newly constructed variant
2540     if (!QMetaType::load(s, d.type, const_cast<void *>(constData()))) {
2541         s.setStatus(QDataStream::ReadCorruptData);
2542         qWarning("QVariant::load: unable to load type %d.", d.type);
2543     }
2544 }
2545 
2546 /*!
2547     Internal function for saving a variant to the stream \a s. Use the
2548     stream operators instead.
2549 
2550     \internal
2551 */
save(QDataStream & s) const2552 void QVariant::save(QDataStream &s) const
2553 {
2554     quint32 typeId = d.type >= QMetaType::User ? QMetaType::User : userType();
2555     bool fakeUserType = false;
2556     if (s.version() < QDataStream::Qt_4_0) {
2557         int i;
2558         for (i = 0; i <= MapFromThreeCount - 1; ++i) {
2559             if (mapIdFromQt3ToCurrent[i] == typeId) {
2560                 typeId = i;
2561                 break;
2562             }
2563         }
2564         if (i >= MapFromThreeCount) {
2565             s << QVariant();
2566             return;
2567         }
2568     } else if (s.version() < QDataStream::Qt_5_0) {
2569         if (typeId == QMetaType::User) {
2570             typeId = 127; // QVariant::UserType had this value in Qt4
2571         } 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             typeId += 97;
2575         } else if (typeId == QMetaType::QSizePolicy) {
2576             typeId = 75;
2577         } else if (typeId >= QMetaType::QKeySequence && typeId <= QMetaType::QQuaternion) {
2578             // and as a result these types received lower ids too
2579             typeId +=1;
2580         } else if (typeId == QMetaType::QPolygonF || typeId == QMetaType::QUuid) {
2581             // These existed in Qt 4 only as a custom type
2582             typeId = 127;
2583             fakeUserType = true;
2584         }
2585     }
2586     s << typeId;
2587     if (s.version() >= QDataStream::Qt_4_2)
2588         s << qint8(d.is_null);
2589     if (d.type >= QVariant::UserType || fakeUserType) {
2590         s << QMetaType::typeName(userType());
2591     }
2592 
2593     if (!isValid()) {
2594         if (s.version() < QDataStream::Qt_5_0)
2595             s << QString();
2596         return;
2597     }
2598 
2599     if (!QMetaType::save(s, d.type, constData())) {
2600         qWarning("QVariant::save: unable to save type '%s' (type id: %d).\n", QMetaType::typeName(d.type), d.type);
2601         Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
2602     }
2603 }
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 */
operator >>(QDataStream & s,QVariant & p)2612 QDataStream& operator>>(QDataStream &s, QVariant &p)
2613 {
2614     p.load(s);
2615     return s;
2616 }
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 */
operator <<(QDataStream & s,const QVariant & p)2623 QDataStream& operator<<(QDataStream &s, const QVariant &p)
2624 {
2625     p.save(s);
2626     return s;
2627 }
2628 
2629 /*!
2630     Reads a variant type \a p in enum representation from the stream \a s.
2631 */
operator >>(QDataStream & s,QVariant::Type & p)2632 QDataStream& operator>>(QDataStream &s, QVariant::Type &p)
2633 {
2634     quint32 u;
2635     s >> u;
2636     p = (QVariant::Type)u;
2637 
2638     return s;
2639 }
2640 
2641 /*!
2642     Writes a variant type \a p to the stream \a s.
2643 */
operator <<(QDataStream & s,const QVariant::Type p)2644 QDataStream& operator<<(QDataStream &s, const QVariant::Type p)
2645 {
2646     s << static_cast<quint32>(p);
2647 
2648     return s;
2649 }
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>
qVariantToHelper(const QVariant::Private & d,const HandlersManager & handlerManager)2661 inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &handlerManager)
2662 {
2663     const uint targetType = qMetaTypeId<T>();
2664     if (d.type == targetType)
2665         return *v_cast<T>(&d);
2666 
2667     T ret;
2668     if (d.type >= QMetaType::User || targetType >= QMetaType::User) {
2669         const void * const from = constData(d);
2670         if (QMetaType::convert(from, d.type, &ret, targetType))
2671             return ret;
2672     }
2673 
2674     handlerManager[d.type]->convert(&d, targetType, &ret, nullptr);
2675     return ret;
2676 }
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 */
toStringList() const2688 QStringList QVariant::toStringList() const
2689 {
2690     return qVariantToHelper<QStringList>(d, handlerManager);
2691 }
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 */
toString() const2708 QString QVariant::toString() const
2709 {
2710     return qVariantToHelper<QString>(d, handlerManager);
2711 }
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 */
toMap() const2719 QVariantMap QVariant::toMap() const
2720 {
2721     return qVariantToHelper<QVariantMap>(d, handlerManager);
2722 }
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 */
toHash() const2730 QVariantHash QVariant::toHash() const
2731 {
2732     return qVariantToHelper<QVariantHash>(d, handlerManager);
2733 }
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 */
toDate() const2747 QDate QVariant::toDate() const
2748 {
2749     return qVariantToHelper<QDate>(d, handlerManager);
2750 }
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 */
toTime() const2764 QTime QVariant::toTime() const
2765 {
2766     return qVariantToHelper<QTime>(d, handlerManager);
2767 }
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 */
toDateTime() const2781 QDateTime QVariant::toDateTime() const
2782 {
2783     return qVariantToHelper<QDateTime>(d, handlerManager);
2784 }
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)
toEasingCurve() const2796 QEasingCurve QVariant::toEasingCurve() const
2797 {
2798     return qVariantToHelper<QEasingCurve>(d, handlerManager);
2799 }
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 */
toByteArray() const2811 QByteArray QVariant::toByteArray() const
2812 {
2813     return qVariantToHelper<QByteArray>(d, handlerManager);
2814 }
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 */
toPoint() const2826 QPoint QVariant::toPoint() const
2827 {
2828     return qVariantToHelper<QPoint>(d, handlerManager);
2829 }
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 */
toRect() const2839 QRect QVariant::toRect() const
2840 {
2841     return qVariantToHelper<QRect>(d, handlerManager);
2842 }
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 */
toSize() const2852 QSize QVariant::toSize() const
2853 {
2854     return qVariantToHelper<QSize>(d, handlerManager);
2855 }
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 */
toSizeF() const2865 QSizeF QVariant::toSizeF() const
2866 {
2867     return qVariantToHelper<QSizeF>(d, handlerManager);
2868 }
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 */
toRectF() const2879 QRectF QVariant::toRectF() const
2880 {
2881     return qVariantToHelper<QRectF>(d, handlerManager);
2882 }
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 */
toLineF() const2892 QLineF QVariant::toLineF() const
2893 {
2894     return qVariantToHelper<QLineF>(d, handlerManager);
2895 }
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 */
toLine() const2905 QLine QVariant::toLine() const
2906 {
2907     return qVariantToHelper<QLine>(d, handlerManager);
2908 }
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 */
toPointF() const2919 QPointF QVariant::toPointF() const
2920 {
2921     return qVariantToHelper<QPointF>(d, handlerManager);
2922 }
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 */
toUrl() const2935 QUrl QVariant::toUrl() const
2936 {
2937     return qVariantToHelper<QUrl>(d, handlerManager);
2938 }
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 */
toLocale() const2949 QLocale QVariant::toLocale() const
2950 {
2951     return qVariantToHelper<QLocale>(d, handlerManager);
2952 }
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
toRegExp() const2964 QRegExp QVariant::toRegExp() const
2965 {
2966     return qVariantToHelper<QRegExp>(d, handlerManager);
2967 }
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 */
toRegularExpression() const2980 QRegularExpression QVariant::toRegularExpression() const
2981 {
2982     return qVariantToHelper<QRegularExpression>(d, handlerManager);
2983 }
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 */
toModelIndex() const2995 QModelIndex QVariant::toModelIndex() const
2996 {
2997     return qVariantToHelper<QModelIndex>(d, handlerManager);
2998 }
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 */
toPersistentModelIndex() const3008 QPersistentModelIndex QVariant::toPersistentModelIndex() const
3009 {
3010     return qVariantToHelper<QPersistentModelIndex>(d, handlerManager);
3011 }
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 */
toUuid() const3023 QUuid QVariant::toUuid() const
3024 {
3025     return qVariantToHelper<QUuid>(d, handlerManager);
3026 }
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 */
toJsonValue() const3037 QJsonValue QVariant::toJsonValue() const
3038 {
3039     return qVariantToHelper<QJsonValue>(d, handlerManager);
3040 }
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 */
toJsonObject() const3050 QJsonObject QVariant::toJsonObject() const
3051 {
3052     return qVariantToHelper<QJsonObject>(d, handlerManager);
3053 }
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 */
toJsonArray() const3063 QJsonArray QVariant::toJsonArray() const
3064 {
3065     return qVariantToHelper<QJsonArray>(d, handlerManager);
3066 }
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 */
toJsonDocument() const3076 QJsonDocument QVariant::toJsonDocument() const
3077 {
3078     return qVariantToHelper<QJsonDocument>(d, handlerManager);
3079 }
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 */
toChar() const3091 QChar QVariant::toChar() const
3092 {
3093     return qVariantToHelper<QChar>(d, handlerManager);
3094 }
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 */
toBitArray() const3102 QBitArray QVariant::toBitArray() const
3103 {
3104     return qVariantToHelper<QBitArray>(d, handlerManager);
3105 }
3106 
3107 template <typename T>
qNumVariantToHelper(const QVariant::Private & d,const HandlersManager & handlerManager,bool * ok,const T & val)3108 inline T qNumVariantToHelper(const QVariant::Private &d,
3109                              const HandlersManager &handlerManager, bool *ok, const T& val)
3110 {
3111     const uint t = qMetaTypeId<T>();
3112     if (ok)
3113         *ok = true;
3114 
3115     if (d.type == t)
3116         return val;
3117 
3118     T ret = 0;
3119     if ((d.type >= QMetaType::User || t >= QMetaType::User)
3120         && QMetaType::convert(constData(d), d.type, &ret, t))
3121         return ret;
3122 
3123     if (!handlerManager[d.type]->convert(&d, t, &ret, ok) && ok)
3124         *ok = false;
3125     return ret;
3126 }
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 */
toInt(bool * ok) const3145 int QVariant::toInt(bool *ok) const
3146 {
3147     return qNumVariantToHelper<int>(d, handlerManager, ok, d.data.i);
3148 }
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 */
toUInt(bool * ok) const3167 uint QVariant::toUInt(bool *ok) const
3168 {
3169     return qNumVariantToHelper<uint>(d, handlerManager, ok, d.data.u);
3170 }
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 */
toLongLong(bool * ok) const3184 qlonglong QVariant::toLongLong(bool *ok) const
3185 {
3186     return qNumVariantToHelper<qlonglong>(d, handlerManager, ok, d.data.ll);
3187 }
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 */
toULongLong(bool * ok) const3201 qulonglong QVariant::toULongLong(bool *ok) const
3202 {
3203     return qNumVariantToHelper<qulonglong>(d, handlerManager, ok, d.data.ull);
3204 }
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 */
toBool() const3218 bool QVariant::toBool() const
3219 {
3220     if (d.type == Bool)
3221         return d.data.b;
3222 
3223     bool res = false;
3224     handlerManager[d.type]->convert(&d, Bool, &res, nullptr);
3225 
3226     return res;
3227 }
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 */
toDouble(bool * ok) const3241 double QVariant::toDouble(bool *ok) const
3242 {
3243     return qNumVariantToHelper<double>(d, handlerManager, ok, d.data.d);
3244 }
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 */
toFloat(bool * ok) const3260 float QVariant::toFloat(bool *ok) const
3261 {
3262     return qNumVariantToHelper<float>(d, handlerManager, ok, d.data.f);
3263 }
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 */
toReal(bool * ok) const3279 qreal QVariant::toReal(bool *ok) const
3280 {
3281     return qNumVariantToHelper<qreal>(d, handlerManager, ok, d.data.real);
3282 }
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 */
toList() const3291 QVariantList QVariant::toList() const
3292 {
3293     return qVariantToHelper<QVariantList>(d, handlerManager);
3294 }
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 */
canConvertMetaObject(const QMetaObject * from,const QMetaObject * to)3386 static bool canConvertMetaObject(const QMetaObject *from, const QMetaObject *to)
3387 {
3388     if (from && to == &QObject::staticMetaObject)
3389         return true;
3390 
3391     while (from) {
3392         if (from == to)
3393             return true;
3394         from = from->superClass();
3395     }
3396 
3397     return false;
3398 }
3399 #endif
3400 
canConvertMetaObject(int fromId,int toId,QObject * fromObject)3401 static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject)
3402 {
3403 #ifndef QT_BOOTSTRAPPED
3404     QMetaType toType(toId);
3405     if ((QMetaType::typeFlags(fromId) & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
3406         if (!fromObject)
3407             return true;
3408         return canConvertMetaObject(fromObject->metaObject(), toType.metaObject());
3409     }
3410 #else
3411     Q_UNUSED(fromId);
3412     Q_UNUSED(toId);
3413     Q_UNUSED(fromObject);
3414 #endif
3415     return false;
3416 }
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 */
canConvert(int targetTypeId) const3497 bool QVariant::canConvert(int targetTypeId) const
3498 {
3499     if (d.type == targetTypeId)
3500         return true;
3501 
3502 #if QT_CONFIG(itemmodel)
3503     if ((targetTypeId == QMetaType::QModelIndex && d.type == QMetaType::QPersistentModelIndex)
3504         || (targetTypeId == QMetaType::QPersistentModelIndex && d.type == QMetaType::QModelIndex))
3505         return true;
3506 #endif
3507 
3508     if (targetTypeId == QMetaType::QVariantList
3509             && (d.type == QMetaType::QVariantList
3510               || d.type == QMetaType::QStringList
3511               || d.type == QMetaType::QByteArrayList
3512               || QMetaType::hasRegisteredConverterFunction(d.type,
3513                     qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>()))) {
3514         return true;
3515     }
3516 
3517     if ((targetTypeId == QMetaType::QVariantHash || targetTypeId == QMetaType::QVariantMap)
3518             && (d.type == QMetaType::QVariantMap
3519               || d.type == QMetaType::QVariantHash
3520               || QMetaType::hasRegisteredConverterFunction(d.type,
3521                     qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()))) {
3522         return true;
3523     }
3524 
3525     if (targetTypeId == qMetaTypeId<QPair<QVariant, QVariant> >() &&
3526               QMetaType::hasRegisteredConverterFunction(d.type,
3527                     qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
3528         return true;
3529     }
3530 
3531     if ((d.type >= QMetaType::User || targetTypeId >= QMetaType::User)
3532         && QMetaType::hasRegisteredConverterFunction(d.type, targetTypeId)) {
3533         return true;
3534     }
3535 
3536     // TODO Reimplement this function, currently it works but it is a historical mess.
3537     uint currentType = d.type;
3538     if (currentType == QMetaType::SChar || currentType == QMetaType::Char)
3539         currentType = QMetaType::UInt;
3540     if (targetTypeId == QMetaType::SChar || currentType == QMetaType::Char)
3541         targetTypeId = QMetaType::UInt;
3542     if (currentType == QMetaType::Short || currentType == QMetaType::UShort)
3543         currentType = QMetaType::Int;
3544     if (targetTypeId == QMetaType::Short || currentType == QMetaType::UShort)
3545         targetTypeId = QMetaType::Int;
3546     if (currentType == QMetaType::Float)
3547         currentType = QMetaType::Double;
3548     if (targetTypeId == QMetaType::Float)
3549         targetTypeId = QMetaType::Double;
3550 
3551     if (currentType == uint(targetTypeId))
3552         return true;
3553 
3554     if (targetTypeId < 0)
3555         return false;
3556     if (targetTypeId >= QMetaType::User) {
3557         if (QMetaType::typeFlags(targetTypeId) & QMetaType::IsEnumeration) {
3558             targetTypeId = QMetaType::Int;
3559         } else {
3560             return canConvertMetaObject(currentType, targetTypeId, d.data.o);
3561         }
3562     }
3563 
3564     if (currentType == QMetaType::QJsonValue || targetTypeId == QMetaType::QJsonValue) {
3565         switch (currentType == QMetaType::QJsonValue ? targetTypeId : currentType) {
3566         case QMetaType::Nullptr:
3567         case QMetaType::QString:
3568         case QMetaType::Bool:
3569         case QMetaType::Int:
3570         case QMetaType::UInt:
3571         case QMetaType::Double:
3572         case QMetaType::Float:
3573         case QMetaType::ULong:
3574         case QMetaType::Long:
3575         case QMetaType::LongLong:
3576         case QMetaType::ULongLong:
3577         case QMetaType::UShort:
3578         case QMetaType::UChar:
3579         case QMetaType::Char:
3580         case QMetaType::SChar:
3581         case QMetaType::Short:
3582         case QMetaType::QVariantList:
3583         case QMetaType::QVariantMap:
3584         case QMetaType::QVariantHash:
3585         case QMetaType::QCborValue:
3586         case QMetaType::QCborArray:
3587         case QMetaType::QCborMap:
3588             return true;
3589         default:
3590             return false;
3591         }
3592     }
3593     if (currentType == QMetaType::QJsonArray)
3594         return targetTypeId == QMetaType::QVariantList || targetTypeId == QMetaType::QCborValue
3595                 || targetTypeId == QMetaType::QCborArray;
3596     if (currentType == QMetaType::QJsonObject)
3597         return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash
3598                 || targetTypeId == QMetaType::QCborValue || targetTypeId == QMetaType::QCborMap;
3599 
3600     if (currentType == QMetaType::QCborValue || targetTypeId == QMetaType::QCborValue) {
3601         switch (currentType == QMetaType::QCborValue ? targetTypeId : currentType) {
3602         case QMetaType::UnknownType:
3603         case QMetaType::Nullptr:
3604         case QMetaType::Bool:
3605         case QMetaType::Int:
3606         case QMetaType::UInt:
3607         case QMetaType::Double:
3608         case QMetaType::Float:
3609         case QMetaType::ULong:
3610         case QMetaType::Long:
3611         case QMetaType::LongLong:
3612         case QMetaType::ULongLong:
3613         case QMetaType::UShort:
3614         case QMetaType::UChar:
3615         case QMetaType::Char:
3616         case QMetaType::SChar:
3617         case QMetaType::Short:
3618         case QMetaType::QString:
3619         case QMetaType::QByteArray:
3620         case QMetaType::QDateTime:
3621         case QMetaType::QUrl:
3622         case QMetaType::QRegularExpression:
3623         case QMetaType::QUuid:
3624         case QMetaType::QVariantList:
3625         case QMetaType::QVariantMap:
3626         case QMetaType::QVariantHash:
3627         case QMetaType::QJsonValue:
3628         case QMetaType::QJsonArray:
3629         case QMetaType::QJsonObject:
3630         case QMetaType::QJsonDocument:
3631         case QMetaType::QCborArray:
3632         case QMetaType::QCborMap:
3633         case QMetaType::QCborSimpleType:
3634             return true;
3635         default:
3636             return false;
3637         }
3638     }
3639     if (currentType == QMetaType::QCborArray)
3640         return targetTypeId == QMetaType::QVariantList || targetTypeId == QMetaType::QCborValue
3641                 || targetTypeId == QMetaType::QJsonArray;
3642     if (currentType == QMetaType::QCborMap)
3643         return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash
3644                 || targetTypeId == QMetaType::QCborValue || targetTypeId == QMetaType::QJsonObject;
3645 
3646     // FIXME It should be LastCoreType intead of Uuid
3647     if (currentType > int(QMetaType::QUuid) || targetTypeId > int(QMetaType::QUuid)) {
3648         switch (uint(targetTypeId)) {
3649         case QVariant::Int:
3650             if (currentType == QVariant::KeySequence)
3651                 return true;
3652             Q_FALLTHROUGH();
3653         case QVariant::UInt:
3654         case QVariant::LongLong:
3655         case QVariant::ULongLong:
3656                return currentType == QMetaType::ULong
3657                    || currentType == QMetaType::Long
3658                    || currentType == QMetaType::UShort
3659                    || currentType == QMetaType::UChar
3660                    || currentType == QMetaType::Char
3661                    || currentType == QMetaType::SChar
3662                    || currentType == QMetaType::Short
3663                    || QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration;
3664         case QVariant::Image:
3665             return currentType == QVariant::Pixmap || currentType == QVariant::Bitmap;
3666         case QVariant::Pixmap:
3667             return currentType == QVariant::Image || currentType == QVariant::Bitmap
3668                               || currentType == QVariant::Brush;
3669         case QVariant::Bitmap:
3670             return currentType == QVariant::Pixmap || currentType == QVariant::Image;
3671         case QVariant::ByteArray:
3672             return currentType == QVariant::Color || currentType == QMetaType::Nullptr
3673                               || ((QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration) && QMetaType::metaObjectForType(currentType));
3674         case QVariant::String:
3675             return currentType == QVariant::KeySequence || currentType == QVariant::Font
3676                               || currentType == QVariant::Color || currentType == QMetaType::Nullptr
3677                               || ((QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration) && QMetaType::metaObjectForType(currentType));
3678         case QVariant::KeySequence:
3679             return currentType == QVariant::String || currentType == QVariant::Int;
3680         case QVariant::Font:
3681             return currentType == QVariant::String;
3682         case QVariant::Color:
3683             return currentType == QVariant::String || currentType == QVariant::ByteArray
3684                               || currentType == QVariant::Brush;
3685         case QVariant::Brush:
3686             return currentType == QVariant::Color || currentType == QVariant::Pixmap;
3687         case QMetaType::Long:
3688         case QMetaType::Char:
3689         case QMetaType::SChar:
3690         case QMetaType::UChar:
3691         case QMetaType::ULong:
3692         case QMetaType::Short:
3693         case QMetaType::UShort:
3694             return currentType == QVariant::Int
3695                 || (currentType < qCanConvertMatrixMaximumTargetType
3696                     && qCanConvertMatrix[QVariant::Int] & (1U << currentType))
3697                 || QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration;
3698         case QMetaType::QObjectStar:
3699             return canConvertMetaObject(currentType, targetTypeId, d.data.o);
3700         default:
3701             return false;
3702         }
3703     }
3704 
3705     if (targetTypeId == String && currentType == StringList)
3706         return v_cast<QStringList>(&d)->count() == 1;
3707     return currentType < qCanConvertMatrixMaximumTargetType
3708         && qCanConvertMatrix[targetTypeId] & (1U << currentType);
3709 }
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 
convert(int targetTypeId)3731 bool QVariant::convert(int targetTypeId)
3732 {
3733     if (d.type == uint(targetTypeId))
3734         return true;
3735 
3736     QVariant oldValue = *this;
3737 
3738     clear();
3739     if (!oldValue.canConvert(targetTypeId))
3740         return false;
3741 
3742     create(targetTypeId, nullptr);
3743     // Fail if the value is not initialized or was forced null by a previous failed convert.
3744     if (oldValue.d.is_null && oldValue.d.type != QMetaType::Nullptr)
3745         return false;
3746 
3747     if ((QMetaType::typeFlags(oldValue.userType()) & QMetaType::PointerToQObject) && (QMetaType::typeFlags(targetTypeId) & QMetaType::PointerToQObject)) {
3748         create(targetTypeId, &oldValue.d.data.o);
3749         return true;
3750     }
3751 
3752     bool isOk = true;
3753     int converterType = std::max(oldValue.userType(), targetTypeId);
3754     if (!handlerManager[converterType]->convert(&oldValue.d, targetTypeId, data(), &isOk))
3755         isOk = false;
3756     d.is_null = !isOk;
3757     return isOk;
3758 }
3759 
3760 /*!
3761   \fn bool QVariant::convert(const int type, void *ptr) const
3762   \internal
3763   Created for qvariant_cast() usage
3764 */
convert(const int type,void * ptr) const3765 bool QVariant::convert(const int type, void *ptr) const
3766 {
3767     return handlerManager[type]->convert(&d, type, ptr, nullptr);
3768 }
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 
qIsNumericType(uint tp)3896 static bool qIsNumericType(uint tp)
3897 {
3898     static const qulonglong numericTypeBits =
3899             Q_UINT64_C(1) << QMetaType::Bool |
3900             Q_UINT64_C(1) << QMetaType::Double |
3901             Q_UINT64_C(1) << QMetaType::Float |
3902             Q_UINT64_C(1) << QMetaType::Char |
3903             Q_UINT64_C(1) << QMetaType::SChar |
3904             Q_UINT64_C(1) << QMetaType::UChar |
3905             Q_UINT64_C(1) << QMetaType::Short |
3906             Q_UINT64_C(1) << QMetaType::UShort |
3907             Q_UINT64_C(1) << QMetaType::Int |
3908             Q_UINT64_C(1) << QMetaType::UInt |
3909             Q_UINT64_C(1) << QMetaType::Long |
3910             Q_UINT64_C(1) << QMetaType::ULong |
3911             Q_UINT64_C(1) << QMetaType::LongLong |
3912             Q_UINT64_C(1) << QMetaType::ULongLong;
3913     return tp < (CHAR_BIT * sizeof numericTypeBits) ? numericTypeBits & (Q_UINT64_C(1) << tp) : false;
3914 }
3915 
qIsFloatingPoint(uint tp)3916 static bool qIsFloatingPoint(uint tp)
3917 {
3918     return tp == QMetaType::Double || tp == QMetaType::Float;
3919 }
3920 
normalizeLowerRanks(uint tp)3921 static int normalizeLowerRanks(uint tp)
3922 {
3923     static const qulonglong numericTypeBits =
3924             Q_UINT64_C(1) << QMetaType::Bool |
3925             Q_UINT64_C(1) << QMetaType::Char |
3926             Q_UINT64_C(1) << QMetaType::SChar |
3927             Q_UINT64_C(1) << QMetaType::UChar |
3928             Q_UINT64_C(1) << QMetaType::Short |
3929             Q_UINT64_C(1) << QMetaType::UShort;
3930     return numericTypeBits & (Q_UINT64_C(1) << tp) ? uint(QMetaType::Int) : tp;
3931 }
3932 
normalizeLong(uint tp)3933 static int normalizeLong(uint tp)
3934 {
3935     const uint IntType = sizeof(long) == sizeof(int) ? QMetaType::Int : QMetaType::LongLong;
3936     const uint UIntType = sizeof(ulong) == sizeof(uint) ? QMetaType::UInt : QMetaType::ULongLong;
3937     return tp == QMetaType::Long ? IntType :
3938            tp == QMetaType::ULong ? UIntType : tp;
3939 }
3940 
numericTypePromotion(uint t1,uint t2)3941 static int numericTypePromotion(uint t1, uint t2)
3942 {
3943     Q_ASSERT(qIsNumericType(t1));
3944     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     if (qIsFloatingPoint(t1) || qIsFloatingPoint(t2))
3962         return QMetaType::QReal;
3963 
3964     // integral rules:
3965     // for all platforms we support, int can always hold the values of lower-ranked types
3966     t1 = normalizeLowerRanks(t1);
3967     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     t1 = normalizeLong(t1);
3971     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     if (t1 == QMetaType::ULongLong || t2 == QMetaType::ULongLong)
3979         return QMetaType::ULongLong;
3980     if (t1 == QMetaType::LongLong || t2 == QMetaType::LongLong)
3981         return QMetaType::LongLong;
3982     if (t1 == QMetaType::UInt || t2 == QMetaType::UInt)
3983         return QMetaType::UInt;
3984     return QMetaType::Int;
3985 }
3986 
integralCompare(uint promotedType,const QVariant::Private * d1,const QVariant::Private * d2)3987 static int integralCompare(uint promotedType, const QVariant::Private *d1, const QVariant::Private *d2)
3988 {
3989     // use toLongLong to retrieve the data, it gets us all the bits
3990     bool ok;
3991     qlonglong l1 = qConvertToNumber(d1, &ok);
3992     Q_ASSERT(ok);
3993 
3994     qlonglong l2 = qConvertToNumber(d2, &ok);
3995     Q_ASSERT(ok);
3996 
3997     if (promotedType == QMetaType::Int)
3998         return int(l1) < int(l2) ? -1 : int(l1) == int(l2) ? 0 : 1;
3999     if (promotedType == QMetaType::UInt)
4000         return uint(l1) < uint(l2) ? -1 : uint(l1) == uint(l2) ? 0 : 1;
4001     if (promotedType == QMetaType::LongLong)
4002         return l1 < l2 ? -1 : l1 == l2 ? 0 : 1;
4003     if (promotedType == QMetaType::ULongLong)
4004         return qulonglong(l1) < qulonglong(l2) ? -1 : qulonglong(l1) == qulonglong(l2) ? 0 : 1;
4005 
4006     Q_UNREACHABLE();
4007     return 0;
4008 }
4009 
numericCompare(const QVariant::Private * d1,const QVariant::Private * d2)4010 static int numericCompare(const QVariant::Private *d1, const QVariant::Private *d2)
4011 {
4012     uint promotedType = numericTypePromotion(d1->type, d2->type);
4013     if (promotedType != QMetaType::QReal)
4014         return integralCompare(promotedType, d1, d2);
4015 
4016     // qreal comparisons
4017     bool ok;
4018     qreal r1 = qConvertToRealNumber(d1, &ok);
4019     Q_ASSERT(ok);
4020     qreal r2 = qConvertToRealNumber(d2, &ok);
4021     Q_ASSERT(ok);
4022     if (r1 == r2)
4023         return 0;
4024 
4025     // only do fuzzy comparisons for finite, non-zero numbers
4026     int c1 = qFpClassify(r1);
4027     int c2 = qFpClassify(r2);
4028     if ((c1 == FP_NORMAL || c1 == FP_SUBNORMAL) && (c2 == FP_NORMAL || c2 == FP_SUBNORMAL)) {
4029         if (qFuzzyCompare(r1, r2))
4030             return 0;
4031     }
4032 
4033     return r1 < r2 ? -1 : 1;
4034 }
4035 
4036 /*!
4037     \internal
4038  */
cmp(const QVariant & v) const4039 bool QVariant::cmp(const QVariant &v) const
4040 {
4041     auto cmp_helper = [] (const QVariant::Private &d1, const QVariant::Private &d2)
4042     {
4043         Q_ASSERT(d1.type == d2.type);
4044         if (d1.type >= QMetaType::User) {
4045             int result;
4046             if (QMetaType::equals(QT_PREPEND_NAMESPACE(constData(d1)), QT_PREPEND_NAMESPACE(constData(d2)), d1.type, &result))
4047                 return result == 0;
4048         }
4049         return handlerManager[d1.type]->compare(&d1, &d2);
4050     };
4051 
4052     // try numerics first, with C++ type promotion rules (no conversion)
4053     if (qIsNumericType(d.type) && qIsNumericType(v.d.type))
4054         return numericCompare(&d, &v.d) == 0;
4055 
4056     if (d.type == v.d.type)
4057         return cmp_helper(d, v.d);
4058 
4059     QVariant v1 = *this;
4060     QVariant v2 = v;
4061     if (v2.canConvert(v1.d.type)) {
4062         if (!v2.convert(v1.d.type))
4063             return false;
4064     } else {
4065         // try the opposite conversion, it might work
4066         qSwap(v1, v2);
4067         if (!v2.convert(v1.d.type))
4068             return false;
4069     }
4070     return cmp_helper(v1.d, v2.d);
4071 }
4072 
4073 /*!
4074     \internal
4075  */
compare(const QVariant & v) const4076 int QVariant::compare(const QVariant &v) const
4077 {
4078     // try numerics first, with C++ type promotion rules (no conversion)
4079     if (qIsNumericType(d.type) && qIsNumericType(v.d.type))
4080         return numericCompare(&d, &v.d);
4081 
4082     // check for equality next, as more types implement operator== than operator<
4083     if (cmp(v))
4084         return 0;
4085 
4086     const QVariant *v1 = this;
4087     const QVariant *v2 = &v;
4088     QVariant converted1;
4089     QVariant converted2;
4090 
4091     if (d.type != v.d.type) {
4092         // if both types differ, try to convert
4093         if (v2->canConvert(v1->d.type)) {
4094             converted2 = *v2;
4095             if (converted2.convert(v1->d.type))
4096                 v2 = &converted2;
4097         }
4098         if (v1->d.type != v2->d.type && v1->canConvert(v2->d.type)) {
4099             converted1 = *v1;
4100             if (converted1.convert(v2->d.type))
4101                 v1 = &converted1;
4102         }
4103         if (v1->d.type != v2->d.type) {
4104             // if conversion fails, default to toString
4105             int r = v1->toString().compare(v2->toString(), Qt::CaseInsensitive);
4106             if (r == 0) {
4107                 // cmp(v) returned false, so we should try to agree with it.
4108                 return (v1->d.type < v2->d.type) ? -1 : 1;
4109             }
4110             return r;
4111         }
4112 
4113         // did we end up with two numerics? If so, restart
4114         if (qIsNumericType(v1->d.type) && qIsNumericType(v2->d.type))
4115             return v1->compare(*v2);
4116     }
4117     if (v1->d.type >= QMetaType::User) {
4118         int result;
4119         if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(d)), QT_PREPEND_NAMESPACE(constData(v2->d)), d.type, &result))
4120             return result;
4121     }
4122     switch (v1->d.type) {
4123     case QVariant::Date:
4124         return v1->toDate() < v2->toDate() ? -1 : 1;
4125     case QVariant::Time:
4126         return v1->toTime() < v2->toTime() ? -1 : 1;
4127     case QVariant::DateTime:
4128         return v1->toDateTime() < v2->toDateTime() ? -1 : 1;
4129     case QVariant::StringList:
4130         return v1->toStringList() < v2->toStringList() ? -1 : 1;
4131     }
4132     int r = v1->toString().compare(v2->toString(), Qt::CaseInsensitive);
4133     if (r == 0) {
4134         // cmp(v) returned false, so we should try to agree with it.
4135         return (d.type < v.d.type) ? -1 : 1;
4136     }
4137     return r;
4138 }
4139 
4140 /*!
4141     \internal
4142  */
4143 
constData() const4144 const void *QVariant::constData() const
4145 {
4146     return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr);
4147 }
4148 
4149 /*!
4150     \fn const void* QVariant::data() const
4151 
4152     \internal
4153 */
4154 
4155 /*!
4156     \internal
4157 */
data()4158 void* QVariant::data()
4159 {
4160     detach();
4161     return const_cast<void *>(constData());
4162 }
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 */
isNull() const4177 bool QVariant::isNull() const
4178 {
4179     return handlerManager[d.type]->isNull(&d);
4180 }
4181 
4182 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug dbg,const QVariant & v)4183 QDebug operator<<(QDebug dbg, const QVariant &v)
4184 {
4185     QDebugStateSaver saver(dbg);
4186     const uint typeId = v.d.type;
4187     dbg.nospace() << "QVariant(";
4188     if (typeId != QMetaType::UnknownType) {
4189         dbg << QMetaType::typeName(typeId) << ", ";
4190         bool userStream = false;
4191         bool canConvertToString = false;
4192         if (typeId >= QMetaType::User) {
4193             userStream = QMetaType::debugStream(dbg, constData(v.d), typeId);
4194             canConvertToString = v.canConvert<QString>();
4195         }
4196         if (!userStream && canConvertToString)
4197             dbg << v.toString();
4198         else if (!userStream)
4199             handlerManager[typeId]->debugStream(dbg, v);
4200     } else {
4201         dbg << "Invalid";
4202     }
4203     dbg << ')';
4204     return dbg;
4205 }
4206 
operator <<(QDebug dbg,const QVariant::Type p)4207 QDebug operator<<(QDebug dbg, const QVariant::Type p)
4208 {
4209     QDebugStateSaver saver(dbg);
4210     dbg.nospace() << "QVariant::"
4211                   << (int(p) != int(QMetaType::UnknownType)
4212                      ? QMetaType::typeName(p)
4213                      : "Invalid");
4214     return dbg;
4215 }
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)
QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl)4480 QSequentialIterable::QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl)
4481 #else
4482 QSequentialIterable::QSequentialIterable(const QtMetaTypePrivate::QSequentialIterableImpl &impl)
4483 #endif
4484   : m_impl(impl)
4485 {
4486 }
4487 
const_iterator(const QSequentialIterable & iter,QAtomicInt * ref_)4488 QSequentialIterable::const_iterator::const_iterator(const QSequentialIterable &iter, QAtomicInt *ref_)
4489   : m_impl(iter.m_impl), ref(ref_)
4490 {
4491     ref->ref();
4492 }
4493 
const_iterator(const QtMetaTypePrivate::QSequentialIterableImpl & impl,QAtomicInt * ref_)4494 QSequentialIterable::const_iterator::const_iterator(const QtMetaTypePrivate::QSequentialIterableImpl &impl, QAtomicInt *ref_)
4495   : m_impl(impl), ref(ref_)
4496 {
4497     ref->ref();
4498 }
4499 
begin()4500 void QSequentialIterable::const_iterator::begin()
4501 {
4502     m_impl.moveToBegin();
4503 }
4504 
end()4505 void QSequentialIterable::const_iterator::end()
4506 {
4507     m_impl.moveToEnd();
4508 }
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 */
begin() const4517 QSequentialIterable::const_iterator QSequentialIterable::begin() const
4518 {
4519     const_iterator it(*this, new QAtomicInt(0));
4520     it.begin();
4521     return it;
4522 }
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 */
end() const4530 QSequentialIterable::const_iterator QSequentialIterable::end() const
4531 {
4532     const_iterator it(*this, new QAtomicInt(0));
4533     it.end();
4534     return it;
4535 }
4536 
variantFromVariantDataHelper(const QtMetaTypePrivate::VariantData & d)4537 static const QVariant variantFromVariantDataHelper(const QtMetaTypePrivate::VariantData &d) {
4538     QVariant v;
4539     if (d.metaTypeId == qMetaTypeId<QVariant>())
4540         v =  *reinterpret_cast<const QVariant*>(d.data);
4541     else
4542         v = QVariant(d.metaTypeId, d.data, d.flags & ~QVariantConstructionFlags::ShouldDeleteVariantData);
4543     if (d.flags & QVariantConstructionFlags::ShouldDeleteVariantData)
4544         QMetaType::destroy(d.metaTypeId, const_cast<void *>(d.data));
4545     return v;
4546 }
4547 
4548 /*!
4549     Returns the element at position \a idx in the container.
4550 */
at(int idx) const4551 QVariant QSequentialIterable::at(int idx) const
4552 {
4553     const QtMetaTypePrivate::VariantData d = m_impl.at(idx);
4554     return variantFromVariantDataHelper(d);
4555 }
4556 
4557 /*!
4558     Returns the number of elements in the container.
4559 */
size() const4560 int QSequentialIterable::size() const
4561 {
4562     return m_impl.size();
4563 }
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 */
canReverseIterate() const4570 bool QSequentialIterable::canReverseIterate() const
4571 {
4572     return m_impl._iteratorCapabilities & QtMetaTypePrivate::BiDirectionalCapability;
4573 }
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 */
~const_iterator()4593 QSequentialIterable::const_iterator::~const_iterator() {
4594     if (!ref->deref()) {
4595         m_impl.destroyIter();
4596         delete ref;
4597     }
4598 }
4599 
4600 /*!
4601     Creates a copy of \a other.
4602 */
const_iterator(const const_iterator & other)4603 QSequentialIterable::const_iterator::const_iterator(const const_iterator &other)
4604   : m_impl(other.m_impl), ref(other.ref)
4605 {
4606     ref->ref();
4607 }
4608 
4609 /*!
4610     Assigns \a other to this.
4611 */
4612 QSequentialIterable::const_iterator&
operator =(const const_iterator & other)4613 QSequentialIterable::const_iterator::operator=(const const_iterator &other)
4614 {
4615     other.ref->ref();
4616     if (!ref->deref()) {
4617         m_impl.destroyIter();
4618         delete ref;
4619     }
4620     m_impl = other.m_impl;
4621     ref = other.ref;
4622     return *this;
4623 }
4624 
4625 /*!
4626     Returns the current item, converted to a QVariant.
4627 */
operator *() const4628 const QVariant QSequentialIterable::const_iterator::operator*() const
4629 {
4630     const QtMetaTypePrivate::VariantData d = m_impl.getCurrent();
4631     return variantFromVariantDataHelper(d);
4632 }
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 */
operator ==(const const_iterator & other) const4640 bool QSequentialIterable::const_iterator::operator==(const const_iterator &other) const
4641 {
4642     return m_impl.equal(other.m_impl);
4643 }
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 */
operator !=(const const_iterator & other) const4651 bool QSequentialIterable::const_iterator::operator!=(const const_iterator &other) const
4652 {
4653     return !m_impl.equal(other.m_impl);
4654 }
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 */
operator ++()4665 QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator++()
4666 {
4667     m_impl.advance(1);
4668     return *this;
4669 }
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 */
operator ++(int)4678 QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator++(int)
4679 {
4680     QtMetaTypePrivate::QSequentialIterableImpl impl;
4681     impl.copy(m_impl);
4682     m_impl.advance(1);
4683     return const_iterator(impl, new QAtomicInt(0));
4684 }
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 */
operator --()4697 QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator--()
4698 {
4699     m_impl.advance(-1);
4700     return *this;
4701 }
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 */
operator --(int)4714 QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator--(int)
4715 {
4716     QtMetaTypePrivate::QSequentialIterableImpl impl;
4717     impl.copy(m_impl);
4718     m_impl.advance(-1);
4719     return const_iterator(impl, new QAtomicInt(0));
4720 }
4721 
4722 /*!
4723     Advances the iterator by \a j items.
4724 
4725     \sa operator-=(), operator+()
4726 */
operator +=(int j)4727 QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator+=(int j)
4728 {
4729     m_impl.advance(j);
4730     return *this;
4731 }
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 */
operator -=(int j)4741 QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator-=(int j)
4742 {
4743     m_impl.advance(-j);
4744     return *this;
4745 }
4746 
4747 /*!
4748     Returns an iterator to the item at \a j positions forward from
4749     this iterator.
4750 
4751     \sa operator-(), operator+=()
4752 */
operator +(int j) const4753 QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator+(int j) const
4754 {
4755     QtMetaTypePrivate::QSequentialIterableImpl impl;
4756     impl.copy(m_impl);
4757     impl.advance(j);
4758     return const_iterator(impl, new QAtomicInt(0));
4759 }
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 */
operator -(int j) const4770 QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator-(int j) const
4771 {
4772     QtMetaTypePrivate::QSequentialIterableImpl impl;
4773     impl.copy(m_impl);
4774     impl.advance(-j);
4775     return const_iterator(impl, new QAtomicInt(0));
4776 }
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)
QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl)4799 QAssociativeIterable::QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl)
4800 #else
4801 QAssociativeIterable::QAssociativeIterable(const QtMetaTypePrivate::QAssociativeIterableImpl &impl)
4802 #endif
4803   : m_impl(impl)
4804 {
4805 }
4806 
const_iterator(const QAssociativeIterable & iter,QAtomicInt * ref_)4807 QAssociativeIterable::const_iterator::const_iterator(const QAssociativeIterable &iter, QAtomicInt *ref_)
4808   : m_impl(iter.m_impl), ref(ref_)
4809 {
4810     ref->ref();
4811 }
4812 
const_iterator(const QtMetaTypePrivate::QAssociativeIterableImpl & impl,QAtomicInt * ref_)4813 QAssociativeIterable::const_iterator::const_iterator(const QtMetaTypePrivate::QAssociativeIterableImpl &impl, QAtomicInt *ref_)
4814   : m_impl(impl), ref(ref_)
4815 {
4816     ref->ref();
4817 }
4818 
begin()4819 void QAssociativeIterable::const_iterator::begin()
4820 {
4821     m_impl.begin();
4822 }
4823 
end()4824 void QAssociativeIterable::const_iterator::end()
4825 {
4826     m_impl.end();
4827 }
4828 
find(const QVariant & key)4829 void QAssociativeIterable::const_iterator::find(const QVariant &key)
4830 {
4831     Q_ASSERT(key.userType() == m_impl._metaType_id_key);
4832     const QtMetaTypePrivate::VariantData dkey(key.userType(), key.constData(), 0 /*key.flags()*/);
4833     m_impl.find(dkey);
4834 }
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 */
begin() const4842 QAssociativeIterable::const_iterator QAssociativeIterable::begin() const
4843 {
4844     const_iterator it(*this, new QAtomicInt(0));
4845     it.begin();
4846     return it;
4847 }
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 */
end() const4855 QAssociativeIterable::const_iterator QAssociativeIterable::end() const
4856 {
4857     const_iterator it(*this, new QAtomicInt(0));
4858     it.end();
4859     return it;
4860 }
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 */
find(const QVariant & key) const4874 QAssociativeIterable::const_iterator QAssociativeIterable::find(const QVariant &key) const
4875 {
4876     const_iterator it(*this, new QAtomicInt(0));
4877     QVariant key_ = key;
4878     if (key_.canConvert(m_impl._metaType_id_key) && key_.convert(m_impl._metaType_id_key))
4879         it.find(key_);
4880     else
4881         it.end();
4882     return it;
4883 }
4884 
4885 /*!
4886     Returns the value for the given \a key in the container, if the types are convertible.
4887 
4888     \sa find()
4889 */
value(const QVariant & key) const4890 QVariant QAssociativeIterable::value(const QVariant &key) const
4891 {
4892     const const_iterator it = find(key);
4893     if (it == end())
4894         return QVariant();
4895     return *it;
4896 }
4897 
4898 /*!
4899     Returns the number of elements in the container.
4900 */
size() const4901 int QAssociativeIterable::size() const
4902 {
4903     return m_impl.size();
4904 }
4905 
4906 /*!
4907     \class QAssociativeIterable::const_iterator
4908     \since 5.2
4909     \inmodule QtCore
4910     \brief The QAssociativeIterable::const_iterator allows iteration over a container in a QVariant.
4911 
4912     A QAssociativeIterable::const_iterator can only be created by a QAssociativeIterable instance,
4913     and can be used in a way similar to other stl-style iterators.
4914 
4915     \snippet code/src_corelib_kernel_qvariant.cpp 10
4916 
4917     \sa QAssociativeIterable
4918 */
4919 
4920 
4921 /*!
4922     Destroys the QAssociativeIterable::const_iterator.
4923 */
~const_iterator()4924 QAssociativeIterable::const_iterator::~const_iterator()
4925 {
4926     if (!ref->deref()) {
4927         m_impl.destroyIter();
4928         delete ref;
4929     }
4930 }
4931 
4932 /*!
4933     Creates a copy of \a other.
4934 */
const_iterator(const const_iterator & other)4935 QAssociativeIterable::const_iterator::const_iterator(const const_iterator &other)
4936   : m_impl(other.m_impl), ref(other.ref)
4937 {
4938     ref->ref();
4939 }
4940 
4941 /*!
4942     Assigns \a other to this.
4943 */
4944 QAssociativeIterable::const_iterator&
operator =(const const_iterator & other)4945 QAssociativeIterable::const_iterator::operator=(const const_iterator &other)
4946 {
4947     other.ref->ref();
4948     if (!ref->deref()) {
4949         m_impl.destroyIter();
4950         delete ref;
4951     }
4952     m_impl = other.m_impl;
4953     ref = other.ref;
4954     return *this;
4955 }
4956 
4957 /*!
4958     Returns the current value, converted to a QVariant.
4959 */
operator *() const4960 const QVariant QAssociativeIterable::const_iterator::operator*() const
4961 {
4962     const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue();
4963     return variantFromVariantDataHelper(d);
4964 }
4965 
4966 /*!
4967     Returns the current key, converted to a QVariant.
4968 */
key() const4969 const QVariant QAssociativeIterable::const_iterator::key() const
4970 {
4971     const QtMetaTypePrivate::VariantData d = m_impl.getCurrentKey();
4972     return variantFromVariantDataHelper(d);
4973 }
4974 
4975 /*!
4976     Returns the current value, converted to a QVariant.
4977 */
value() const4978 const QVariant QAssociativeIterable::const_iterator::value() const
4979 {
4980     return operator*();
4981 }
4982 
4983 /*!
4984     Returns \c true if \a other points to the same item as this
4985     iterator; otherwise returns \c false.
4986 
4987     \sa operator!=()
4988 */
operator ==(const const_iterator & other) const4989 bool QAssociativeIterable::const_iterator::operator==(const const_iterator &other) const
4990 {
4991     return m_impl.equal(other.m_impl);
4992 }
4993 
4994 /*!
4995     Returns \c true if \a other points to a different item than this
4996     iterator; otherwise returns \c false.
4997 
4998     \sa operator==()
4999 */
operator !=(const const_iterator & other) const5000 bool QAssociativeIterable::const_iterator::operator!=(const const_iterator &other) const
5001 {
5002     return !m_impl.equal(other.m_impl);
5003 }
5004 
5005 /*!
5006     The prefix ++ operator (\c{++it}) advances the iterator to the
5007     next item in the container and returns an iterator to the new current
5008     item.
5009 
5010     Calling this function on QAssociativeIterable::end() leads to undefined results.
5011 
5012     \sa operator--()
5013 */
operator ++()5014 QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator++()
5015 {
5016     m_impl.advance(1);
5017     return *this;
5018 }
5019 
5020 /*!
5021     \overload
5022 
5023     The postfix ++ operator (\c{it++}) advances the iterator to the
5024     next item in the container and returns an iterator to the previously
5025     current item.
5026 */
operator ++(int)5027 QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator++(int)
5028 {
5029     QtMetaTypePrivate::QAssociativeIterableImpl impl;
5030     impl.copy(m_impl);
5031     m_impl.advance(1);
5032     return const_iterator(impl, new QAtomicInt(0));
5033 }
5034 
5035 /*!
5036     The prefix -- operator (\c{--it}) makes the preceding item
5037     current and returns an iterator to the new current item.
5038 
5039     Calling this function on QAssociativeIterable::begin() leads to undefined results.
5040 
5041     \sa operator++()
5042 */
operator --()5043 QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator--()
5044 {
5045     m_impl.advance(-1);
5046     return *this;
5047 }
5048 
5049 /*!
5050     \overload
5051 
5052     The postfix -- operator (\c{it--}) makes the preceding item
5053     current and returns an iterator to the previously current item.
5054 */
operator --(int)5055 QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator--(int)
5056 {
5057     QtMetaTypePrivate::QAssociativeIterableImpl impl;
5058     impl.copy(m_impl);
5059     m_impl.advance(-1);
5060     return const_iterator(impl, new QAtomicInt(0));
5061 }
5062 
5063 /*!
5064     Advances the iterator by \a j items.
5065 
5066     \sa operator-=(), operator+()
5067 */
operator +=(int j)5068 QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator+=(int j)
5069 {
5070     m_impl.advance(j);
5071     return *this;
5072 }
5073 
5074 /*!
5075     Makes the iterator go back by \a j items.
5076 
5077     \sa operator+=(), operator-()
5078 */
operator -=(int j)5079 QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator-=(int j)
5080 {
5081     m_impl.advance(-j);
5082     return *this;
5083 }
5084 
5085 /*!
5086     Returns an iterator to the item at \a j positions forward from
5087     this iterator.
5088 
5089     \sa operator-(), operator+=()
5090 */
operator +(int j) const5091 QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator+(int j) const
5092 {
5093     QtMetaTypePrivate::QAssociativeIterableImpl impl;
5094     impl.copy(m_impl);
5095     impl.advance(j);
5096     return const_iterator(impl, new QAtomicInt(0));
5097 }
5098 
5099 /*!
5100     Returns an iterator to the item at \a j positions backward from
5101     this iterator.
5102 
5103     \sa operator+(), operator-=()
5104 */
operator -(int j) const5105 QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator-(int j) const
5106 {
5107     QtMetaTypePrivate::QAssociativeIterableImpl impl;
5108     impl.copy(m_impl);
5109     impl.advance(-j);
5110     return const_iterator(impl, new QAtomicInt(0));
5111 }
5112 
5113 QT_END_NAMESPACE
5114