1/****************************************************************************
2**
3** Copyright (C) 2019 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#include "qeasingcurve.h"
50#include "qlist.h"
51#if QT_CONFIG(regularexpression)
52#include "qregularexpression.h"
53#endif
54#include "qstring.h"
55#include "qstringlist.h"
56#include "qurl.h"
57#include "qlocale.h"
58#include "quuid.h"
59#if QT_CONFIG(itemmodel)
60#include "qabstractitemmodel.h"
61#endif
62#ifndef QT_BOOTSTRAPPED
63#include "qcborarray.h"
64#include "qcborcommon.h"
65#include "qcbormap.h"
66#include "qjsonvalue.h"
67#include "qjsonobject.h"
68#include "qjsonarray.h"
69#include "qjsondocument.h"
70#include "qbytearraylist.h"
71#endif
72#include "private/qvariant_p.h"
73#include "private/qlocale_p.h"
74#include "qmetatype_p.h"
75#include <qmetaobject.h>
76
77#ifndef QT_NO_GEOM_VARIANT
78#include "qsize.h"
79#include "qpoint.h"
80#include "qrect.h"
81#include "qline.h"
82#endif
83
84#include <cmath>
85#include <float.h>
86#include <cstring>
87
88QT_BEGIN_NAMESPACE
89
90namespace {
91class HandlersManager
92{
93 static const QVariant::Handler *Handlers[QModulesPrivate::ModulesCount];
94public:
95 const QVariant::Handler *operator[] (const uint typeId) const
96 {
97 return Handlers[QModulesPrivate::moduleForType(typeId)];
98 }
99
100 void registerHandler(const QModulesPrivate::Names name, const QVariant::Handler *handler)
101 {
102 Handlers[name] = handler;
103 }
104};
105} // namespace
106
107namespace {
108struct CoreTypesFilter {
109 template<typename T>
110 struct Acceptor {
111 static const bool IsAccepted = QModulesPrivate::QTypeModuleInfo<T>::IsCore && QtMetaTypePrivate::TypeDefinition<T>::IsAvailable;
112 };
113};
114} // annonymous
115
116namespace { // annonymous used to hide QVariant handlers
117
118static void construct(QVariant::Private *x, const void *copy)
119{
120 QVariantConstructor<CoreTypesFilter> constructor(x, copy);
121 QMetaTypeSwitcher::switcher<void>(constructor, x->type, 0);
122}
123
124static void clear(QVariant::Private *d)
125{
126 QVariantDestructor<CoreTypesFilter> cleaner(d);
127 QMetaTypeSwitcher::switcher<void>(cleaner, d->type, 0);
128}
129
130static bool isNull(const QVariant::Private *d)
131{
132 QVariantIsNull<CoreTypesFilter> isNull(d);
133 return QMetaTypeSwitcher::switcher<bool>(isNull, d->type, 0);
134}
135
136/*!
137 \internal
138
139 Compares \a a to \a b. The caller guarantees that \a a and \a b
140 are of the same type.
141 */
142static bool compare(const QVariant::Private *a, const QVariant::Private *b)
143{
144 QVariantComparator<CoreTypesFilter> comparator(a, b);
145 return QMetaTypeSwitcher::switcher<bool>(comparator, a->type, 0);
146}
147
148/*!
149 \internal
150 */
151static qlonglong qMetaTypeNumber(const QVariant::Private *d)
152{
153 switch (d->type) {
154 case QMetaType::Int:
155 return d->data.i;
156 case QMetaType::LongLong:
157 return d->data.ll;
158 case QMetaType::Char:
159 return qlonglong(d->data.c);
160 case QMetaType::SChar:
161 return qlonglong(d->data.sc);
162 case QMetaType::Short:
163 return qlonglong(d->data.s);
164 case QMetaType::Long:
165 return qlonglong(d->data.l);
166 case QMetaType::Float:
167 return qRound64(d->data.f);
168 case QVariant::Double:
169 return qRound64(d->data.d);
170#ifndef QT_BOOTSTRAPPED
171 case QMetaType::QJsonValue:
172 return v_cast<QJsonValue>(d)->toDouble();
173 case QMetaType::QCborValue:
174 return v_cast<QCborValue>(d)->toInteger();
175#endif
176 }
177 Q_ASSERT(false);
178 return 0;
179}
180
181static qulonglong qMetaTypeUNumber(const QVariant::Private *d)
182{
183 switch (d->type) {
184 case QVariant::UInt:
185 return d->data.u;
186 case QVariant::ULongLong:
187 return d->data.ull;
188 case QMetaType::UChar:
189 return d->data.uc;
190 case QMetaType::UShort:
191 return d->data.us;
192 case QMetaType::ULong:
193 return d->data.ul;
194 }
195 Q_ASSERT(false);
196 return 0;
197}
198
199static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
200{
201 *ok = true;
202
203 switch (uint(d->type)) {
204 case QVariant::String:
205 return v_cast<QString>(d)->toLongLong(ok);
206 case QVariant::Char:
207 return v_cast<QChar>(d)->unicode();
208 case QVariant::ByteArray:
209 return v_cast<QByteArray>(d)->toLongLong(ok);
210 case QVariant::Bool:
211 return qlonglong(d->data.b);
212#ifndef QT_BOOTSTRAPPED
213 case QMetaType::QCborValue:
214 if (!v_cast<QCborValue>(d)->isInteger() && !v_cast<QCborValue>(d)->isDouble())
215 break;
216 return qMetaTypeNumber(d);
217 case QMetaType::QJsonValue:
218 if (!v_cast<QJsonValue>(d)->isDouble())
219 break;
220 Q_FALLTHROUGH();
221#endif
222 case QVariant::Double:
223 case QVariant::Int:
224 case QMetaType::Char:
225 case QMetaType::SChar:
226 case QMetaType::Short:
227 case QMetaType::Long:
228 case QMetaType::Float:
229 case QMetaType::LongLong:
230 return qMetaTypeNumber(d);
231 case QVariant::ULongLong:
232 case QVariant::UInt:
233 case QMetaType::UChar:
234 case QMetaType::UShort:
235 case QMetaType::ULong:
236
237 return qlonglong(qMetaTypeUNumber(d));
238 }
239
240 QMetaType typeInfo(d->type);
241 if (typeInfo.flags() & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
242 switch (typeInfo.sizeOf()) {
243 case 1:
244 return d->is_shared ? *reinterpret_cast<signed char *>(d->data.shared->ptr) : d->data.sc;
245 case 2:
246 return d->is_shared ? *reinterpret_cast<qint16 *>(d->data.shared->ptr) : d->data.s;
247 case 4:
248 return d->is_shared ? *reinterpret_cast<qint32 *>(d->data.shared->ptr) : d->data.i;
249 case 8:
250 return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->ptr) : d->data.ll;
251 }
252 }
253
254 *ok = false;
255 return Q_INT64_C(0);
256}
257
258static qreal qConvertToRealNumber(const QVariant::Private *d, bool *ok)
259{
260 *ok = true;
261 switch (uint(d->type)) {
262 case QVariant::Double:
263 return qreal(d->data.d);
264 case QMetaType::Float:
265 return qreal(d->data.f);
266 case QVariant::ULongLong:
267 case QVariant::UInt:
268 case QMetaType::UChar:
269 case QMetaType::UShort:
270 case QMetaType::ULong:
271 return qreal(qMetaTypeUNumber(d));
272#ifndef QT_BOOTSTRAPPED
273 case QMetaType::QCborValue:
274 return v_cast<QCborValue>(d)->toDouble();
275 case QMetaType::QJsonValue:
276 return v_cast<QJsonValue>(d)->toDouble();
277#endif
278 default:
279 // includes enum conversion as well as invalid types
280 return qreal(qConvertToNumber(d, ok));
281 }
282}
283
284static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
285{
286 *ok = true;
287
288 switch (uint(d->type)) {
289 case QVariant::String:
290 return v_cast<QString>(d)->toULongLong(ok);
291 case QVariant::Char:
292 return v_cast<QChar>(d)->unicode();
293 case QVariant::ByteArray:
294 return v_cast<QByteArray>(d)->toULongLong(ok);
295 case QVariant::Bool:
296 return qulonglong(d->data.b);
297#ifndef QT_BOOTSTRAPPED
298 case QMetaType::QCborValue:
299 if (v_cast<QCborValue>(d)->isDouble())
300 return qulonglong(qConvertToRealNumber(d, ok));
301 if (!v_cast<QCborValue>(d)->isInteger())
302 return false;
303 return qulonglong(qMetaTypeNumber(d));
304 case QMetaType::QJsonValue:
305 if (!v_cast<QJsonValue>(d)->isDouble())
306 break;
307 Q_FALLTHROUGH();
308#endif
309 case QVariant::Double:
310 case QVariant::Int:
311 case QMetaType::Char:
312 case QMetaType::SChar:
313 case QMetaType::Short:
314 case QMetaType::Long:
315 case QMetaType::Float:
316 case QMetaType::LongLong:
317 return qulonglong(qMetaTypeNumber(d));
318 case QVariant::ULongLong:
319 case QVariant::UInt:
320 case QMetaType::UChar:
321 case QMetaType::UShort:
322 case QMetaType::ULong:
323 return qMetaTypeUNumber(d);
324 }
325
326 QMetaType typeInfo(d->type);
327 if (typeInfo.flags() & QMetaType::IsEnumeration) {
328 switch (typeInfo.sizeOf()) {
329 case 1:
330 return d->is_shared ? *reinterpret_cast<uchar *>(d->data.shared->ptr) : d->data.uc;
331 case 2:
332 return d->is_shared ? *reinterpret_cast<quint16 *>(d->data.shared->ptr) : d->data.us;
333 case 4:
334 return d->is_shared ? *reinterpret_cast<quint32 *>(d->data.shared->ptr) : d->data.u;
335 case 8:
336 return d->is_shared ? *reinterpret_cast<qint64 *>(d->data.shared->ptr) : d->data.ull;
337 }
338 }
339
340 *ok = false;
341 return Q_UINT64_C(0);
342}
343
344template<typename TInput, typename LiteralWrapper>
345inline bool qt_convertToBool(const QVariant::Private *const d)
346{
347 TInput str = v_cast<TInput>(d)->toLower();
348 return !(str.isEmpty() || str == LiteralWrapper("0") || str == LiteralWrapper("false"));
349}
350
351/*!
352 \internal
353 Returns the internal data pointer from \a d.
354 */
355
356static const void *constData(const QVariant::Private &d)
357{
358 return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.c);
359}
360
361#ifndef QT_NO_QOBJECT
362/*!
363 \internal
364 returns a QMetaEnum for a given meta tape type id if possible
365*/
366static QMetaEnum metaEnumFromType(int type)
367{
368 QMetaType t(type);
369 if (t.flags() & QMetaType::IsEnumeration) {
370 if (const QMetaObject *metaObject = t.metaObject()) {
371 const char *enumName = QMetaType::typeName(type);
372 const char *lastColon = std::strrchr(enumName, ':');
373 if (lastColon)
374 enumName = lastColon + 1;
375 return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
376 }
377 }
378 return QMetaEnum();
379}
380#endif
381
382/*!
383 \internal
384
385 Converts \a d to type \a t, which is placed in \a result.
386 */
387static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
388{
389 Q_ASSERT(d->type != uint(t));
390 Q_ASSERT(result);
391
392 if (d->type >= QMetaType::User || t >= QMetaType::User) {
393 const bool isOk = QMetaType::convert(constData(*d), d->type, result, t);
394 if (ok)
395 *ok = isOk;
396 if (isOk)
397 return true;
398 }
399
400 bool dummy;
401 if (!ok)
402 ok = &dummy;
403
404 switch (uint(t)) {
405#ifndef QT_BOOTSTRAPPED
406 case QVariant::Url:
407 switch (d->type) {
408 case QVariant::String:
409 *static_cast<QUrl *>(result) = QUrl(*v_cast<QString>(d));
410 break;
411 case QMetaType::QCborValue:
412 if (v_cast<QCborValue>(d)->isUrl()) {
413 *static_cast<QUrl *>(result) = v_cast<QCborValue>(d)->toUrl();
414 break;
415 }
416 return false;
417 default:
418 return false;
419 }
420 break;
421#endif // QT_BOOTSTRAPPED
422#if QT_CONFIG(itemmodel)
423 case QVariant::ModelIndex:
424 switch (d->type) {
425 case QVariant::PersistentModelIndex:
426 *static_cast<QModelIndex *>(result) = QModelIndex(*v_cast<QPersistentModelIndex>(d));
427 break;
428 default:
429 return false;
430 }
431 break;
432 case QVariant::PersistentModelIndex:
433 switch (d->type) {
434 case QVariant::ModelIndex:
435 *static_cast<QPersistentModelIndex *>(result) = QPersistentModelIndex(*v_cast<QModelIndex>(d));
436 break;
437 default:
438 return false;
439 }
440 break;
441#endif // QT_CONFIG(itemmodel)
442 case QVariant::String: {
443 QString *str = static_cast<QString *>(result);
444 switch (d->type) {
445 case QVariant::Char:
446 *str = *v_cast<QChar>(d);
447 break;
448 case QMetaType::Char:
449 case QMetaType::SChar:
450 case QMetaType::UChar:
451 *str = QChar::fromLatin1(d->data.c);
452 break;
453 case QMetaType::Short:
454 case QMetaType::Long:
455 case QVariant::Int:
456 case QVariant::LongLong:
457 *str = QString::number(qMetaTypeNumber(d));
458 break;
459 case QVariant::UInt:
460 case QVariant::ULongLong:
461 case QMetaType::UShort:
462 case QMetaType::ULong:
463 *str = QString::number(qMetaTypeUNumber(d));
464 break;
465 case QMetaType::Float:
466 *str = QString::number(d->data.f, 'g', QLocale::FloatingPointShortest);
467 break;
468 case QVariant::Double:
469 *str = QString::number(d->data.d, 'g', QLocale::FloatingPointShortest);
470 break;
471#if QT_CONFIG(datestring)
472 case QVariant::Date:
473 *str = v_cast<QDate>(d)->toString(Qt::ISODate);
474 break;
475 case QVariant::Time:
476 *str = v_cast<QTime>(d)->toString(Qt::ISODateWithMs);
477 break;
478 case QVariant::DateTime:
479 *str = v_cast<QDateTime>(d)->toString(Qt::ISODateWithMs);
480 break;
481#endif
482 case QVariant::Bool:
483 *str = d->data.b ? QStringLiteral("true") : QStringLiteral("false");
484 break;
485 case QVariant::ByteArray:
486 *str = QString::fromUtf8(v_cast<QByteArray>(d)->constData());
487 break;
488 case QVariant::StringList:
489 if (v_cast<QStringList>(d)->count() == 1)
490 *str = v_cast<QStringList>(d)->at(0);
491 break;
492#ifndef QT_BOOTSTRAPPED
493 case QVariant::Url:
494 *str = v_cast<QUrl>(d)->toString();
495 break;
496 case QMetaType::QJsonValue:
497 if (v_cast<QJsonValue>(d)->isString())
498 *str = v_cast<QJsonValue>(d)->toString();
499 else if (!v_cast<QJsonValue>(d)->isNull())
500 return false;
501 break;
502 case QMetaType::QCborValue:
503 if (v_cast<QCborValue>(d)->isContainer() || v_cast<QCborValue>(d)->isTag())
504 return false;
505 *str = v_cast<QCborValue>(d)->toVariant().toString();
506 break;
507#endif
508 case QVariant::Uuid:
509 *str = v_cast<QUuid>(d)->toString();
510 break;
511 case QMetaType::Nullptr:
512 *str = QString();
513 break;
514 default:
515#ifndef QT_NO_QOBJECT
516 {
517 QMetaEnum en = metaEnumFromType(d->type);
518 if (en.isValid()) {
519 *str = QString::fromUtf8(en.valueToKey(qConvertToNumber(d, ok)));
520 return *ok;
521 }
522 }
523#endif
524 return false;
525 }
526 break;
527 }
528 case QVariant::Char: {
529 QChar *c = static_cast<QChar *>(result);
530 switch (d->type) {
531 case QVariant::Int:
532 case QVariant::LongLong:
533 case QMetaType::Char:
534 case QMetaType::SChar:
535 case QMetaType::Short:
536 case QMetaType::Long:
537 case QMetaType::Float:
538 *c = QChar(ushort(qMetaTypeNumber(d)));
539 break;
540 case QVariant::UInt:
541 case QVariant::ULongLong:
542 case QMetaType::UChar:
543 case QMetaType::UShort:
544 case QMetaType::ULong:
545 *c = QChar(ushort(qMetaTypeUNumber(d)));
546 break;
547 default:
548 return false;
549 }
550 break;
551 }
552#ifndef QT_NO_GEOM_VARIANT
553 case QVariant::Size: {
554 QSize *s = static_cast<QSize *>(result);
555 switch (d->type) {
556 case QVariant::SizeF:
557 *s = v_cast<QSizeF>(d)->toSize();
558 break;
559 default:
560 return false;
561 }
562 break;
563 }
564
565 case QVariant::SizeF: {
566 QSizeF *s = static_cast<QSizeF *>(result);
567 switch (d->type) {
568 case QVariant::Size:
569 *s = QSizeF(*(v_cast<QSize>(d)));
570 break;
571 default:
572 return false;
573 }
574 break;
575 }
576
577 case QVariant::Line: {
578 QLine *s = static_cast<QLine *>(result);
579 switch (d->type) {
580 case QVariant::LineF:
581 *s = v_cast<QLineF>(d)->toLine();
582 break;
583 default:
584 return false;
585 }
586 break;
587 }
588
589 case QVariant::LineF: {
590 QLineF *s = static_cast<QLineF *>(result);
591 switch (d->type) {
592 case QVariant::Line:
593 *s = QLineF(*(v_cast<QLine>(d)));
594 break;
595 default:
596 return false;
597 }
598 break;
599 }
600#endif
601 case QVariant::StringList:
602 if (d->type == QVariant::List) {
603 QStringList *slst = static_cast<QStringList *>(result);
604 const QVariantList *list = v_cast<QVariantList >(d);
605 const int size = list->size();
606 slst->reserve(size);
607 for (int i = 0; i < size; ++i)
608 slst->append(list->at(i).toString());
609 } else if (d->type == QVariant::String) {
610 QStringList *slst = static_cast<QStringList *>(result);
611 *slst = QStringList(*v_cast<QString>(d));
612 } else {
613 return false;
614 }
615 break;
616 case QVariant::Date: {
617 QDate *dt = static_cast<QDate *>(result);
618 if (d->type == QVariant::DateTime)
619 *dt = v_cast<QDateTime>(d)->date();
620#if QT_CONFIG(datestring)
621 else if (d->type == QVariant::String)
622 *dt = QDate::fromString(*v_cast<QString>(d), Qt::ISODate);
623#endif
624 else
625 return false;
626
627 return dt->isValid();
628 }
629 case QVariant::Time: {
630 QTime *t = static_cast<QTime *>(result);
631 switch (d->type) {
632 case QVariant::DateTime:
633 *t = v_cast<QDateTime>(d)->time();
634 break;
635#if QT_CONFIG(datestring)
636 case QVariant::String:
637 *t = QTime::fromString(*v_cast<QString>(d), Qt::ISODate);
638 break;
639#endif
640 default:
641 return false;
642 }
643 return t->isValid();
644 }
645 case QVariant::DateTime: {
646 QDateTime *dt = static_cast<QDateTime *>(result);
647 switch (d->type) {
648#if QT_CONFIG(datestring)
649 case QVariant::String:
650 *dt = QDateTime::fromString(*v_cast<QString>(d), Qt::ISODate);
651 break;
652# ifndef QT_BOOTSTRAPPED
653 case QMetaType::QCborValue:
654 if (v_cast<QCborValue>(d)->isDateTime())
655 *dt = v_cast<QCborValue>(d)->toDateTime();
656 else
657 return false;
658 break;
659# endif
660#endif
661 case QVariant::Date:
662 *dt = QDateTime(*v_cast<QDate>(d));
663 break;
664 default:
665 return false;
666 }
667 return dt->isValid();
668 }
669 case QVariant::ByteArray: {
670 QByteArray *ba = static_cast<QByteArray *>(result);
671 switch (d->type) {
672 case QVariant::String:
673 *ba = v_cast<QString>(d)->toUtf8();
674 break;
675 case QVariant::Double:
676 *ba = QByteArray::number(d->data.d, 'g', QLocale::FloatingPointShortest);
677 break;
678 case QMetaType::Float:
679 *ba = QByteArray::number(d->data.f, 'g', QLocale::FloatingPointShortest);
680 break;
681 case QMetaType::Char:
682 case QMetaType::SChar:
683 case QMetaType::UChar:
684 *ba = QByteArray(1, d->data.c);
685 break;
686 case QVariant::Int:
687 case QVariant::LongLong:
688 case QMetaType::Short:
689 case QMetaType::Long:
690 *ba = QByteArray::number(qMetaTypeNumber(d));
691 break;
692 case QVariant::UInt:
693 case QVariant::ULongLong:
694 case QMetaType::UShort:
695 case QMetaType::ULong:
696 *ba = QByteArray::number(qMetaTypeUNumber(d));
697 break;
698 case QVariant::Bool:
699 *ba = QByteArray(d->data.b ? "true" : "false");
700 break;
701 case QVariant::Uuid:
702 *ba = v_cast<QUuid>(d)->toByteArray();
703 break;
704 case QMetaType::Nullptr:
705 *ba = QByteArray();
706 break;
707#ifndef QT_BOOTSTRAPPED
708 case QMetaType::QCborValue:
709 if (v_cast<QCborValue>(d)->isByteArray())
710 *ba = v_cast<QCborValue>(d)->toByteArray();
711 else
712 return false;
713 break;
714#endif
715 default:
716#ifndef QT_NO_QOBJECT
717 {
718 QMetaEnum en = metaEnumFromType(d->type);
719 if (en.isValid()) {
720 *ba = en.valueToKey(qConvertToNumber(d, ok));
721 return *ok;
722 }
723 }
724#endif
725 return false;
726 }
727 }
728 break;
729 case QMetaType::Short:
730 *static_cast<short *>(result) = short(qConvertToNumber(d, ok));
731 return *ok;
732 case QMetaType::Long:
733 *static_cast<long *>(result) = long(qConvertToNumber(d, ok));
734 return *ok;
735 case QMetaType::UShort:
736 *static_cast<ushort *>(result) = ushort(qConvertToUnsignedNumber(d, ok));
737 return *ok;
738 case QMetaType::ULong:
739 *static_cast<ulong *>(result) = ulong(qConvertToUnsignedNumber(d, ok));
740 return *ok;
741 case QVariant::Int:
742 *static_cast<int *>(result) = int(qConvertToNumber(d, ok));
743 return *ok;
744 case QVariant::UInt:
745 *static_cast<uint *>(result) = uint(qConvertToUnsignedNumber(d, ok));
746 return *ok;
747 case QVariant::LongLong:
748 *static_cast<qlonglong *>(result) = qConvertToNumber(d, ok);
749 return *ok;
750 case QVariant::ULongLong: {
751 *static_cast<qulonglong *>(result) = qConvertToUnsignedNumber(d, ok);
752 return *ok;
753 }
754 case QMetaType::SChar: {
755 signed char s = qConvertToNumber(d, ok);
756 *static_cast<signed char*>(result) = s;
757 return *ok;
758 }
759 case QMetaType::UChar: {
760 *static_cast<uchar *>(result) = qConvertToUnsignedNumber(d, ok);
761 return *ok;
762 }
763 case QVariant::Bool: {
764 bool *b = static_cast<bool *>(result);
765 switch(d->type) {
766 case QVariant::ByteArray:
767 *b = qt_convertToBool<QByteArray, const char*>(d);
768 break;
769 case QVariant::String:
770 *b = qt_convertToBool<QString, QLatin1String>(d);
771 break;
772 case QVariant::Char:
773 *b = !v_cast<QChar>(d)->isNull();
774 break;
775 case QVariant::Double:
776 case QVariant::Int:
777 case QVariant::LongLong:
778 case QMetaType::Char:
779 case QMetaType::SChar:
780 case QMetaType::Short:
781 case QMetaType::Long:
782 case QMetaType::Float:
783 *b = qMetaTypeNumber(d) != Q_INT64_C(0);
784 break;
785 case QVariant::UInt:
786 case QVariant::ULongLong:
787 case QMetaType::UChar:
788 case QMetaType::UShort:
789 case QMetaType::ULong:
790 *b = qMetaTypeUNumber(d) != Q_UINT64_C(0);
791 break;
792#ifndef QT_BOOTSTRAPPED
793 case QMetaType::QCborValue:
794 *b = v_cast<QCborValue>(d)->toBool();
795 if (!v_cast<QCborValue>(d)->isBool())
796 return false;
797 break;
798 case QMetaType::QJsonValue:
799 *b = v_cast<QJsonValue>(d)->toBool(false);
800 if (!v_cast<QJsonValue>(d)->isBool())
801 return false;
802 break;
803#endif
804 default:
805 *b = false;
806 return false;
807 }
808 break;
809 }
810 case QVariant::Double: {
811 double *f = static_cast<double *>(result);
812 switch (d->type) {
813 case QVariant::String:
814 *f = v_cast<QString>(d)->toDouble(ok);
815 break;
816 case QVariant::ByteArray:
817 *f = v_cast<QByteArray>(d)->toDouble(ok);
818 break;
819 case QVariant::Bool:
820 *f = double(d->data.b);
821 break;
822 case QMetaType::Float:
823 *f = double(d->data.f);
824 break;
825 case QVariant::LongLong:
826 case QVariant::Int:
827 case QMetaType::Char:
828 case QMetaType::SChar:
829 case QMetaType::Short:
830 case QMetaType::Long:
831 *f = double(qMetaTypeNumber(d));
832 break;
833 case QVariant::UInt:
834 case QVariant::ULongLong:
835 case QMetaType::UChar:
836 case QMetaType::UShort:
837 case QMetaType::ULong:
838 *f = double(qMetaTypeUNumber(d));
839 break;
840#ifndef QT_BOOTSTRAPPED
841 case QMetaType::QCborValue:
842 *f = v_cast<QCborValue>(d)->toDouble();
843 if (!v_cast<QCborValue>(d)->isDouble())
844 return false;
845 break;
846 case QMetaType::QJsonValue:
847 *f = v_cast<QJsonValue>(d)->toDouble(0.0);
848 if (!v_cast<QJsonValue>(d)->isDouble())
849 return false;
850 break;
851#endif
852 default:
853 *f = 0.0;
854 return false;
855 }
856 break;
857 }
858 case QMetaType::Float: {
859 float *f = static_cast<float *>(result);
860 switch (d->type) {
861 case QVariant::String:
862 *f = v_cast<QString>(d)->toFloat(ok);
863 break;
864 case QVariant::ByteArray:
865 *f = v_cast<QByteArray>(d)->toFloat(ok);
866 break;
867 case QVariant::Bool:
868 *f = float(d->data.b);
869 break;
870 case QVariant::Double:
871 *f = float(d->data.d);
872 break;
873 case QVariant::LongLong:
874 case QVariant::Int:
875 case QMetaType::Char:
876 case QMetaType::SChar:
877 case QMetaType::Short:
878 case QMetaType::Long:
879 *f = float(qMetaTypeNumber(d));
880 break;
881 case QVariant::UInt:
882 case QVariant::ULongLong:
883 case QMetaType::UChar:
884 case QMetaType::UShort:
885 case QMetaType::ULong:
886 *f = float(qMetaTypeUNumber(d));
887 break;
888#ifndef QT_BOOTSTRAPPED
889 case QMetaType::QCborValue:
890 *f = v_cast<QCborValue>(d)->toDouble();
891 if (!v_cast<QCborValue>(d)->isDouble())
892 return false;
893 break;
894 case QMetaType::QJsonValue:
895 *f = v_cast<QJsonValue>(d)->toDouble(0.0);
896 if (!v_cast<QJsonValue>(d)->isDouble())
897 return false;
898 break;
899#endif
900 default:
901 *f = 0.0f;
902 return false;
903 }
904 break;
905 }
906 case QVariant::List:
907 if (d->type == QVariant::StringList) {
908 QVariantList *lst = static_cast<QVariantList *>(result);
909 const QStringList *slist = v_cast<QStringList>(d);
910 const int size = slist->size();
911 lst->reserve(size);
912 for (int i = 0; i < size; ++i)
913 lst->append(QVariant(slist->at(i)));
914 } else if (qstrcmp(QMetaType::typeName(d->type), "QList<QVariant>") == 0) {
915 *static_cast<QVariantList *>(result) =
916 *static_cast<QList<QVariant> *>(d->data.shared->ptr);
917#ifndef QT_BOOTSTRAPPED
918 } else if (d->type == QMetaType::QCborValue) {
919 if (!v_cast<QCborValue>(d)->isArray())
920 return false;
921 *static_cast<QVariantList *>(result) = v_cast<QCborValue>(d)->toArray().toVariantList();
922 } else if (d->type == QMetaType::QCborArray) {
923 *static_cast<QVariantList *>(result) = v_cast<QCborArray>(d)->toVariantList();
924 } else if (d->type == QMetaType::QJsonValue) {
925 if (!v_cast<QJsonValue>(d)->isArray())
926 return false;
927 *static_cast<QVariantList *>(result) = v_cast<QJsonValue>(d)->toArray().toVariantList();
928 } else if (d->type == QMetaType::QJsonArray) {
929 *static_cast<QVariantList *>(result) = v_cast<QJsonArray>(d)->toVariantList();
930#endif
931 } else {
932 return false;
933 }
934 break;
935 case QVariant::Map:
936 if (qstrcmp(QMetaType::typeName(d->type), "QMap<QString, QVariant>") == 0) {
937 *static_cast<QVariantMap *>(result) =
938 *static_cast<QMap<QString, QVariant> *>(d->data.shared->ptr);
939 } else if (d->type == QVariant::Hash) {
940 QVariantMap *map = static_cast<QVariantMap *>(result);
941 const QVariantHash *hash = v_cast<QVariantHash>(d);
942 const auto end = hash->end();
943 for (auto it = hash->begin(); it != end; ++it)
944 map->insertMulti(it.key(), it.value());
945#ifndef QT_BOOTSTRAPPED
946 } else if (d->type == QMetaType::QCborValue) {
947 if (!v_cast<QCborValue>(d)->isMap())
948 return false;
949 *static_cast<QVariantMap *>(result) = v_cast<QCborValue>(d)->toMap().toVariantMap();
950 } else if (d->type == QMetaType::QCborMap) {
951 *static_cast<QVariantMap *>(result) = v_cast<QCborMap>(d)->toVariantMap();
952 } else if (d->type == QMetaType::QJsonValue) {
953 if (!v_cast<QJsonValue>(d)->isObject())
954 return false;
955 *static_cast<QVariantMap *>(result) = v_cast<QJsonValue>(d)->toObject().toVariantMap();
956 } else if (d->type == QMetaType::QJsonObject) {
957 *static_cast<QVariantMap *>(result) = v_cast<QJsonObject>(d)->toVariantMap();
958#endif
959 } else {
960 return false;
961 }
962 break;
963 case QVariant::Hash:
964 if (qstrcmp(QMetaType::typeName(d->type), "QHash<QString, QVariant>") == 0) {
965 *static_cast<QVariantHash *>(result) =
966 *static_cast<QHash<QString, QVariant> *>(d->data.shared->ptr);
967 } else if (d->type == QVariant::Map) {
968 QVariantHash *hash = static_cast<QVariantHash *>(result);
969 const QVariantMap *map = v_cast<QVariantMap>(d);
970 const auto end = map->end();
971 for (auto it = map->begin(); it != end; ++it)
972 hash->insertMulti(it.key(), it.value());
973#ifndef QT_BOOTSTRAPPED
974 } else if (d->type == QMetaType::QCborValue) {
975 if (!v_cast<QCborValue>(d)->isMap())
976 return false;
977 *static_cast<QVariantHash *>(result) = v_cast<QCborValue>(d)->toMap().toVariantHash();
978 } else if (d->type == QMetaType::QCborMap) {
979 *static_cast<QVariantHash *>(result) = v_cast<QCborMap>(d)->toVariantHash();
980 } else if (d->type == QMetaType::QJsonValue) {
981 if (!v_cast<QJsonValue>(d)->isObject())
982 return false;
983 *static_cast<QVariantHash *>(result) = v_cast<QJsonValue>(d)->toObject().toVariantHash();
984 } else if (d->type == QMetaType::QJsonObject) {
985 *static_cast<QVariantHash *>(result) = v_cast<QJsonObject>(d)->toVariantHash();
986#endif
987 } else {
988 return false;
989 }
990 break;
991#ifndef QT_NO_GEOM_VARIANT
992 case QVariant::Rect:
993 if (d->type == QVariant::RectF)
994 *static_cast<QRect *>(result) = (v_cast<QRectF>(d))->toRect();
995 else
996 return false;
997 break;
998 case QVariant::RectF:
999 if (d->type == QVariant::Rect)
1000 *static_cast<QRectF *>(result) = *v_cast<QRect>(d);
1001 else
1002 return false;
1003 break;
1004 case QVariant::PointF:
1005 if (d->type == QVariant::Point)
1006 *static_cast<QPointF *>(result) = *v_cast<QPoint>(d);
1007 else
1008 return false;
1009 break;
1010 case QVariant::Point:
1011 if (d->type == QVariant::PointF)
1012 *static_cast<QPoint *>(result) = (v_cast<QPointF>(d))->toPoint();
1013 else
1014 return false;
1015 break;
1016 case QMetaType::Char:
1017 {
1018 *static_cast<qint8 *>(result) = qint8(qConvertToNumber(d, ok));
1019 return *ok;
1020 }
1021#endif
1022 case QVariant::Uuid:
1023 switch (d->type) {
1024 case QVariant::String:
1025 *static_cast<QUuid *>(result) = QUuid(*v_cast<QString>(d));
1026 break;
1027 case QVariant::ByteArray:
1028 *static_cast<QUuid *>(result) = QUuid(*v_cast<QByteArray>(d));
1029 break;
1030#ifndef QT_BOOTSTRAPPED
1031 case QMetaType::QCborValue:
1032 if (!v_cast<QCborValue>(d)->isUuid())
1033 return false;
1034 *static_cast<QUuid *>(result) = v_cast<QCborValue>(d)->toUuid();
1035 break;
1036#endif
1037 default:
1038 return false;
1039 }
1040 break;
1041 case QMetaType::Nullptr:
1042 *static_cast<std::nullptr_t *>(result) = nullptr;
1043 if (QMetaType::typeFlags(t) & (QMetaType::PointerToGadget | QMetaType::PointerToQObject)
1044 || d->type == QMetaType::VoidStar) {
1045 if (v_cast<const void *>(d) == nullptr)
1046 break;
1047 }
1048#ifndef QT_BOOTSTRAPPED
1049 if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isNull())
1050 break;
1051#endif
1052 return false;
1053
1054#ifndef QT_BOOTSTRAPPED
1055#if QT_CONFIG(regularexpression)
1056 case QMetaType::QRegularExpression:
1057 if (d->type != QMetaType::QCborValue || !v_cast<QCborValue>(d)->isRegularExpression())
1058 return false;
1059 *static_cast<QRegularExpression *>(result) = v_cast<QCborValue>(d)->toRegularExpression();
1060 break;
1061#endif
1062 case QMetaType::QJsonValue:
1063 switch (d->type) {
1064 case QMetaType::Nullptr:
1065 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Null);
1066 break;
1067 case QVariant::Bool:
1068 *static_cast<QJsonValue *>(result) = QJsonValue(d->data.b);
1069 break;
1070 case QMetaType::Int:
1071 case QMetaType::UInt:
1072 case QMetaType::Double:
1073 case QMetaType::Float:
1074 case QMetaType::ULong:
1075 case QMetaType::Long:
1076 case QMetaType::LongLong:
1077 case QMetaType::ULongLong:
1078 case QMetaType::UShort:
1079 case QMetaType::UChar:
1080 case QMetaType::Char:
1081 case QMetaType::SChar:
1082 case QMetaType::Short:
1083 *static_cast<QJsonValue *>(result) = QJsonValue(qConvertToRealNumber(d, ok));
1084 Q_ASSERT(ok);
1085 break;
1086 case QVariant::String:
1087 *static_cast<QJsonValue *>(result) = QJsonValue(*v_cast<QString>(d));
1088 break;
1089 case QVariant::StringList:
1090 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonArray::fromStringList(*v_cast<QStringList>(d)));
1091 break;
1092 case QVariant::List:
1093 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonArray::fromVariantList(*v_cast<QVariantList>(d)));
1094 break;
1095 case QVariant::Map:
1096 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonObject::fromVariantMap(*v_cast<QVariantMap>(d)));
1097 break;
1098 case QVariant::Hash:
1099 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonObject::fromVariantHash(*v_cast<QVariantHash>(d)));
1100 break;
1101 case QMetaType::QJsonObject:
1102 *static_cast<QJsonValue *>(result) = *v_cast<QJsonObject>(d);
1103 break;
1104 case QMetaType::QJsonArray:
1105 *static_cast<QJsonValue *>(result) = *v_cast<QJsonArray>(d);
1106 break;
1107 case QMetaType::QJsonDocument: {
1108 QJsonDocument doc = *v_cast<QJsonDocument>(d);
1109 *static_cast<QJsonValue *>(result) = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1110 break;
1111 }
1112 case QMetaType::QCborValue:
1113 *static_cast<QJsonValue *>(result) = v_cast<QCborValue>(d)->toJsonValue();
1114 break;
1115 case QMetaType::QCborMap:
1116 *static_cast<QJsonValue *>(result) = v_cast<QCborMap>(d)->toJsonObject();
1117 break;
1118 case QMetaType::QCborArray:
1119 *static_cast<QJsonValue *>(result) = v_cast<QCborArray>(d)->toJsonArray();
1120 break;
1121 default:
1122 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Undefined);
1123 return false;
1124 }
1125 break;
1126 case QMetaType::QJsonArray:
1127 switch (d->type) {
1128 case QVariant::StringList:
1129 *static_cast<QJsonArray *>(result) = QJsonArray::fromStringList(*v_cast<QStringList>(d));
1130 break;
1131 case QVariant::List:
1132 *static_cast<QJsonArray *>(result) = QJsonArray::fromVariantList(*v_cast<QVariantList>(d));
1133 break;
1134 case QMetaType::QJsonValue:
1135 if (!v_cast<QJsonValue>(d)->isArray())
1136 return false;
1137 *static_cast<QJsonArray *>(result) = v_cast<QJsonValue>(d)->toArray();
1138 break;
1139 case QMetaType::QJsonDocument:
1140 if (!v_cast<QJsonDocument>(d)->isArray())
1141 return false;
1142 *static_cast<QJsonArray *>(result) = v_cast<QJsonDocument>(d)->array();
1143 break;
1144 case QMetaType::QCborValue:
1145 if (!v_cast<QCborValue>(d)->isArray())
1146 return false;
1147 *static_cast<QJsonArray *>(result) = v_cast<QCborValue>(d)->toArray().toJsonArray();
1148 break;
1149 case QMetaType::QCborArray:
1150 *static_cast<QJsonArray *>(result) = v_cast<QCborArray>(d)->toJsonArray();
1151 break;
1152 default:
1153 return false;
1154 }
1155 break;
1156 case QMetaType::QJsonObject:
1157 switch (d->type) {
1158 case QVariant::Map:
1159 *static_cast<QJsonObject *>(result) = QJsonObject::fromVariantMap(*v_cast<QVariantMap>(d));
1160 break;
1161 case QVariant::Hash:
1162 *static_cast<QJsonObject *>(result) = QJsonObject::fromVariantHash(*v_cast<QVariantHash>(d));
1163 break;
1164 case QMetaType::QJsonValue:
1165 if (!v_cast<QJsonValue>(d)->isObject())
1166 return false;
1167 *static_cast<QJsonObject *>(result) = v_cast<QJsonValue>(d)->toObject();
1168 break;
1169 case QMetaType::QJsonDocument:
1170 if (v_cast<QJsonDocument>(d)->isArray())
1171 return false;
1172 *static_cast<QJsonObject *>(result) = v_cast<QJsonDocument>(d)->object();
1173 break;
1174 case QMetaType::QCborValue:
1175 if (!v_cast<QCborValue>(d)->isMap())
1176 return false;
1177 *static_cast<QJsonObject *>(result) = v_cast<QCborValue>(d)->toMap().toJsonObject();
1178 break;
1179 case QMetaType::QCborMap:
1180 *static_cast<QJsonObject *>(result) = v_cast<QCborMap>(d)->toJsonObject();
1181 break;
1182 default:
1183 return false;
1184 }
1185 break;
1186 case QMetaType::QCborSimpleType:
1187 if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isSimpleType()) {
1188 *static_cast<QCborSimpleType *>(result) = v_cast<QCborValue>(d)->toSimpleType();
1189 break;
1190 }
1191 return false;
1192 case QMetaType::QCborValue:
1193 switch (d->type) {
1194 case QMetaType::Nullptr:
1195 *static_cast<QCborValue *>(result) = QCborValue(QCborValue::Null);
1196 break;
1197 case QVariant::Bool:
1198 *static_cast<QCborValue *>(result) = QCborValue(d->data.b);
1199 break;
1200 case QMetaType::Int:
1201 case QMetaType::UInt:
1202 case QMetaType::ULong:
1203 case QMetaType::Long:
1204 case QMetaType::LongLong:
1205 case QMetaType::ULongLong:
1206 case QMetaType::UShort:
1207 case QMetaType::UChar:
1208 case QMetaType::Char:
1209 case QMetaType::SChar:
1210 case QMetaType::Short:
1211 *static_cast<QCborValue *>(result) = QCborValue(qConvertToNumber(d, ok));
1212 Q_ASSERT(ok);
1213 break;
1214 case QMetaType::Double:
1215 case QMetaType::Float:
1216 *static_cast<QCborValue *>(result) = QCborValue(qConvertToRealNumber(d, ok));
1217 Q_ASSERT(ok);
1218 break;
1219 case QVariant::String:
1220 *static_cast<QCborValue *>(result) = *v_cast<QString>(d);
1221 break;
1222 case QVariant::StringList:
1223 *static_cast<QCborValue *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
1224 break;
1225 case QVariant::ByteArray:
1226 *static_cast<QCborValue *>(result) = *v_cast<QByteArray>(d);
1227 break;
1228 case QVariant::Date:
1229 *static_cast<QCborValue *>(result) = QCborValue(QDateTime(*v_cast<QDate>(d)));
1230 break;
1231 case QVariant::DateTime:
1232 *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QDateTime>(d));
1233 break;
1234 case QVariant::Url:
1235 *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUrl>(d));
1236 break;
1237#if QT_CONFIG(regularexpression)
1238 case QVariant::RegularExpression:
1239 *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QRegularExpression>(d));
1240 break;
1241#endif
1242 case QVariant::Uuid:
1243 *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUuid>(d));
1244 break;
1245 case QVariant::List:
1246 *static_cast<QCborValue *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
1247 break;
1248 case QVariant::Map:
1249 *static_cast<QCborValue *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
1250 break;
1251 case QVariant::Hash:
1252 *static_cast<QCborValue *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
1253 break;
1254 case QMetaType::QJsonValue:
1255 *static_cast<QCborValue *>(result) = QCborValue::fromJsonValue(*v_cast<QJsonValue>(d));
1256 break;
1257 case QMetaType::QJsonObject:
1258 *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
1259 break;
1260 case QMetaType::QJsonArray:
1261 *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
1262 break;
1263 case QMetaType::QJsonDocument: {
1264 QJsonDocument doc = *v_cast<QJsonDocument>(d);
1265 if (doc.isArray())
1266 *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(doc.array());
1267 else
1268 *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(doc.object());
1269 break;
1270 }
1271 case QMetaType::QCborSimpleType:
1272 *static_cast<QCborValue *>(result) = *v_cast<QCborSimpleType>(d);
1273 break;
1274 case QMetaType::QCborMap:
1275 *static_cast<QCborValue *>(result) = *v_cast<QCborMap>(d);
1276 break;
1277 case QMetaType::QCborArray:
1278 *static_cast<QCborValue *>(result) = *v_cast<QCborArray>(d);
1279 break;
1280 default:
1281 *static_cast<QCborValue *>(result) = {};
1282 return false;
1283 }
1284 break;
1285 case QMetaType::QCborArray:
1286 switch (d->type) {
1287 case QVariant::StringList:
1288 *static_cast<QCborArray *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
1289 break;
1290 case QVariant::List:
1291 *static_cast<QCborArray *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
1292 break;
1293 case QMetaType::QCborValue:
1294 if (!v_cast<QCborValue>(d)->isArray())
1295 return false;
1296 *static_cast<QCborArray *>(result) = v_cast<QCborValue>(d)->toArray();
1297 break;
1298 case QMetaType::QJsonDocument:
1299 if (!v_cast<QJsonDocument>(d)->isArray())
1300 return false;
1301 *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonDocument>(d)->array());
1302 break;
1303 case QMetaType::QJsonValue:
1304 if (!v_cast<QJsonValue>(d)->isArray())
1305 return false;
1306 *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonValue>(d)->toArray());
1307 break;
1308 case QMetaType::QJsonArray:
1309 *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
1310 break;
1311 default:
1312 return false;
1313 }
1314 break;
1315 case QMetaType::QCborMap:
1316 switch (d->type) {
1317 case QVariant::Map:
1318 *static_cast<QCborMap *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
1319 break;
1320 case QVariant::Hash:
1321 *static_cast<QCborMap *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
1322 break;
1323 case QMetaType::QCborValue:
1324 if (!v_cast<QCborValue>(d)->isMap())
1325 return false;
1326 *static_cast<QCborMap *>(result) = v_cast<QCborValue>(d)->toMap();
1327 break;
1328 case QMetaType::QJsonDocument:
1329 if (v_cast<QJsonDocument>(d)->isArray())
1330 return false;
1331 *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonDocument>(d)->object());
1332 break;
1333 case QMetaType::QJsonValue:
1334 if (!v_cast<QJsonValue>(d)->isObject())
1335 return false;
1336 *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonValue>(d)->toObject());
1337 break;
1338 case QMetaType::QJsonObject:
1339 *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
1340 break;
1341 default:
1342 return false;
1343 }
1344 break;
1345#endif
1346
1347 default:
1348#ifndef QT_NO_QOBJECT
1349 if (d->type == QVariant::String || d->type == QVariant::ByteArray) {
1350 QMetaEnum en = metaEnumFromType(t);
1351 if (en.isValid()) {
1352 QByteArray keys = (d->type == QVariant::String) ? v_cast<QString>(d)->toUtf8() : *v_cast<QByteArray>(d);
1353 int value = en.keysToValue(keys.constData(), ok);
1354 if (*ok) {
1355 switch (QMetaType::sizeOf(t)) {
1356 case 1:
1357 *static_cast<signed char *>(result) = value;
1358 return true;
1359 case 2:
1360 *static_cast<qint16 *>(result) = value;
1361 return true;
1362 case 4:
1363 *static_cast<qint32 *>(result) = value;
1364 return true;
1365 case 8:
1366 *static_cast<qint64 *>(result) = value;
1367 return true;
1368 }
1369 }
1370 }
1371 }
1372#endif
1373 if (QMetaType::typeFlags(t) & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
1374 qlonglong value = qConvertToNumber(d, ok);
1375 if (*ok) {
1376 switch (QMetaType::sizeOf(t)) {
1377 case 1:
1378 *static_cast<signed char *>(result) = value;
1379 return true;
1380 case 2:
1381 *static_cast<qint16 *>(result) = value;
1382 return true;
1383 case 4:
1384 *static_cast<qint32 *>(result) = value;
1385 return true;
1386 case 8:
1387 *static_cast<qint64 *>(result) = value;
1388 return true;
1389 }
1390 }
1391 return *ok;
1392 }
1393 return false;
1394 }
1395 return true;
1396}
1397
1398#if !defined(QT_NO_DEBUG_STREAM)
1399static void streamDebug(QDebug dbg, const QVariant &v)
1400{
1401 QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
1402 QVariantDebugStream<CoreTypesFilter> stream(dbg, d);
1403 QMetaTypeSwitcher::switcher<void>(stream, d->type, 0);
1404}
1405#endif
1406
1407const QVariant::Handler qt_kernel_variant_handler = {
1408 construct,
1409 clear,
1410 isNull,
1411#ifndef QT_NO_DATASTREAM
1412 0,
1413 0,
1414#endif
1415 compare,
1416 convert,
1417 0,
1418#if !defined(QT_NO_DEBUG_STREAM)
1419 streamDebug
1420#else
1421 0
1422#endif
1423};
1424
1425static void dummyConstruct(QVariant::Private *, const void *) { Q_ASSERT_X(false, "QVariant", "Trying to construct an unknown type"); }
1426static void dummyClear(QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to clear an unknown type"); }
1427static bool dummyIsNull(const QVariant::Private *d) { Q_ASSERT_X(false, "QVariant::isNull", "Trying to call isNull on an unknown type"); return d->is_null; }
1428static bool dummyCompare(const QVariant::Private *, const QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to compare an unknown types"); return false; }
1429static bool dummyConvert(const QVariant::Private *, int, void *, bool *) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); return false; }
1430#if !defined(QT_NO_DEBUG_STREAM)
1431static void dummyStreamDebug(QDebug, const QVariant &) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); }
1432#endif
1433const QVariant::Handler qt_dummy_variant_handler = {
1434 dummyConstruct,
1435 dummyClear,
1436 dummyIsNull,
1437#ifndef QT_NO_DATASTREAM
1438 0,
1439 0,
1440#endif
1441 dummyCompare,
1442 dummyConvert,
1443 0,
1444#if !defined(QT_NO_DEBUG_STREAM)
1445 dummyStreamDebug
1446#else
1447 0
1448#endif
1449};
1450
1451static void customConstruct(QVariant::Private *d, const void *copy)
1452{
1453 const QMetaType type(d->type);
1454 const uint size = type.sizeOf();
1455 if (!size) {
1456 qWarning("Trying to construct an instance of an invalid type, type id: %i", d->type);
1457 d->type = QVariant::Invalid;
1458 return;
1459 }
1460
1461 // this logic should match with QVariantIntegrator::CanUseInternalSpace
1462 if (size <= sizeof(QVariant::Private::Data)
1463 && (type.flags() & (QMetaType::MovableType | QMetaType::IsEnumeration))) {
1464 type.construct(&d->data.ptr, copy);
1465 d->is_null = d->data.ptr == nullptr;
1466 d->is_shared = false;
1467 } else {
1468 // Private::Data contains long long, and long double is the biggest standard type.
1469 const size_t maxAlignment =
1470 qMax(Q_ALIGNOF(QVariant::Private::Data), Q_ALIGNOF(long double));
1471 const size_t s = sizeof(QVariant::PrivateShared);
1472 const size_t offset = s + ((s * maxAlignment - s) % maxAlignment);
1473 void *data = operator new(offset + size);
1474 void *ptr = static_cast<char *>(data) + offset;
1475 type.construct(ptr, copy);
1476 d->is_null = ptr == nullptr;
1477 d->is_shared = true;
1478 d->data.shared = new (data) QVariant::PrivateShared(ptr);
1479 }
1480}
1481
1482static void customClear(QVariant::Private *d)
1483{
1484 if (!d->is_shared) {
1485 QMetaType::destruct(d->type, &d->data.ptr);
1486 } else {
1487 QMetaType::destruct(d->type, d->data.shared->ptr);
1488 d->data.shared->~PrivateShared();
1489 operator delete(d->data.shared);
1490 }
1491}
1492
1493static bool customIsNull(const QVariant::Private *d)
1494{
1495 if (d->is_null)
1496 return true;
1497 const char *const typeName = QMetaType::typeName(d->type);
1498 if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(d->type)))
1499 qFatal("QVariant::isNull: type %d unknown to QVariant.", d->type);
1500 uint typeNameLen = qstrlen(typeName);
1501 if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*') {
1502 const void *d_ptr = d->is_shared ? d->data.shared->ptr : &(d->data.ptr);
1503 return *static_cast<void *const *>(d_ptr) == nullptr;
1504 }
1505 return false;
1506}
1507
1508static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
1509{
1510 const char *const typeName = QMetaType::typeName(a->type);
1511 if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(a->type)))
1512 qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
1513
1514 const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data.ptr);
1515 const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data.ptr);
1516
1517 uint typeNameLen = qstrlen(typeName);
1518 if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*')
1519 return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
1520
1521 if (a->is_null && b->is_null)
1522 return true;
1523
1524 return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
1525}
1526
1527static bool customConvert(const QVariant::Private *d, int t, void *result, bool *ok)
1528{
1529 if (d->type >= QMetaType::User || t >= QMetaType::User) {
1530 if (QMetaType::convert(constData(*d), d->type, result, t)) {
1531 if (ok)
1532 *ok = true;
1533 return true;
1534 }
1535 }
1536 return convert(d, t, result, ok);
1537}
1538
1539#if !defined(QT_NO_DEBUG_STREAM)
1540static void customStreamDebug(QDebug dbg, const QVariant &variant) {
1541#ifndef QT_BOOTSTRAPPED
1542 QMetaType::TypeFlags flags = QMetaType::typeFlags(variant.userType());
1543 if (flags & QMetaType::PointerToQObject)
1544 dbg.nospace() << variant.value<QObject*>();
1545#else
1546 Q_UNUSED(dbg);
1547 Q_UNUSED(variant);
1548#endif
1549}
1550#endif
1551
1552const QVariant::Handler qt_custom_variant_handler = {
1553 customConstruct,
1554 customClear,
1555 customIsNull,
1556#ifndef QT_NO_DATASTREAM
1557 0,
1558 0,
1559#endif
1560 customCompare,
1561 customConvert,
1562 0,
1563#if !defined(QT_NO_DEBUG_STREAM)
1564 customStreamDebug
1565#else
1566 0
1567#endif
1568};
1569
1570} // annonymous used to hide QVariant handlers
1571
1572static HandlersManager handlerManager;
1573Q_STATIC_ASSERT_X(!QModulesPrivate::Core, "Initialization assumes that ModulesNames::Core is 0");
1574const QVariant::Handler *HandlersManager::Handlers[QModulesPrivate::ModulesCount]
1575 = { &qt_kernel_variant_handler, &qt_dummy_variant_handler,
1576 &qt_dummy_variant_handler, &qt_custom_variant_handler };
1577
1578Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler()
1579{
1580 return &qt_kernel_variant_handler;
1581}
1582
1583Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names */name, const QVariant::Handler *handler)
1584{
1585 handlerManager.registerHandler(static_cast<QModulesPrivate::Names>(name), handler);
1586}
1587
1588/*!
1589 \class QVariant
1590 \inmodule QtCore
1591 \brief The QVariant class acts like a union for the most common Qt data types.
1592
1593 \ingroup objectmodel
1594 \ingroup shared
1595
1596
1597 Because C++ forbids unions from including types that have
1598 non-default constructors or destructors, most interesting Qt
1599 classes cannot be used in unions. Without QVariant, this would be
1600 a problem for QObject::property() and for database work, etc.
1601
1602 A QVariant object holds a single value of a single type() at a
1603 time. (Some type()s are multi-valued, for example a string list.)
1604 You can find out what type, T, the variant holds, convert it to a
1605 different type using convert(), get its value using one of the
1606 toT() functions (e.g., toSize()) and check whether the type can
1607 be converted to a particular type using canConvert().
1608
1609 The methods named toT() (e.g., toInt(), toString()) are const. If
1610 you ask for the stored type, they return a copy of the stored
1611 object. If you ask for a type that can be generated from the
1612 stored type, toT() copies and converts and leaves the object
1613 itself unchanged. If you ask for a type that cannot be generated
1614 from the stored type, the result depends on the type; see the
1615 function documentation for details.
1616
1617 Here is some example code to demonstrate the use of QVariant:
1618
1619 \snippet code/src_corelib_kernel_qvariant.cpp 0
1620
1621 You can even store QList<QVariant> and QMap<QString, QVariant>
1622 values in a variant, so you can easily construct arbitrarily
1623 complex data structures of arbitrary types. This is very powerful
1624 and versatile, but may prove less memory and speed efficient than
1625 storing specific types in standard data structures.
1626
1627 QVariant also supports the notion of null values, where you can
1628 have a defined type with no value set. However, note that QVariant
1629 types can only be cast when they have had a value set.
1630
1631 \snippet code/src_corelib_kernel_qvariant.cpp 1
1632
1633 QVariant can be extended to support other types than those
1634 mentioned in the \l Type enum. See \l{Creating Custom Qt Types}{Creating Custom Qt Types}
1635 for details.
1636
1637 \section1 A Note on GUI Types
1638
1639 Because QVariant is part of the Qt Core module, it cannot provide
1640 conversion functions to data types defined in Qt GUI, such as
1641 QColor, QImage, and QPixmap. In other words, there is no \c
1642 toColor() function. Instead, you can use the QVariant::value() or
1643 the qvariant_cast() template function. For example:
1644
1645 \snippet code/src_corelib_kernel_qvariant.cpp 2
1646
1647 The inverse conversion (e.g., from QColor to QVariant) is
1648 automatic for all data types supported by QVariant, including
1649 GUI-related types:
1650
1651 \snippet code/src_corelib_kernel_qvariant.cpp 3
1652
1653 \section1 Using canConvert() and convert() Consecutively
1654
1655 When using canConvert() and convert() consecutively, it is possible for
1656 canConvert() to return true, but convert() to return false. This
1657 is typically because canConvert() only reports the general ability of
1658 QVariant to convert between types given suitable data; it is still
1659 possible to supply data which cannot actually be converted.
1660
1661 For example, canConvert(Int) would return true when called on a variant
1662 containing a string because, in principle, QVariant is able to convert
1663 strings of numbers to integers.
1664 However, if the string contains non-numeric characters, it cannot be
1665 converted to an integer, and any attempt to convert it will fail.
1666 Hence, it is important to have both functions return true for a
1667 successful conversion.
1668
1669 \sa QMetaType
1670*/
1671
1672/*!
1673 \obsolete Use QMetaType::Type instead
1674 \enum QVariant::Type
1675
1676 This enum type defines the types of variable that a QVariant can
1677 contain.
1678
1679 \value Invalid no type
1680 \value BitArray a QBitArray
1681 \value Bitmap a QBitmap
1682 \value Bool a bool
1683 \value Brush a QBrush
1684 \value ByteArray a QByteArray
1685 \value Char a QChar
1686 \value Color a QColor
1687 \value Cursor a QCursor
1688 \value Date a QDate
1689 \value DateTime a QDateTime
1690 \value Double a double
1691 \value EasingCurve a QEasingCurve
1692 \value Uuid a QUuid
1693 \value ModelIndex a QModelIndex
1694 \value PersistentModelIndex a QPersistentModelIndex (since 5.5)
1695 \value Font a QFont
1696 \value Hash a QVariantHash
1697 \value Icon a QIcon
1698 \value Image a QImage
1699 \value Int an int
1700 \value KeySequence a QKeySequence
1701 \value Line a QLine
1702 \value LineF a QLineF
1703 \value List a QVariantList
1704 \value Locale a QLocale
1705 \value LongLong a \l qlonglong
1706 \value Map a QVariantMap
1707 \value Matrix a QMatrix
1708 \value Transform a QTransform
1709 \value Matrix4x4 a QMatrix4x4
1710 \value Palette a QPalette
1711 \value Pen a QPen
1712 \value Pixmap a QPixmap
1713 \value Point a QPoint
1714 \value PointF a QPointF
1715 \value Polygon a QPolygon
1716 \value PolygonF a QPolygonF
1717 \value Quaternion a QQuaternion
1718 \value Rect a QRect
1719 \value RectF a QRectF
1720 \value RegExp a QRegExp
1721 \value RegularExpression a QRegularExpression
1722 \value Region a QRegion
1723 \value Size a QSize
1724 \value SizeF a QSizeF
1725 \value SizePolicy a QSizePolicy
1726 \value String a QString
1727 \value StringList a QStringList
1728 \value TextFormat a QTextFormat
1729 \value TextLength a QTextLength
1730 \value Time a QTime
1731 \value UInt a \l uint
1732 \value ULongLong a \l qulonglong
1733 \value Url a QUrl
1734 \value Vector2D a QVector2D
1735 \value Vector3D a QVector3D
1736 \value Vector4D a QVector4D
1737
1738 \value UserType Base value for user-defined types.
1739
1740 \omitvalue LastGuiType
1741 \omitvalue LastCoreType
1742 \omitvalue LastType
1743*/
1744
1745/*!
1746 \fn QVariant::QVariant(QVariant &&other)
1747
1748 Move-constructs a QVariant instance, making it point at the same
1749 object that \a other was pointing to.
1750
1751 \since 5.2
1752*/
1753
1754/*!
1755 \fn QVariant &QVariant::operator=(QVariant &&other)
1756
1757 Move-assigns \a other to this QVariant instance.
1758
1759 \since 5.2
1760*/
1761
1762/*!
1763 \fn QVariant::QVariant()
1764
1765 Constructs an invalid variant.
1766*/
1767
1768
1769/*!
1770 \fn QVariant::QVariant(int typeId, const void *copy)
1771
1772 Constructs variant of type \a typeId, and initializes with
1773 \a copy if \a copy is not \nullptr.
1774
1775 Note that you have to pass the address of the variable you want stored.
1776
1777 Usually, you never have to use this constructor, use QVariant::fromValue()
1778 instead to construct variants from the pointer types represented by
1779 \c QMetaType::VoidStar, and \c QMetaType::QObjectStar.
1780
1781 \sa QVariant::fromValue(), QMetaType::Type
1782*/
1783
1784/*!
1785 \fn QVariant::QVariant(Type type)
1786
1787 Constructs an uninitialized variant of type \a type. This will create a
1788 variant in a special null state that if accessed will return a default
1789 constructed value of the \a type.
1790
1791 \sa isNull()
1792*/
1793
1794
1795
1796/*!
1797 \fn QVariant::create(int type, const void *copy)
1798
1799 \internal
1800
1801 Constructs a variant private of type \a type, and initializes with \a copy if
1802 \a copy is not \nullptr.
1803*/
1804
1805void QVariant::create(int type, const void *copy)
1806{
1807 d.type = type;
1808 handlerManager[type]->construct(&d, copy);
1809}
1810
1811/*!
1812 \fn QVariant::~QVariant()
1813
1814 Destroys the QVariant and the contained object.
1815
1816 Note that subclasses that reimplement clear() should reimplement
1817 the destructor to call clear(). This destructor calls clear(), but
1818 because it is the destructor, QVariant::clear() is called rather
1819 than a subclass's clear().
1820*/
1821
1822QVariant::~QVariant()
1823{
1824 if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
1825 handlerManager[d.type]->clear(&d);
1826}
1827
1828/*!
1829 \fn QVariant::QVariant(const QVariant &p)
1830
1831 Constructs a copy of the variant, \a p, passed as the argument to
1832 this constructor.
1833*/
1834
1835QVariant::QVariant(const QVariant &p)
1836 : d(p.d)
1837{
1838 if (d.is_shared) {
1839 d.data.shared->ref.ref();
1840 } else if (p.d.type > Char) {
1841 handlerManager[d.type]->construct(&d, p.constData());
1842 d.is_null = p.d.is_null;
1843 }
1844}
1845
1846#ifndef QT_NO_DATASTREAM
1847/*!
1848 Reads the variant from the data stream, \a s.
1849*/
1850QVariant::QVariant(QDataStream &s)
1851{
1852 d.is_null = true;
1853 s >> *this;
1854}
1855#endif //QT_NO_DATASTREAM
1856
1857/*!
1858 \fn QVariant::QVariant(const QString &val)
1859
1860 Constructs a new variant with a string value, \a val.
1861*/
1862
1863/*!
1864 \fn QVariant::QVariant(QLatin1String val)
1865
1866 Constructs a new variant with a string value, \a val.
1867*/
1868
1869/*!
1870 \fn QVariant::QVariant(const char *val)
1871
1872 Constructs a new variant with a string value of \a val.
1873 The variant creates a deep copy of \a val into a QString assuming
1874 UTF-8 encoding on the input \a val.
1875
1876 Note that \a val is converted to a QString for storing in the
1877 variant and QVariant::userType() will return QMetaType::QString for
1878 the variant.
1879
1880 You can disable this operator by defining \c
1881 QT_NO_CAST_FROM_ASCII when you compile your applications.
1882*/
1883
1884#ifndef QT_NO_CAST_FROM_ASCII
1885QVariant::QVariant(const char *val)
1886{
1887 QString s = QString::fromUtf8(val);
1888 create(String, &s);
1889}
1890#endif
1891
1892/*!
1893 \fn QVariant::QVariant(const QStringList &val)
1894
1895 Constructs a new variant with a string list value, \a val.
1896*/
1897
1898/*!
1899 \fn QVariant::QVariant(const QMap<QString, QVariant> &val)
1900
1901 Constructs a new variant with a map of \l {QVariant}s, \a val.
1902*/
1903
1904/*!
1905 \fn QVariant::QVariant(const QHash<QString, QVariant> &val)
1906
1907 Constructs a new variant with a hash of \l {QVariant}s, \a val.
1908*/
1909
1910/*!
1911 \fn QVariant::QVariant(const QDate &val)
1912
1913 Constructs a new variant with a date value, \a val.
1914*/
1915
1916/*!
1917 \fn QVariant::QVariant(const QTime &val)
1918
1919 Constructs a new variant with a time value, \a val.
1920*/
1921
1922/*!
1923 \fn QVariant::QVariant(const QDateTime &val)
1924
1925 Constructs a new variant with a date/time value, \a val.
1926*/
1927
1928/*!
1929 \since 4.7
1930 \fn QVariant::QVariant(const QEasingCurve &val)
1931
1932 Constructs a new variant with an easing curve value, \a val.
1933*/
1934
1935/*!
1936 \since 5.0
1937 \fn QVariant::QVariant(const QUuid &val)
1938
1939 Constructs a new variant with an uuid value, \a val.
1940*/
1941
1942/*!
1943 \since 5.0
1944 \fn QVariant::QVariant(const QModelIndex &val)
1945
1946 Constructs a new variant with a QModelIndex value, \a val.
1947*/
1948
1949/*!
1950 \since 5.5
1951 \fn QVariant::QVariant(const QPersistentModelIndex &val)
1952
1953 Constructs a new variant with a QPersistentModelIndex value, \a val.
1954*/
1955
1956/*!
1957 \since 5.0
1958 \fn QVariant::QVariant(const QJsonValue &val)
1959
1960 Constructs a new variant with a json value, \a val.
1961*/
1962
1963/*!
1964 \since 5.0
1965 \fn QVariant::QVariant(const QJsonObject &val)
1966
1967 Constructs a new variant with a json object value, \a val.
1968*/
1969
1970/*!
1971 \since 5.0
1972 \fn QVariant::QVariant(const QJsonArray &val)
1973
1974 Constructs a new variant with a json array value, \a val.
1975*/
1976
1977/*!
1978 \since 5.0
1979 \fn QVariant::QVariant(const QJsonDocument &val)
1980
1981 Constructs a new variant with a json document value, \a val.
1982*/
1983
1984/*!
1985 \fn QVariant::QVariant(const QByteArray &val)
1986
1987 Constructs a new variant with a bytearray value, \a val.
1988*/
1989
1990/*!
1991 \fn QVariant::QVariant(const QBitArray &val)
1992
1993 Constructs a new variant with a bitarray value, \a val.
1994*/
1995
1996/*!
1997 \fn QVariant::QVariant(const QPoint &val)
1998
1999 Constructs a new variant with a point value of \a val.
2000 */
2001
2002/*!
2003 \fn QVariant::QVariant(const QPointF &val)
2004
2005 Constructs a new variant with a point value of \a val.
2006 */
2007
2008/*!
2009 \fn QVariant::QVariant(const QRectF &val)
2010
2011 Constructs a new variant with a rect value of \a val.
2012 */
2013
2014/*!
2015 \fn QVariant::QVariant(const QLineF &val)
2016
2017 Constructs a new variant with a line value of \a val.
2018 */
2019
2020/*!
2021 \fn QVariant::QVariant(const QLine &val)
2022
2023 Constructs a new variant with a line value of \a val.
2024 */
2025
2026/*!
2027 \fn QVariant::QVariant(const QRect &val)
2028
2029 Constructs a new variant with a rect value of \a val.
2030 */
2031
2032/*!
2033 \fn QVariant::QVariant(const QSize &val)
2034
2035 Constructs a new variant with a size value of \a val.
2036 */
2037
2038/*!
2039 \fn QVariant::QVariant(const QSizeF &val)
2040
2041 Constructs a new variant with a size value of \a val.
2042 */
2043
2044/*!
2045 \fn QVariant::QVariant(const QUrl &val)
2046
2047 Constructs a new variant with a url value of \a val.
2048 */
2049
2050/*!
2051 \fn QVariant::QVariant(int val)
2052
2053 Constructs a new variant with an integer value, \a val.
2054*/
2055
2056/*!
2057 \fn QVariant::QVariant(uint val)
2058
2059 Constructs a new variant with an unsigned integer value, \a val.
2060*/
2061
2062/*!
2063 \fn QVariant::QVariant(qlonglong val)
2064
2065 Constructs a new variant with a long long integer value, \a val.
2066*/
2067
2068/*!
2069 \fn QVariant::QVariant(qulonglong val)
2070
2071 Constructs a new variant with an unsigned long long integer value, \a val.
2072*/
2073
2074
2075/*!
2076 \fn QVariant::QVariant(bool val)
2077
2078 Constructs a new variant with a boolean value, \a val.
2079*/
2080
2081/*!
2082 \fn QVariant::QVariant(double val)
2083
2084 Constructs a new variant with a floating point value, \a val.
2085*/
2086
2087/*!
2088 \fn QVariant::QVariant(float val)
2089
2090 Constructs a new variant with a floating point value, \a val.
2091 \since 4.6
2092*/
2093
2094/*!
2095 \fn QVariant::QVariant(const QList<QVariant> &val)
2096
2097 Constructs a new variant with a list value, \a val.
2098*/
2099
2100/*!
2101 \fn QVariant::QVariant(QChar c)
2102
2103 Constructs a new variant with a char value, \a c.
2104*/
2105
2106/*!
2107 \fn QVariant::QVariant(const QLocale &l)
2108
2109 Constructs a new variant with a locale value, \a l.
2110*/
2111
2112/*!
2113 \fn QVariant::QVariant(const QRegExp &regExp)
2114
2115 Constructs a new variant with the regexp value \a regExp.
2116*/
2117
2118/*!
2119 \fn QVariant::QVariant(const QRegularExpression &re)
2120
2121 \since 5.0
2122
2123 Constructs a new variant with the regular expression value \a re.
2124*/
2125
2126QVariant::QVariant(Type type)
2127{ create(type, 0); }
2128QVariant::QVariant(int typeId, const void *copy)
2129{ create(typeId, copy); d.is_null = false; }
2130
2131/*!
2132 \internal
2133 flags is true if it is a pointer type
2134 */
2135QVariant::QVariant(int typeId, const void *copy, uint flags)
2136{
2137 if (flags) { //type is a pointer type
2138 d.type = typeId;
2139 d.data.ptr = *reinterpret_cast<void *const*>(copy);
2140 } else {
2141 create(typeId, copy);
2142 }
2143 d.is_null = false;
2144}
2145
2146QVariant::QVariant(int val)
2147 : d(Int)
2148{ d.data.i = val; }
2149QVariant::QVariant(uint val)
2150 : d(UInt)
2151{ d.data.u = val; }
2152QVariant::QVariant(qlonglong val)
2153 : d(LongLong)
2154{ d.data.ll = val; }
2155QVariant::QVariant(qulonglong val)
2156 : d(ULongLong)
2157{ d.data.ull = val; }
2158QVariant::QVariant(bool val)
2159 : d(Bool)
2160{ d.data.b = val; }
2161QVariant::QVariant(double val)
2162 : d(Double)
2163{ d.data.d = val; }
2164QVariant::QVariant(float val)
2165 : d(QMetaType::Float)
2166{ d.data.f = val; }
2167
2168QVariant::QVariant(const QByteArray &val)
2169 : d(ByteArray)
2170{ v_construct<QByteArray>(&d, val); }
2171QVariant::QVariant(const QBitArray &val)
2172 : d(BitArray)
2173{ v_construct<QBitArray>(&d, val); }
2174QVariant::QVariant(const QString &val)
2175 : d(String)
2176{ v_construct<QString>(&d, val); }
2177QVariant::QVariant(QChar val)
2178 : d(Char)
2179{ v_construct<QChar>(&d, val); }
2180QVariant::QVariant(QLatin1String val)
2181 : d(String)
2182{ v_construct<QString>(&d, val); }
2183QVariant::QVariant(const QStringList &val)
2184 : d(StringList)
2185{ v_construct<QStringList>(&d, val); }
2186
2187QVariant::QVariant(const QDate &val)
2188 : d(Date)
2189{ v_construct<QDate>(&d, val); }
2190QVariant::QVariant(const QTime &val)
2191 : d(Time)
2192{ v_construct<QTime>(&d, val); }
2193QVariant::QVariant(const QDateTime &val)
2194 : d(DateTime)
2195{ v_construct<QDateTime>(&d, val); }
2196#ifndef QT_BOOTSTRAPPED
2197QVariant::QVariant(const QEasingCurve &val)
2198 : d(EasingCurve)
2199{ v_construct<QEasingCurve>(&d, val); }
2200#endif
2201QVariant::QVariant(const QList<QVariant> &list)
2202 : d(List)
2203{ v_construct<QVariantList>(&d, list); }
2204QVariant::QVariant(const QMap<QString, QVariant> &map)
2205 : d(Map)
2206{ v_construct<QVariantMap>(&d, map); }
2207QVariant::QVariant(const QHash<QString, QVariant> &hash)
2208 : d(Hash)
2209{ v_construct<QVariantHash>(&d, hash); }
2210#ifndef QT_NO_GEOM_VARIANT
2211QVariant::QVariant(const QPoint &pt)
2212 : d(Point)
2213{ v_construct<QPoint>(&d, pt); }
2214QVariant::QVariant(const QPointF &pt)
2215 : d(PointF)
2216{ v_construct<QPointF>(&d, pt); }
2217QVariant::QVariant(const QRectF &r)
2218 : d(RectF)
2219{ v_construct<QRectF>(&d, r); }
2220QVariant::QVariant(const QLineF &l)
2221 : d(LineF)
2222{ v_construct<QLineF>(&d, l); }
2223QVariant::QVariant(const QLine &l)
2224 : d(Line)
2225{ v_construct<QLine>(&d, l); }
2226QVariant::QVariant(const QRect &r)
2227 : d(Rect)
2228{ v_construct<QRect>(&d, r); }
2229QVariant::QVariant(const QSize &s)
2230 : d(Size)
2231{ v_construct<QSize>(&d, s); }
2232QVariant::QVariant(const QSizeF &s)
2233 : d(SizeF)
2234{ v_construct<QSizeF>(&d, s); }
2235#endif
2236#ifndef QT_BOOTSTRAPPED
2237QVariant::QVariant(const QUrl &u)
2238 : d(Url)
2239{ v_construct<QUrl>(&d, u); }
2240#endif
2241QVariant::QVariant(const QLocale &l)
2242 : d(Locale)
2243{ v_construct<QLocale>(&d, l); }
2244#ifndef QT_NO_REGEXP
2245QVariant::QVariant(const QRegExp &regExp)
2246 : d(RegExp)
2247{ v_construct<QRegExp>(&d, regExp); }
2248#endif // QT_NO_REGEXP
2249#if QT_CONFIG(regularexpression)
2250QVariant::QVariant(const QRegularExpression &re)
2251 : d(RegularExpression)
2252{ v_construct<QRegularExpression>(&d, re); }
2253#endif // QT_CONFIG(regularexpression)
2254#ifndef QT_BOOTSTRAPPED
2255QVariant::QVariant(const QUuid &uuid)
2256 : d(Uuid)
2257{ v_construct<QUuid>(&d, uuid); }
2258QVariant::QVariant(const QJsonValue &jsonValue)
2259 : d(QMetaType::QJsonValue)
2260{ v_construct<QJsonValue>(&d, jsonValue); }
2261QVariant::QVariant(const QJsonObject &jsonObject)
2262 : d(QMetaType::QJsonObject)
2263{ v_construct<QJsonObject>(&d, jsonObject); }
2264QVariant::QVariant(const QJsonArray &jsonArray)
2265 : d(QMetaType::QJsonArray)
2266{ v_construct<QJsonArray>(&d, jsonArray); }
2267QVariant::QVariant(const QJsonDocument &jsonDocument)
2268 : d(QMetaType::QJsonDocument)
2269{ v_construct<QJsonDocument>(&d, jsonDocument); }
2270#endif // QT_BOOTSTRAPPED
2271#if QT_CONFIG(itemmodel)
2272QVariant::QVariant(const QModelIndex &modelIndex)
2273 : d(ModelIndex)
2274{ v_construct<QModelIndex>(&d, modelIndex); }
2275QVariant::QVariant(const QPersistentModelIndex &modelIndex)
2276 : d(PersistentModelIndex)
2277{ v_construct<QPersistentModelIndex>(&d, modelIndex); }
2278#endif
2279
2280/*!
2281 Returns the storage type of the value stored in the variant.
2282 Although this function is declared as returning QVariant::Type,
2283 the return value should be interpreted as QMetaType::Type. In
2284 particular, QVariant::UserType is returned here only if the value
2285 is equal or greater than QMetaType::User.
2286
2287 Note that return values in the ranges QVariant::Char through
2288 QVariant::RegExp and QVariant::Font through QVariant::Transform
2289 correspond to the values in the ranges QMetaType::QChar through
2290 QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion.
2291
2292 Pay particular attention when working with char and QChar
2293 variants. Note that there is no QVariant constructor specifically
2294 for type char, but there is one for QChar. For a variant of type
2295 QChar, this function returns QVariant::Char, which is the same as
2296 QMetaType::QChar, but for a variant of type \c char, this function
2297 returns QMetaType::Char, which is \e not the same as
2298 QVariant::Char.
2299
2300 Also note that the types \c void*, \c long, \c short, \c unsigned
2301 \c long, \c unsigned \c short, \c unsigned \c char, \c float, \c
2302 QObject*, and \c QWidget* are represented in QMetaType::Type but
2303 not in QVariant::Type, and they can be returned by this function.
2304 However, they are considered to be user defined types when tested
2305 against QVariant::Type.
2306
2307 To test whether an instance of QVariant contains a data type that
2308 is compatible with the data type you are interested in, use
2309 canConvert().
2310*/
2311
2312QVariant::Type QVariant::type() const
2313{
2314 return d.type >= QMetaType::User ? UserType : static_cast<Type>(d.type);
2315}
2316
2317/*!
2318 Returns the storage type of the value stored in the variant. For
2319 non-user types, this is the same as type().
2320
2321 \sa type()
2322*/
2323
2324int QVariant::userType() const
2325{
2326 return d.type;
2327}
2328
2329/*!
2330 Assigns the value of the variant \a variant to this variant.
2331*/
2332QVariant& QVariant::operator=(const QVariant &variant)
2333{
2334 if (this == &variant)
2335 return *this;
2336
2337 clear();
2338 if (variant.d.is_shared) {
2339 variant.d.data.shared->ref.ref();
2340 d = variant.d;
2341 } else if (variant.d.type > Char) {
2342 d.type = variant.d.type;
2343 handlerManager[d.type]->construct(&d, variant.constData());
2344 d.is_null = variant.d.is_null;
2345 } else {
2346 d = variant.d;
2347 }
2348
2349 return *this;
2350}
2351
2352/*!
2353 \fn void QVariant::swap(QVariant &other)
2354 \since 4.8
2355
2356 Swaps variant \a other with this variant. This operation is very
2357 fast and never fails.
2358*/
2359
2360/*!
2361 \fn void QVariant::detach()
2362
2363 \internal
2364*/
2365
2366void QVariant::detach()
2367{
2368 if (!d.is_shared || d.data.shared->ref.load() == 1)
2369 return;
2370
2371 Private dd;
2372 dd.type = d.type;
2373 handlerManager[d.type]->construct(&dd, constData());
2374 if (!d.data.shared->ref.deref())
2375 handlerManager[d.type]->clear(&d);
2376 d.data.shared = dd.data.shared;
2377}
2378
2379/*!
2380 \fn bool QVariant::isDetached() const
2381
2382 \internal
2383*/
2384
2385/*!
2386 Returns the name of the type stored in the variant. The returned
2387 strings describe the C++ datatype used to store the data: for
2388 example, "QFont", "QString", or "QVariantList". An Invalid
2389 variant returns 0.
2390*/
2391const char *QVariant::typeName() const
2392{
2393 return QMetaType::typeName(d.type);
2394}
2395
2396/*!
2397 Convert this variant to type QMetaType::UnknownType and free up any resources
2398 used.
2399*/
2400void QVariant::clear()
2401{
2402 if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
2403 handlerManager[d.type]->clear(&d);
2404 d.type = Invalid;
2405 d.is_null = true;
2406 d.is_shared = false;
2407}
2408
2409/*!
2410 Converts the int representation of the storage type, \a typeId, to
2411 its string representation.
2412
2413 Returns a null pointer if the type is QMetaType::UnknownType or doesn't exist.
2414*/
2415const char *QVariant::typeToName(int typeId)
2416{
2417 return QMetaType::typeName(typeId);
2418}
2419
2420
2421/*!
2422 Converts the string representation of the storage type given in \a
2423 name, to its enum representation.
2424
2425 If the string representation cannot be converted to any enum
2426 representation, the variant is set to \c Invalid.
2427*/
2428QVariant::Type QVariant::nameToType(const char *name)
2429{
2430 int metaType = QMetaType::type(name);
2431 return metaType <= int(UserType) ? QVariant::Type(metaType) : UserType;
2432}
2433
2434#ifndef QT_NO_DATASTREAM
2435enum { MapFromThreeCount = 36 };
2436static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] =
2437{
2438 QVariant::Invalid,
2439 QVariant::Map,
2440 QVariant::List,
2441 QVariant::String,
2442 QVariant::StringList,
2443 QVariant::Font,
2444 QVariant::Pixmap,
2445 QVariant::Brush,
2446 QVariant::Rect,
2447 QVariant::Size,
2448 QVariant::Color,
2449 QVariant::Palette,
2450 0, // ColorGroup
2451 QVariant::Icon,
2452 QVariant::Point,
2453 QVariant::Image,
2454 QVariant::Int,
2455 QVariant::UInt,
2456 QVariant::Bool,
2457 QVariant::Double,
2458 0, // Buggy ByteArray, QByteArray never had id == 20
2459 QVariant::Polygon,
2460 QVariant::Region,
2461 QVariant::Bitmap,
2462 QVariant::Cursor,
2463 QVariant::SizePolicy,
2464 QVariant::Date,
2465 QVariant::Time,
2466 QVariant::DateTime,
2467 QVariant::ByteArray,
2468 QVariant::BitArray,
2469 QVariant::KeySequence,
2470 QVariant::Pen,
2471 QVariant::LongLong,
2472 QVariant::ULongLong,
2473 QVariant::EasingCurve
2474};
2475
2476/*!
2477 Internal function for loading a variant from stream \a s. Use the
2478 stream operators instead.
2479
2480 \internal
2481*/
2482void QVariant::load(QDataStream &s)
2483{
2484 clear();
2485
2486 quint32 typeId;
2487 s >> typeId;
2488 if (s.version() < QDataStream::Qt_4_0) {
2489 if (typeId >= MapFromThreeCount)
2490 return;
2491 typeId = mapIdFromQt3ToCurrent[typeId];
2492 } else if (s.version() < QDataStream::Qt_5_0) {
2493 if (typeId == 127 /* QVariant::UserType */) {
2494 typeId = QMetaType::User;
2495 } else if (typeId >= 128 && typeId != QVariant::UserType) {
2496 // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
2497 // by moving all ids down by 97.
2498 typeId -= 97;
2499 } else if (typeId == 75 /* QSizePolicy */) {
2500 typeId = QMetaType::QSizePolicy;
2501 } else if (typeId > 75 && typeId <= 86) {
2502 // and as a result these types received lower ids too
2503 // QKeySequence QPen QTextLength QTextFormat QMatrix QTransform QMatrix4x4 QVector2D QVector3D QVector4D QQuaternion
2504 typeId -=1;
2505 }
2506 }
2507
2508 qint8 is_null = false;
2509 if (s.version() >= QDataStream::Qt_4_2)
2510 s >> is_null;
2511 if (typeId == QVariant::UserType) {
2512 QByteArray name;
2513 s >> name;
2514 typeId = QMetaType::type(name.constData());
2515 if (typeId == QMetaType::UnknownType) {
2516 s.setStatus(QDataStream::ReadCorruptData);
2517 qWarning("QVariant::load: unknown user type with name %s.", name.constData());
2518 return;
2519 }
2520 }
2521 create(typeId, 0);
2522 d.is_null = is_null;
2523
2524 if (!isValid()) {
2525 if (s.version() < QDataStream::Qt_5_0) {
2526 // Since we wrote something, we should read something
2527 QString x;
2528 s >> x;
2529 }
2530 d.is_null = true;
2531 return;
2532 }
2533
2534 // const cast is safe since we operate on a newly constructed variant
2535 if (!QMetaType::load(s, d.type, const_cast<void *>(constData()))) {
2536 s.setStatus(QDataStream::ReadCorruptData);
2537 qWarning("QVariant::load: unable to load type %d.", d.type);
2538 }
2539}
2540
2541/*!
2542 Internal function for saving a variant to the stream \a s. Use the
2543 stream operators instead.
2544
2545 \internal
2546*/
2547void QVariant::save(QDataStream &s) const
2548{
2549 quint32 typeId = type();
2550 bool fakeUserType = false;
2551 if (s.version() < QDataStream::Qt_4_0) {
2552 int i;
2553 for (i = 0; i <= MapFromThreeCount - 1; ++i) {
2554 if (mapIdFromQt3ToCurrent[i] == typeId) {
2555 typeId = i;
2556 break;
2557 }
2558 }
2559 if (i >= MapFromThreeCount) {
2560 s << QVariant();
2561 return;
2562 }
2563 } else if (s.version() < QDataStream::Qt_5_0) {
2564 if (typeId == QMetaType::User) {
2565 typeId = 127; // QVariant::UserType had this value in Qt4
2566 } else if (typeId >= 128 - 97 && typeId <= LastCoreType) {
2567 // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
2568 // by moving all ids down by 97.
2569 typeId += 97;
2570 } else if (typeId == QMetaType::QSizePolicy) {
2571 typeId = 75;
2572 } else if (typeId >= QMetaType::QKeySequence && typeId <= QMetaType::QQuaternion) {
2573 // and as a result these types received lower ids too
2574 typeId +=1;
2575 } else if (typeId == QMetaType::QPolygonF) {
2576 // This existed in Qt 4 only as a custom type
2577 typeId = 127;
2578 fakeUserType = true;
2579 }
2580 }
2581 s << typeId;
2582 if (s.version() >= QDataStream::Qt_4_2)
2583 s << qint8(d.is_null);
2584 if (d.type >= QVariant::UserType || fakeUserType) {
2585 s << QMetaType::typeName(userType());
2586 }
2587
2588 if (!isValid()) {
2589 if (s.version() < QDataStream::Qt_5_0)
2590 s << QString();
2591 return;
2592 }
2593
2594 if (!QMetaType::save(s, d.type, constData())) {
2595 qWarning("QVariant::save: unable to save type '%s' (type id: %d).\n", QMetaType::typeName(d.type), d.type);
2596 Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
2597 }
2598}
2599
2600/*!
2601 \since 4.4
2602
2603 Reads a variant \a p from the stream \a s.
2604
2605 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2606*/
2607QDataStream& operator>>(QDataStream &s, QVariant &p)
2608{
2609 p.load(s);
2610 return s;
2611}
2612
2613/*!
2614 Writes a variant \a p to the stream \a s.
2615
2616 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2617*/
2618QDataStream& operator<<(QDataStream &s, const QVariant &p)
2619{
2620 p.save(s);
2621 return s;
2622}
2623
2624/*!
2625 Reads a variant type \a p in enum representation from the stream \a s.
2626*/
2627QDataStream& operator>>(QDataStream &s, QVariant::Type &p)
2628{
2629 quint32 u;
2630 s >> u;
2631 p = (QVariant::Type)u;
2632
2633 return s;
2634}
2635
2636/*!
2637 Writes a variant type \a p to the stream \a s.
2638*/
2639QDataStream& operator<<(QDataStream &s, const QVariant::Type p)
2640{
2641 s << static_cast<quint32>(p);
2642
2643 return s;
2644}
2645
2646#endif //QT_NO_DATASTREAM
2647
2648/*!
2649 \fn bool QVariant::isValid() const
2650
2651 Returns \c true if the storage type of this variant is not
2652 QMetaType::UnknownType; otherwise returns \c false.
2653*/
2654
2655template <typename T>
2656inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &handlerManager)
2657{
2658 const uint targetType = qMetaTypeId<T>();
2659 if (d.type == targetType)
2660 return *v_cast<T>(&d);
2661
2662 T ret;
2663 if (d.type >= QMetaType::User || targetType >= QMetaType::User) {
2664 const void * const from = constData(d);
2665 if (QMetaType::convert(from, d.type, &ret, targetType))
2666 return ret;
2667 }
2668
2669 handlerManager[d.type]->convert(&d, targetType, &ret, 0);
2670 return ret;
2671}
2672
2673/*!
2674 \fn QStringList QVariant::toStringList() const
2675
2676 Returns the variant as a QStringList if the variant has userType()
2677 \l QMetaType::QStringList, \l QMetaType::QString, or
2678 \l QMetaType::QVariantList of a type that can be converted to QString;
2679 otherwise returns an empty list.
2680
2681 \sa canConvert(int targetTypeId), convert()
2682*/
2683QStringList QVariant::toStringList() const
2684{
2685 return qVariantToHelper<QStringList>(d, handlerManager);
2686}
2687
2688/*!
2689 Returns the variant as a QString if the variant has a userType()
2690 including, but not limited to:
2691
2692 \l QMetaType::QString, \l QMetaType::Bool, \l QMetaType::QByteArray,
2693 \l QMetaType::QChar, \l QMetaType::QDate, \l QMetaType::QDateTime,
2694 \l QMetaType::Double, \l QMetaType::Int, \l QMetaType::LongLong,
2695 \l QMetaType::QStringList, \l QMetaType::QTime, \l QMetaType::UInt, or
2696 \l QMetaType::ULongLong.
2697
2698 Calling QVariant::toString() on an unsupported variant returns an empty
2699 string.
2700
2701 \sa canConvert(int targetTypeId), convert()
2702*/
2703QString QVariant::toString() const
2704{
2705 return qVariantToHelper<QString>(d, handlerManager);
2706}
2707
2708/*!
2709 Returns the variant as a QMap<QString, QVariant> if the variant
2710 has type() \l QMetaType::QVariantMap; otherwise returns an empty map.
2711
2712 \sa canConvert(int targetTypeId), convert()
2713*/
2714QVariantMap QVariant::toMap() const
2715{
2716 return qVariantToHelper<QVariantMap>(d, handlerManager);
2717}
2718
2719/*!
2720 Returns the variant as a QHash<QString, QVariant> if the variant
2721 has type() \l QMetaType::QVariantHash; otherwise returns an empty map.
2722
2723 \sa canConvert(int targetTypeId), convert()
2724*/
2725QVariantHash QVariant::toHash() const
2726{
2727 return qVariantToHelper<QVariantHash>(d, handlerManager);
2728}
2729
2730/*!
2731 \fn QDate QVariant::toDate() const
2732
2733 Returns the variant as a QDate if the variant has userType()
2734 \l QMetaType::QDate, \l QMetaType::QDateTime, or \l QMetaType::QString;
2735 otherwise returns an invalid date.
2736
2737 If the type() is \l QMetaType::QString, an invalid date will be returned if
2738 the string cannot be parsed as a Qt::ISODate format date.
2739
2740 \sa canConvert(int targetTypeId), convert()
2741*/
2742QDate QVariant::toDate() const
2743{
2744 return qVariantToHelper<QDate>(d, handlerManager);
2745}
2746
2747/*!
2748 \fn QTime QVariant::toTime() const
2749
2750 Returns the variant as a QTime if the variant has userType()
2751 \l QMetaType::QTime, \l QMetaType::QDateTime, or \l QMetaType::QString;
2752 otherwise returns an invalid time.
2753
2754 If the type() is \l QMetaType::QString, an invalid time will be returned if
2755 the string cannot be parsed as a Qt::ISODate format time.
2756
2757 \sa canConvert(int targetTypeId), convert()
2758*/
2759QTime QVariant::toTime() const
2760{
2761 return qVariantToHelper<QTime>(d, handlerManager);
2762}
2763
2764/*!
2765 \fn QDateTime QVariant::toDateTime() const
2766
2767 Returns the variant as a QDateTime if the variant has userType()
2768 \l QMetaType::QDateTime, \l QMetaType::QDate, or \l QMetaType::QString;
2769 otherwise returns an invalid date/time.
2770
2771 If the type() is \l QMetaType::QString, an invalid date/time will be
2772 returned if the string cannot be parsed as a Qt::ISODate format date/time.
2773
2774 \sa canConvert(int targetTypeId), convert()
2775*/
2776QDateTime QVariant::toDateTime() const
2777{
2778 return qVariantToHelper<QDateTime>(d, handlerManager);
2779}
2780
2781/*!
2782 \since 4.7
2783 \fn QEasingCurve QVariant::toEasingCurve() const
2784
2785 Returns the variant as a QEasingCurve if the variant has userType()
2786 \l QMetaType::QEasingCurve; otherwise returns a default easing curve.
2787
2788 \sa canConvert(int targetTypeId), convert()
2789*/
2790#ifndef QT_BOOTSTRAPPED
2791QEasingCurve QVariant::toEasingCurve() const
2792{
2793 return qVariantToHelper<QEasingCurve>(d, handlerManager);
2794}
2795#endif
2796
2797/*!
2798 \fn QByteArray QVariant::toByteArray() const
2799
2800 Returns the variant as a QByteArray if the variant has userType()
2801 \l QMetaType::QByteArray or \l QMetaType::QString (converted using
2802 QString::fromUtf8()); otherwise returns an empty byte array.
2803
2804 \sa canConvert(int targetTypeId), convert()
2805*/
2806QByteArray QVariant::toByteArray() const
2807{
2808 return qVariantToHelper<QByteArray>(d, handlerManager);
2809}
2810
2811#ifndef QT_NO_GEOM_VARIANT
2812/*!
2813 \fn QPoint QVariant::toPoint() const
2814
2815 Returns the variant as a QPoint if the variant has userType()
2816 \l QMetaType::QPoint or \l QMetaType::QPointF; otherwise returns a null
2817 QPoint.
2818
2819 \sa canConvert(int targetTypeId), convert()
2820*/
2821QPoint QVariant::toPoint() const
2822{
2823 return qVariantToHelper<QPoint>(d, handlerManager);
2824}
2825
2826/*!
2827 \fn QRect QVariant::toRect() const
2828
2829 Returns the variant as a QRect if the variant has userType()
2830 \l QMetaType::QRect; otherwise returns an invalid QRect.
2831
2832 \sa canConvert(int targetTypeId), convert()
2833*/
2834QRect QVariant::toRect() const
2835{
2836 return qVariantToHelper<QRect>(d, handlerManager);
2837}
2838
2839/*!
2840 \fn QSize QVariant::toSize() const
2841
2842 Returns the variant as a QSize if the variant has userType()
2843 \l QMetaType::QSize; otherwise returns an invalid QSize.
2844
2845 \sa canConvert(int targetTypeId), convert()
2846*/
2847QSize QVariant::toSize() const
2848{
2849 return qVariantToHelper<QSize>(d, handlerManager);
2850}
2851
2852/*!
2853 \fn QSizeF QVariant::toSizeF() const
2854
2855 Returns the variant as a QSizeF if the variant has userType() \l
2856 QMetaType::QSizeF; otherwise returns an invalid QSizeF.
2857
2858 \sa canConvert(int targetTypeId), convert()
2859*/
2860QSizeF QVariant::toSizeF() const
2861{
2862 return qVariantToHelper<QSizeF>(d, handlerManager);
2863}
2864
2865/*!
2866 \fn QRectF QVariant::toRectF() const
2867
2868 Returns the variant as a QRectF if the variant has userType()
2869 \l QMetaType::QRect or \l QMetaType::QRectF; otherwise returns an invalid
2870 QRectF.
2871
2872 \sa canConvert(int targetTypeId), convert()
2873*/
2874QRectF QVariant::toRectF() const
2875{
2876 return qVariantToHelper<QRectF>(d, handlerManager);
2877}
2878
2879/*!
2880 \fn QLineF QVariant::toLineF() const
2881
2882 Returns the variant as a QLineF if the variant has userType()
2883 \l QMetaType::QLineF; otherwise returns an invalid QLineF.
2884
2885 \sa canConvert(int targetTypeId), convert()
2886*/
2887QLineF QVariant::toLineF() const
2888{
2889 return qVariantToHelper<QLineF>(d, handlerManager);
2890}
2891
2892/*!
2893 \fn QLine QVariant::toLine() const
2894
2895 Returns the variant as a QLine if the variant has userType()
2896 \l QMetaType::QLine; otherwise returns an invalid QLine.
2897
2898 \sa canConvert(int targetTypeId), convert()
2899*/
2900QLine QVariant::toLine() const
2901{
2902 return qVariantToHelper<QLine>(d, handlerManager);
2903}
2904
2905/*!
2906 \fn QPointF QVariant::toPointF() const
2907
2908 Returns the variant as a QPointF if the variant has userType() \l
2909 QMetaType::QPoint or \l QMetaType::QPointF; otherwise returns a null
2910 QPointF.
2911
2912 \sa canConvert(int targetTypeId), convert()
2913*/
2914QPointF QVariant::toPointF() const
2915{
2916 return qVariantToHelper<QPointF>(d, handlerManager);
2917}
2918
2919#endif // QT_NO_GEOM_VARIANT
2920
2921#ifndef QT_BOOTSTRAPPED
2922/*!
2923 \fn QUrl QVariant::toUrl() const
2924
2925 Returns the variant as a QUrl if the variant has userType()
2926 \l QMetaType::QUrl; otherwise returns an invalid QUrl.
2927
2928 \sa canConvert(int targetTypeId), convert()
2929*/
2930QUrl QVariant::toUrl() const
2931{
2932 return qVariantToHelper<QUrl>(d, handlerManager);
2933}
2934#endif
2935
2936/*!
2937 \fn QLocale QVariant::toLocale() const
2938
2939 Returns the variant as a QLocale if the variant has userType()
2940 \l QMetaType::QLocale; otherwise returns an invalid QLocale.
2941
2942 \sa canConvert(int targetTypeId), convert()
2943*/
2944QLocale QVariant::toLocale() const
2945{
2946 return qVariantToHelper<QLocale>(d, handlerManager);
2947}
2948
2949/*!
2950 \fn QRegExp QVariant::toRegExp() const
2951 \since 4.1
2952
2953 Returns the variant as a QRegExp if the variant has userType()
2954 \l QMetaType::QRegExp; otherwise returns an empty QRegExp.
2955
2956 \sa canConvert(int targetTypeId), convert()
2957*/
2958#ifndef QT_NO_REGEXP
2959QRegExp QVariant::toRegExp() const
2960{
2961 return qVariantToHelper<QRegExp>(d, handlerManager);
2962}
2963#endif
2964
2965#if QT_CONFIG(regularexpression)
2966/*!
2967 \fn QRegularExpression QVariant::toRegularExpression() const
2968 \since 5.0
2969
2970 Returns the variant as a QRegularExpression if the variant has userType() \l
2971 QRegularExpression; otherwise returns an empty QRegularExpression.
2972
2973 \sa canConvert(int targetTypeId), convert()
2974*/
2975QRegularExpression QVariant::toRegularExpression() const
2976{
2977 return qVariantToHelper<QRegularExpression>(d, handlerManager);
2978}
2979#endif // QT_CONFIG(regularexpression)
2980
2981#if QT_CONFIG(itemmodel)
2982/*!
2983 \since 5.0
2984
2985 Returns the variant as a QModelIndex if the variant has userType() \l
2986 QModelIndex; otherwise returns a default constructed QModelIndex.
2987
2988 \sa canConvert(int targetTypeId), convert(), toPersistentModelIndex()
2989*/
2990QModelIndex QVariant::toModelIndex() const
2991{
2992 return qVariantToHelper<QModelIndex>(d, handlerManager);
2993}
2994
2995/*!
2996 \since 5.5
2997
2998 Returns the variant as a QPersistentModelIndex if the variant has userType() \l
2999 QPersistentModelIndex; otherwise returns a default constructed QPersistentModelIndex.
3000
3001 \sa canConvert(int targetTypeId), convert(), toModelIndex()
3002*/
3003QPersistentModelIndex QVariant::toPersistentModelIndex() const
3004{
3005 return qVariantToHelper<QPersistentModelIndex>(d, handlerManager);
3006}
3007#endif // QT_CONFIG(itemmodel)
3008
3009#ifndef QT_BOOTSTRAPPED
3010/*!
3011 \since 5.0
3012
3013 Returns the variant as a QUuid if the variant has type()
3014 \l QMetaType::QUuid, \l QMetaType::QByteArray or \l QMetaType::QString;
3015 otherwise returns a default-constructed QUuid.
3016
3017 \sa canConvert(int targetTypeId), convert()
3018*/
3019QUuid QVariant::toUuid() const
3020{
3021 return qVariantToHelper<QUuid>(d, handlerManager);
3022}
3023
3024/*!
3025 \since 5.0
3026
3027 Returns the variant as a QJsonValue if the variant has userType() \l
3028 QJsonValue; otherwise returns a default constructed QJsonValue.
3029
3030 \sa canConvert(int targetTypeId), convert()
3031*/
3032QJsonValue QVariant::toJsonValue() const
3033{
3034 return qVariantToHelper<QJsonValue>(d, handlerManager);
3035}
3036
3037/*!
3038 \since 5.0
3039
3040 Returns the variant as a QJsonObject if the variant has userType() \l
3041 QJsonObject; otherwise returns a default constructed QJsonObject.
3042
3043 \sa canConvert(int targetTypeId), convert()
3044*/
3045QJsonObject QVariant::toJsonObject() const
3046{
3047 return qVariantToHelper<QJsonObject>(d, handlerManager);
3048}
3049
3050/*!
3051 \since 5.0
3052
3053 Returns the variant as a QJsonArray if the variant has userType() \l
3054 QJsonArray; otherwise returns a default constructed QJsonArray.
3055
3056 \sa canConvert(int targetTypeId), convert()
3057*/
3058QJsonArray QVariant::toJsonArray() const
3059{
3060 return qVariantToHelper<QJsonArray>(d, handlerManager);
3061}
3062
3063/*!
3064 \since 5.0
3065
3066 Returns the variant as a QJsonDocument if the variant has userType() \l
3067 QJsonDocument; otherwise returns a default constructed QJsonDocument.
3068
3069 \sa canConvert(int targetTypeId), convert()
3070*/
3071QJsonDocument QVariant::toJsonDocument() const
3072{
3073 return qVariantToHelper<QJsonDocument>(d, handlerManager);
3074}
3075#endif // QT_BOOTSTRAPPED
3076
3077/*!
3078 \fn QChar QVariant::toChar() const
3079
3080 Returns the variant as a QChar if the variant has userType()
3081 \l QMetaType::QChar, \l QMetaType::Int, or \l QMetaType::UInt; otherwise
3082 returns an invalid QChar.
3083
3084 \sa canConvert(int targetTypeId), convert()
3085*/
3086QChar QVariant::toChar() const
3087{
3088 return qVariantToHelper<QChar>(d, handlerManager);
3089}
3090
3091/*!
3092 Returns the variant as a QBitArray if the variant has userType()
3093 \l QMetaType::QBitArray; otherwise returns an empty bit array.
3094
3095 \sa canConvert(int targetTypeId), convert()
3096*/
3097QBitArray QVariant::toBitArray() const
3098{
3099 return qVariantToHelper<QBitArray>(d, handlerManager);
3100}
3101
3102template <typename T>
3103inline T qNumVariantToHelper(const QVariant::Private &d,
3104 const HandlersManager &handlerManager, bool *ok, const T& val)
3105{
3106 const uint t = qMetaTypeId<T>();
3107 if (ok)
3108 *ok = true;
3109
3110 if (d.type == t)
3111 return val;
3112
3113 T ret = 0;
3114 if ((d.type >= QMetaType::User || t >= QMetaType::User)
3115 && QMetaType::convert(constData(d), d.type, &ret, t))
3116 return ret;
3117
3118 if (!handlerManager[d.type]->convert(&d, t, &ret, ok) && ok)
3119 *ok = false;
3120 return ret;
3121}
3122
3123/*!
3124 Returns the variant as an int if the variant has userType()
3125 \l QMetaType::Int, \l QMetaType::Bool, \l QMetaType::QByteArray,
3126 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::LongLong,
3127 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3128 otherwise returns 0.
3129
3130 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3131 converted to an int; otherwise \c{*}\a{ok} is set to false.
3132
3133 \b{Warning:} If the value is convertible to a \l QMetaType::LongLong but is
3134 too large to be represented in an int, the resulting arithmetic overflow
3135 will not be reflected in \a ok. A simple workaround is to use
3136 QString::toInt().
3137
3138 \sa canConvert(int targetTypeId), convert()
3139*/
3140int QVariant::toInt(bool *ok) const
3141{
3142 return qNumVariantToHelper<int>(d, handlerManager, ok, d.data.i);
3143}
3144
3145/*!
3146 Returns the variant as an unsigned int if the variant has userType()
3147 \l QMetaType::UInt, \l QMetaType::Bool, \l QMetaType::QByteArray,
3148 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
3149 \l QMetaType::LongLong, \l QMetaType::QString, or \l QMetaType::ULongLong;
3150 otherwise returns 0.
3151
3152 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3153 converted to an unsigned int; otherwise \c{*}\a{ok} is set to false.
3154
3155 \b{Warning:} If the value is convertible to a \l QMetaType::ULongLong but is
3156 too large to be represented in an unsigned int, the resulting arithmetic
3157 overflow will not be reflected in \a ok. A simple workaround is to use
3158 QString::toUInt().
3159
3160 \sa canConvert(int targetTypeId), convert()
3161*/
3162uint QVariant::toUInt(bool *ok) const
3163{
3164 return qNumVariantToHelper<uint>(d, handlerManager, ok, d.data.u);
3165}
3166
3167/*!
3168 Returns the variant as a long long int if the variant has userType()
3169 \l QMetaType::LongLong, \l QMetaType::Bool, \l QMetaType::QByteArray,
3170 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
3171 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3172 otherwise returns 0.
3173
3174 If \a ok is non-null: \c{*}\c{ok} is set to true if the value could be
3175 converted to an int; otherwise \c{*}\c{ok} is set to false.
3176
3177 \sa canConvert(int targetTypeId), convert()
3178*/
3179qlonglong QVariant::toLongLong(bool *ok) const
3180{
3181 return qNumVariantToHelper<qlonglong>(d, handlerManager, ok, d.data.ll);
3182}
3183
3184/*!
3185 Returns the variant as an unsigned long long int if the
3186 variant has type() \l QMetaType::ULongLong, \l QMetaType::Bool,
3187 \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::Double,
3188 \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString, or
3189 \l QMetaType::UInt; otherwise returns 0.
3190
3191 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3192 converted to an int; otherwise \c{*}\a{ok} is set to false.
3193
3194 \sa canConvert(int targetTypeId), convert()
3195*/
3196qulonglong QVariant::toULongLong(bool *ok) const
3197{
3198 return qNumVariantToHelper<qulonglong>(d, handlerManager, ok, d.data.ull);
3199}
3200
3201/*!
3202 Returns the variant as a bool if the variant has userType() Bool.
3203
3204 Returns \c true if the variant has userType() \l QMetaType::Bool,
3205 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
3206 \l QMetaType::LongLong, \l QMetaType::UInt, or \l QMetaType::ULongLong and
3207 the value is non-zero, or if the variant has type \l QMetaType::QString or
3208 \l QMetaType::QByteArray and its lower-case content is not one of the
3209 following: empty, "0" or "false"; otherwise returns \c false.
3210
3211 \sa canConvert(int targetTypeId), convert()
3212*/
3213bool QVariant::toBool() const
3214{
3215 if (d.type == Bool)
3216 return d.data.b;
3217
3218 bool res = false;
3219 handlerManager[d.type]->convert(&d, Bool, &res, 0);
3220
3221 return res;
3222}
3223
3224/*!
3225 Returns the variant as a double if the variant has userType()
3226 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
3227 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
3228 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3229 otherwise returns 0.0.
3230
3231 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3232 converted to a double; otherwise \c{*}\a{ok} is set to false.
3233
3234 \sa canConvert(int targetTypeId), convert()
3235*/
3236double QVariant::toDouble(bool *ok) const
3237{
3238 return qNumVariantToHelper<double>(d, handlerManager, ok, d.data.d);
3239}
3240
3241/*!
3242 Returns the variant as a float if the variant has userType()
3243 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
3244 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
3245 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3246 otherwise returns 0.0.
3247
3248 \since 4.6
3249
3250 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3251 converted to a double; otherwise \c{*}\a{ok} is set to false.
3252
3253 \sa canConvert(int targetTypeId), convert()
3254*/
3255float QVariant::toFloat(bool *ok) const
3256{
3257 return qNumVariantToHelper<float>(d, handlerManager, ok, d.data.f);
3258}
3259
3260/*!
3261 Returns the variant as a qreal if the variant has userType()
3262 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
3263 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
3264 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3265 otherwise returns 0.0.
3266
3267 \since 4.6
3268
3269 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3270 converted to a double; otherwise \c{*}\a{ok} is set to false.
3271
3272 \sa canConvert(int targetTypeId), convert()
3273*/
3274qreal QVariant::toReal(bool *ok) const
3275{
3276 return qNumVariantToHelper<qreal>(d, handlerManager, ok, d.data.real);
3277}
3278
3279/*!
3280 Returns the variant as a QVariantList if the variant has userType()
3281 \l QMetaType::QVariantList or \l QMetaType::QStringList; otherwise returns
3282 an empty list.
3283
3284 \sa canConvert(int targetTypeId), convert()
3285*/
3286QVariantList QVariant::toList() const
3287{
3288 return qVariantToHelper<QVariantList>(d, handlerManager);
3289}
3290
3291
3292static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
3293{
3294/*Invalid*/ 0,
3295
3296/*Bool*/ 1 << QVariant::Double | 1 << QVariant::Int | 1 << QVariant::UInt
3297 | 1 << QVariant::LongLong | 1 << QVariant::ULongLong | 1 << QVariant::ByteArray
3298 | 1 << QVariant::String | 1 << QVariant::Char,
3299
3300/*Int*/ 1 << QVariant::UInt | 1 << QVariant::String | 1 << QVariant::Double
3301 | 1 << QVariant::Bool | 1 << QVariant::LongLong | 1 << QVariant::ULongLong
3302 | 1 << QVariant::Char | 1 << QVariant::ByteArray | 1 << QVariant::Int,
3303
3304/*UInt*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::Double
3305 | 1 << QVariant::Bool | 1 << QVariant::LongLong | 1 << QVariant::ULongLong
3306 | 1 << QVariant::Char | 1 << QVariant::ByteArray,
3307
3308/*LLong*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::Double
3309 | 1 << QVariant::Bool | 1 << QVariant::UInt | 1 << QVariant::ULongLong
3310 | 1 << QVariant::Char | 1 << QVariant::ByteArray,
3311
3312/*ULlong*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::Double
3313 | 1 << QVariant::Bool | 1 << QVariant::UInt | 1 << QVariant::LongLong
3314 | 1 << QVariant::Char | 1 << QVariant::ByteArray,
3315
3316/*double*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::ULongLong
3317 | 1 << QVariant::Bool | 1 << QVariant::UInt | 1 << QVariant::LongLong
3318 | 1 << QVariant::ByteArray,
3319
3320/*QChar*/ 1 << QVariant::Int | 1 << QVariant::UInt | 1 << QVariant::LongLong
3321 | 1 << QVariant::ULongLong,
3322
3323/*QMap*/ 0,
3324