1/****************************************************************************
2**
3** Copyright (C) 2016 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 case QMetaType::QRegularExpression:
1056 if (d->type != QMetaType::QCborValue || !v_cast<QCborValue>(d)->isRegularExpression())
1057 return false;
1058 *static_cast<QRegularExpression *>(result) = v_cast<QCborValue>(d)->toRegularExpression();
1059 break;
1060 case QMetaType::QJsonValue:
1061 switch (d->type) {
1062 case QMetaType::Nullptr:
1063 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Null);
1064 break;
1065 case QVariant::Bool:
1066 *static_cast<QJsonValue *>(result) = QJsonValue(d->data.b);
1067 break;
1068 case QMetaType::Int:
1069 case QMetaType::UInt:
1070 case QMetaType::Double:
1071 case QMetaType::Float:
1072 case QMetaType::ULong:
1073 case QMetaType::Long:
1074 case QMetaType::LongLong:
1075 case QMetaType::ULongLong:
1076 case QMetaType::UShort:
1077 case QMetaType::UChar:
1078 case QMetaType::Char:
1079 case QMetaType::SChar:
1080 case QMetaType::Short:
1081 *static_cast<QJsonValue *>(result) = QJsonValue(qConvertToRealNumber(d, ok));
1082 Q_ASSERT(ok);
1083 break;
1084 case QVariant::String:
1085 *static_cast<QJsonValue *>(result) = QJsonValue(*v_cast<QString>(d));
1086 break;
1087 case QVariant::StringList:
1088 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonArray::fromStringList(*v_cast<QStringList>(d)));
1089 break;
1090 case QVariant::List:
1091 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonArray::fromVariantList(*v_cast<QVariantList>(d)));
1092 break;
1093 case QVariant::Map:
1094 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonObject::fromVariantMap(*v_cast<QVariantMap>(d)));
1095 break;
1096 case QVariant::Hash:
1097 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonObject::fromVariantHash(*v_cast<QVariantHash>(d)));
1098 break;
1099 case QMetaType::QJsonObject:
1100 *static_cast<QJsonValue *>(result) = *v_cast<QJsonObject>(d);
1101 break;
1102 case QMetaType::QJsonArray:
1103 *static_cast<QJsonValue *>(result) = *v_cast<QJsonArray>(d);
1104 break;
1105 case QMetaType::QJsonDocument: {
1106 QJsonDocument doc = *v_cast<QJsonDocument>(d);
1107 *static_cast<QJsonValue *>(result) = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1108 break;
1109 }
1110 case QMetaType::QCborValue:
1111 *static_cast<QJsonValue *>(result) = v_cast<QCborValue>(d)->toJsonValue();
1112 break;
1113 case QMetaType::QCborMap:
1114 *static_cast<QJsonValue *>(result) = v_cast<QCborMap>(d)->toJsonObject();
1115 break;
1116 case QMetaType::QCborArray:
1117 *static_cast<QJsonValue *>(result) = v_cast<QCborArray>(d)->toJsonArray();
1118 break;
1119 default:
1120 *static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Undefined);
1121 return false;
1122 }
1123 break;
1124 case QMetaType::QJsonArray:
1125 switch (d->type) {
1126 case QVariant::StringList:
1127 *static_cast<QJsonArray *>(result) = QJsonArray::fromStringList(*v_cast<QStringList>(d));
1128 break;
1129 case QVariant::List:
1130 *static_cast<QJsonArray *>(result) = QJsonArray::fromVariantList(*v_cast<QVariantList>(d));
1131 break;
1132 case QMetaType::QJsonValue:
1133 if (!v_cast<QJsonValue>(d)->isArray())
1134 return false;
1135 *static_cast<QJsonArray *>(result) = v_cast<QJsonValue>(d)->toArray();
1136 break;
1137 case QMetaType::QJsonDocument:
1138 if (!v_cast<QJsonDocument>(d)->isArray())
1139 return false;
1140 *static_cast<QJsonArray *>(result) = v_cast<QJsonDocument>(d)->array();
1141 break;
1142 case QMetaType::QCborValue:
1143 if (!v_cast<QCborValue>(d)->isArray())
1144 return false;
1145 *static_cast<QJsonArray *>(result) = v_cast<QCborValue>(d)->toArray().toJsonArray();
1146 break;
1147 case QMetaType::QCborArray:
1148 *static_cast<QJsonArray *>(result) = v_cast<QCborArray>(d)->toJsonArray();
1149 break;
1150 default:
1151 return false;
1152 }
1153 break;
1154 case QMetaType::QJsonObject:
1155 switch (d->type) {
1156 case QVariant::Map:
1157 *static_cast<QJsonObject *>(result) = QJsonObject::fromVariantMap(*v_cast<QVariantMap>(d));
1158 break;
1159 case QVariant::Hash:
1160 *static_cast<QJsonObject *>(result) = QJsonObject::fromVariantHash(*v_cast<QVariantHash>(d));
1161 break;
1162 case QMetaType::QJsonValue:
1163 if (!v_cast<QJsonValue>(d)->isObject())
1164 return false;
1165 *static_cast<QJsonObject *>(result) = v_cast<QJsonValue>(d)->toObject();
1166 break;
1167 case QMetaType::QJsonDocument:
1168 if (v_cast<QJsonDocument>(d)->isArray())
1169 return false;
1170 *static_cast<QJsonObject *>(result) = v_cast<QJsonDocument>(d)->object();
1171 break;
1172 case QMetaType::QCborValue:
1173 if (!v_cast<QCborValue>(d)->isMap())
1174 return false;
1175 *static_cast<QJsonObject *>(result) = v_cast<QCborValue>(d)->toMap().toJsonObject();
1176 break;
1177 case QMetaType::QCborMap:
1178 *static_cast<QJsonObject *>(result) = v_cast<QCborMap>(d)->toJsonObject();
1179 break;
1180 default:
1181 return false;
1182 }
1183 break;
1184 case QMetaType::QCborSimpleType:
1185 if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isSimpleType()) {
1186 *static_cast<QCborSimpleType *>(result) = v_cast<QCborValue>(d)->toSimpleType();
1187 break;
1188 }
1189 return false;
1190 case QMetaType::QCborValue:
1191 switch (d->type) {
1192 case QMetaType::Nullptr:
1193 *static_cast<QCborValue *>(result) = QCborValue(QCborValue::Null);
1194 break;
1195 case QVariant::Bool:
1196 *static_cast<QCborValue *>(result) = QCborValue(d->data.b);
1197 break;
1198 case QMetaType::Int:
1199 case QMetaType::UInt:
1200 case QMetaType::ULong:
1201 case QMetaType::Long:
1202 case QMetaType::LongLong:
1203 case QMetaType::ULongLong:
1204 case QMetaType::UShort:
1205 case QMetaType::UChar:
1206 case QMetaType::Char:
1207 case QMetaType::SChar:
1208 case QMetaType::Short:
1209 *static_cast<QCborValue *>(result) = QCborValue(qConvertToNumber(d, ok));
1210 Q_ASSERT(ok);
1211 break;
1212 case QMetaType::Double:
1213 case QMetaType::Float:
1214 *static_cast<QCborValue *>(result) = QCborValue(qConvertToRealNumber(d, ok));
1215 Q_ASSERT(ok);
1216 break;
1217 case QVariant::String:
1218 *static_cast<QCborValue *>(result) = *v_cast<QString>(d);
1219 break;
1220 case QVariant::StringList:
1221 *static_cast<QCborValue *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
1222 break;
1223 case QVariant::ByteArray:
1224 *static_cast<QCborValue *>(result) = *v_cast<QByteArray>(d);
1225 break;
1226 case QVariant::Date:
1227 *static_cast<QCborValue *>(result) = QCborValue(QDateTime(*v_cast<QDate>(d)));
1228 break;
1229 case QVariant::DateTime:
1230 *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QDateTime>(d));
1231 break;
1232 case QVariant::Url:
1233 *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUrl>(d));
1234 break;
1235 case QVariant::RegularExpression:
1236 *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QRegularExpression>(d));
1237 break;
1238 case QVariant::Uuid:
1239 *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUuid>(d));
1240 break;
1241 case QVariant::List:
1242 *static_cast<QCborValue *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
1243 break;
1244 case QVariant::Map:
1245 *static_cast<QCborValue *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
1246 break;
1247 case QVariant::Hash:
1248 *static_cast<QCborValue *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
1249 break;
1250 case QMetaType::QJsonValue:
1251 *static_cast<QCborValue *>(result) = QCborValue::fromJsonValue(*v_cast<QJsonValue>(d));
1252 break;
1253 case QMetaType::QJsonObject:
1254 *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
1255 break;
1256 case QMetaType::QJsonArray:
1257 *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
1258 break;
1259 case QMetaType::QJsonDocument: {
1260 QJsonDocument doc = *v_cast<QJsonDocument>(d);
1261 if (doc.isArray())
1262 *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(doc.array());
1263 else
1264 *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(doc.object());
1265 break;
1266 }
1267 case QMetaType::QCborSimpleType:
1268 *static_cast<QCborValue *>(result) = *v_cast<QCborSimpleType>(d);
1269 break;
1270 case QMetaType::QCborMap:
1271 *static_cast<QCborValue *>(result) = *v_cast<QCborMap>(d);
1272 break;
1273 case QMetaType::QCborArray:
1274 *static_cast<QCborValue *>(result) = *v_cast<QCborArray>(d);
1275 break;
1276 default:
1277 *static_cast<QCborValue *>(result) = {};
1278 return false;
1279 }
1280 break;
1281 case QMetaType::QCborArray:
1282 switch (d->type) {
1283 case QVariant::StringList:
1284 *static_cast<QCborArray *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
1285 break;
1286 case QVariant::List:
1287 *static_cast<QCborArray *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
1288 break;
1289 case QMetaType::QCborValue:
1290 if (!v_cast<QCborValue>(d)->isArray())
1291 return false;
1292 *static_cast<QCborArray *>(result) = v_cast<QCborValue>(d)->toArray();
1293 break;
1294 case QMetaType::QJsonDocument:
1295 if (!v_cast<QJsonDocument>(d)->isArray())
1296 return false;
1297 *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonDocument>(d)->array());
1298 break;
1299 case QMetaType::QJsonValue:
1300 if (!v_cast<QJsonValue>(d)->isArray())
1301 return false;
1302 *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonValue>(d)->toArray());
1303 break;
1304 case QMetaType::QJsonArray:
1305 *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
1306 break;
1307 default:
1308 return false;
1309 }
1310 break;
1311 case QMetaType::QCborMap:
1312 switch (d->type) {
1313 case QVariant::Map:
1314 *static_cast<QCborMap *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
1315 break;
1316 case QVariant::Hash:
1317 *static_cast<QCborMap *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
1318 break;
1319 case QMetaType::QCborValue:
1320 if (!v_cast<QCborValue>(d)->isMap())
1321 return false;
1322 *static_cast<QCborMap *>(result) = v_cast<QCborValue>(d)->toMap();
1323 break;
1324 case QMetaType::QJsonDocument:
1325 if (v_cast<QJsonDocument>(d)->isArray())
1326 return false;
1327 *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonDocument>(d)->object());
1328 break;
1329 case QMetaType::QJsonValue:
1330 if (!v_cast<QJsonValue>(d)->isObject())
1331 return false;
1332 *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonValue>(d)->toObject());
1333 break;
1334 case QMetaType::QJsonObject:
1335 *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
1336 break;
1337 default:
1338 return false;
1339 }
1340 break;
1341#endif
1342
1343 default:
1344#ifndef QT_NO_QOBJECT
1345 if (d->type == QVariant::String || d->type == QVariant::ByteArray) {
1346 QMetaEnum en = metaEnumFromType(t);
1347 if (en.isValid()) {
1348 QByteArray keys = (d->type == QVariant::String) ? v_cast<QString>(d)->toUtf8() : *v_cast<QByteArray>(d);
1349 int value = en.keysToValue(keys.constData(), ok);
1350 if (*ok) {
1351 switch (QMetaType::sizeOf(t)) {
1352 case 1:
1353 *static_cast<signed char *>(result) = value;
1354 return true;
1355 case 2:
1356 *static_cast<qint16 *>(result) = value;
1357 return true;
1358 case 4:
1359 *static_cast<qint32 *>(result) = value;
1360 return true;
1361 case 8:
1362 *static_cast<qint64 *>(result) = value;
1363 return true;
1364 }
1365 }
1366 }
1367 }
1368#endif
1369 if (QMetaType::typeFlags(t) & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
1370 qlonglong value = qConvertToNumber(d, ok);
1371 if (*ok) {
1372 switch (QMetaType::sizeOf(t)) {
1373 case 1:
1374 *static_cast<signed char *>(result) = value;
1375 return true;
1376 case 2:
1377 *static_cast<qint16 *>(result) = value;
1378 return true;
1379 case 4:
1380 *static_cast<qint32 *>(result) = value;
1381 return true;
1382 case 8:
1383 *static_cast<qint64 *>(result) = value;
1384 return true;
1385 }
1386 }
1387 return *ok;
1388 }
1389 return false;
1390 }
1391 return true;
1392}
1393
1394#if !defined(QT_NO_DEBUG_STREAM)
1395static void streamDebug(QDebug dbg, const QVariant &v)
1396{
1397 QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
1398 QVariantDebugStream<CoreTypesFilter> stream(dbg, d);
1399 QMetaTypeSwitcher::switcher<void>(stream, d->type, 0);
1400}
1401#endif
1402
1403const QVariant::Handler qt_kernel_variant_handler = {
1404 construct,
1405 clear,
1406 isNull,
1407#ifndef QT_NO_DATASTREAM
1408 0,
1409 0,
1410#endif
1411 compare,
1412 convert,
1413 0,
1414#if !defined(QT_NO_DEBUG_STREAM)
1415 streamDebug
1416#else
1417 0
1418#endif
1419};
1420
1421static void dummyConstruct(QVariant::Private *, const void *) { Q_ASSERT_X(false, "QVariant", "Trying to construct an unknown type"); }
1422static void dummyClear(QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to clear an unknown type"); }
1423static bool dummyIsNull(const QVariant::Private *d) { Q_ASSERT_X(false, "QVariant::isNull", "Trying to call isNull on an unknown type"); return d->is_null; }
1424static bool dummyCompare(const QVariant::Private *, const QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to compare an unknown types"); return false; }
1425static bool dummyConvert(const QVariant::Private *, int, void *, bool *) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); return false; }
1426#if !defined(QT_NO_DEBUG_STREAM)
1427static void dummyStreamDebug(QDebug, const QVariant &) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); }
1428#endif
1429const QVariant::Handler qt_dummy_variant_handler = {
1430 dummyConstruct,
1431 dummyClear,
1432 dummyIsNull,
1433#ifndef QT_NO_DATASTREAM
1434 0,
1435 0,
1436#endif
1437 dummyCompare,
1438 dummyConvert,
1439 0,
1440#if !defined(QT_NO_DEBUG_STREAM)
1441 dummyStreamDebug
1442#else
1443 0
1444#endif
1445};
1446
1447static void customConstruct(QVariant::Private *d, const void *copy)
1448{
1449 const QMetaType type(d->type);
1450 const uint size = type.sizeOf();
1451 if (!size) {
1452 qWarning("Trying to construct an instance of an invalid type, type id: %i", d->type);
1453 d->type = QVariant::Invalid;
1454 return;
1455 }
1456
1457 // this logic should match with QVariantIntegrator::CanUseInternalSpace
1458 if (size <= sizeof(QVariant::Private::Data)
1459 && (type.flags() & (QMetaType::MovableType | QMetaType::IsEnumeration))) {
1460 type.construct(&d->data.ptr, copy);
1461 d->is_shared = false;
1462 } else {
1463 // Private::Data contains long long, and long double is the biggest standard type.
1464 const size_t maxAlignment =
1465 qMax(Q_ALIGNOF(QVariant::Private::Data), Q_ALIGNOF(long double));
1466 const size_t s = sizeof(QVariant::PrivateShared);
1467 const size_t offset = s + ((s * maxAlignment - s) % maxAlignment);
1468 void *data = operator new(offset + size);
1469 void *ptr = static_cast<char *>(data) + offset;
1470 type.construct(ptr, copy);
1471 d->is_shared = true;
1472 d->data.shared = new (data) QVariant::PrivateShared(ptr);
1473 }
1474}
1475
1476static void customClear(QVariant::Private *d)
1477{
1478 if (!d->is_shared) {
1479 QMetaType::destruct(d->type, &d->data.ptr);
1480 } else {
1481 QMetaType::destruct(d->type, d->data.shared->ptr);
1482 d->data.shared->~PrivateShared();
1483 operator delete(d->data.shared);
1484 }
1485}
1486
1487static bool customIsNull(const QVariant::Private *d)
1488{
1489 if (d->is_null)
1490 return true;
1491 const char *const typeName = QMetaType::typeName(d->type);
1492 if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(d->type)))
1493 qFatal("QVariant::isNull: type %d unknown to QVariant.", d->type);
1494 uint typeNameLen = qstrlen(typeName);
1495 if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*') {
1496 const void *d_ptr = d->is_shared ? d->data.shared->ptr : &(d->data.ptr);
1497 return *static_cast<void *const *>(d_ptr) == nullptr;
1498 }
1499 return false;
1500}
1501
1502static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
1503{
1504 const char *const typeName = QMetaType::typeName(a->type);
1505 if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(a->type)))
1506 qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
1507
1508 const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data.ptr);
1509 const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data.ptr);
1510
1511 uint typeNameLen = qstrlen(typeName);
1512 if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*')
1513 return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
1514
1515 if (a->is_null && b->is_null)
1516 return true;
1517
1518 return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
1519}
1520
1521static bool customConvert(const QVariant::Private *d, int t, void *result, bool *ok)
1522{
1523 if (d->type >= QMetaType::User || t >= QMetaType::User) {
1524 if (QMetaType::convert(constData(*d), d->type, result, t)) {
1525 if (ok)
1526 *ok = true;
1527 return true;
1528 }
1529 }
1530 return convert(d, t, result, ok);
1531}
1532
1533#if !defined(QT_NO_DEBUG_STREAM)
1534static void customStreamDebug(QDebug dbg, const QVariant &variant) {
1535#ifndef QT_BOOTSTRAPPED
1536 QMetaType::TypeFlags flags = QMetaType::typeFlags(variant.userType());
1537 if (flags & QMetaType::PointerToQObject)
1538 dbg.nospace() << variant.value<QObject*>();
1539#else
1540 Q_UNUSED(dbg);
1541 Q_UNUSED(variant);
1542#endif
1543}
1544#endif
1545
1546const QVariant::Handler qt_custom_variant_handler = {
1547 customConstruct,
1548 customClear,
1549 customIsNull,
1550#ifndef QT_NO_DATASTREAM
1551 0,
1552 0,
1553#endif
1554 customCompare,
1555 customConvert,
1556 0,
1557#if !defined(QT_NO_DEBUG_STREAM)
1558 customStreamDebug
1559#else
1560 0
1561#endif
1562};
1563
1564} // annonymous used to hide QVariant handlers
1565
1566static HandlersManager handlerManager;
1567Q_STATIC_ASSERT_X(!QModulesPrivate::Core, "Initialization assumes that ModulesNames::Core is 0");
1568const QVariant::Handler *HandlersManager::Handlers[QModulesPrivate::ModulesCount]
1569 = { &qt_kernel_variant_handler, &qt_dummy_variant_handler,
1570 &qt_dummy_variant_handler, &qt_custom_variant_handler };
1571
1572Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler()
1573{
1574 return &qt_kernel_variant_handler;
1575}
1576
1577Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names */name, const QVariant::Handler *handler)
1578{
1579 handlerManager.registerHandler(static_cast<QModulesPrivate::Names>(name), handler);
1580}
1581
1582/*!
1583 \class QVariant
1584 \inmodule QtCore
1585 \brief The QVariant class acts like a union for the most common Qt data types.
1586
1587 \ingroup objectmodel
1588 \ingroup shared
1589
1590
1591 Because C++ forbids unions from including types that have
1592 non-default constructors or destructors, most interesting Qt
1593 classes cannot be used in unions. Without QVariant, this would be
1594 a problem for QObject::property() and for database work, etc.
1595
1596 A QVariant object holds a single value of a single type() at a
1597 time. (Some type()s are multi-valued, for example a string list.)
1598 You can find out what type, T, the variant holds, convert it to a
1599 different type using convert(), get its value using one of the
1600 toT() functions (e.g., toSize()) and check whether the type can
1601 be converted to a particular type using canConvert().
1602
1603 The methods named toT() (e.g., toInt(), toString()) are const. If
1604 you ask for the stored type, they return a copy of the stored
1605 object. If you ask for a type that can be generated from the
1606 stored type, toT() copies and converts and leaves the object
1607 itself unchanged. If you ask for a type that cannot be generated
1608 from the stored type, the result depends on the type; see the
1609 function documentation for details.
1610
1611 Here is some example code to demonstrate the use of QVariant:
1612
1613 \snippet code/src_corelib_kernel_qvariant.cpp 0
1614
1615 You can even store QList<QVariant> and QMap<QString, QVariant>
1616 values in a variant, so you can easily construct arbitrarily
1617 complex data structures of arbitrary types. This is very powerful
1618 and versatile, but may prove less memory and speed efficient than
1619 storing specific types in standard data structures.
1620
1621 QVariant also supports the notion of null values, where you can
1622 have a defined type with no value set. However, note that QVariant
1623 types can only be cast when they have had a value set.
1624
1625 \snippet code/src_corelib_kernel_qvariant.cpp 1
1626
1627 QVariant can be extended to support other types than those
1628 mentioned in the \l Type enum. See \l{Creating Custom Qt Types}{Creating Custom Qt Types}
1629 for details.
1630
1631 \section1 A Note on GUI Types
1632
1633 Because QVariant is part of the Qt Core module, it cannot provide
1634 conversion functions to data types defined in Qt GUI, such as
1635 QColor, QImage, and QPixmap. In other words, there is no \c
1636 toColor() function. Instead, you can use the QVariant::value() or
1637 the qvariant_cast() template function. For example:
1638
1639 \snippet code/src_corelib_kernel_qvariant.cpp 2
1640
1641 The inverse conversion (e.g., from QColor to QVariant) is
1642 automatic for all data types supported by QVariant, including
1643 GUI-related types:
1644
1645 \snippet code/src_corelib_kernel_qvariant.cpp 3
1646
1647 \section1 Using canConvert() and convert() Consecutively
1648
1649 When using canConvert() and convert() consecutively, it is possible for
1650 canConvert() to return true, but convert() to return false. This
1651 is typically because canConvert() only reports the general ability of
1652 QVariant to convert between types given suitable data; it is still
1653 possible to supply data which cannot actually be converted.
1654
1655 For example, canConvert(Int) would return true when called on a variant
1656 containing a string because, in principle, QVariant is able to convert
1657 strings of numbers to integers.
1658 However, if the string contains non-numeric characters, it cannot be
1659 converted to an integer, and any attempt to convert it will fail.
1660 Hence, it is important to have both functions return true for a
1661 successful conversion.
1662
1663 \sa QMetaType
1664*/
1665
1666/*!
1667 \obsolete Use QMetaType::Type instead
1668 \enum QVariant::Type
1669
1670 This enum type defines the types of variable that a QVariant can
1671 contain.
1672
1673 \value Invalid no type
1674 \value BitArray a QBitArray
1675 \value Bitmap a QBitmap
1676 \value Bool a bool
1677 \value Brush a QBrush
1678 \value ByteArray a QByteArray
1679 \value Char a QChar
1680 \value Color a QColor
1681 \value Cursor a QCursor
1682 \value Date a QDate
1683 \value DateTime a QDateTime
1684 \value Double a double
1685 \value EasingCurve a QEasingCurve
1686 \value Uuid a QUuid
1687 \value ModelIndex a QModelIndex
1688 \value PersistentModelIndex a QPersistentModelIndex (since 5.5)
1689 \value Font a QFont
1690 \value Hash a QVariantHash
1691 \value Icon a QIcon
1692 \value Image a QImage
1693 \value Int an int
1694 \value KeySequence a QKeySequence
1695 \value Line a QLine
1696 \value LineF a QLineF
1697 \value List a QVariantList
1698 \value Locale a QLocale
1699 \value LongLong a \l qlonglong
1700 \value Map a QVariantMap
1701 \value Matrix a QMatrix
1702 \value Transform a QTransform
1703 \value Matrix4x4 a QMatrix4x4
1704 \value Palette a QPalette
1705 \value Pen a QPen
1706 \value Pixmap a QPixmap
1707 \value Point a QPoint
1708 \value PointF a QPointF
1709 \value Polygon a QPolygon
1710 \value PolygonF a QPolygonF
1711 \value Quaternion a QQuaternion
1712 \value Rect a QRect
1713 \value RectF a QRectF
1714 \value RegExp a QRegExp
1715 \value RegularExpression a QRegularExpression
1716 \value Region a QRegion
1717 \value Size a QSize
1718 \value SizeF a QSizeF
1719 \value SizePolicy a QSizePolicy
1720 \value String a QString
1721 \value StringList a QStringList
1722 \value TextFormat a QTextFormat
1723 \value TextLength a QTextLength
1724 \value Time a QTime
1725 \value UInt a \l uint
1726 \value ULongLong a \l qulonglong
1727 \value Url a QUrl
1728 \value Vector2D a QVector2D
1729 \value Vector3D a QVector3D
1730 \value Vector4D a QVector4D
1731
1732 \value UserType Base value for user-defined types.
1733
1734 \omitvalue LastGuiType
1735 \omitvalue LastCoreType
1736 \omitvalue LastType
1737*/
1738
1739/*!
1740 \fn QVariant::QVariant(QVariant &&other)
1741
1742 Move-constructs a QVariant instance, making it point at the same
1743 object that \a other was pointing to.
1744
1745 \since 5.2
1746*/
1747
1748/*!
1749 \fn QVariant &QVariant::operator=(QVariant &&other)
1750
1751 Move-assigns \a other to this QVariant instance.
1752
1753 \since 5.2
1754*/
1755
1756/*!
1757 \fn QVariant::QVariant()
1758
1759 Constructs an invalid variant.
1760*/
1761
1762
1763/*!
1764 \fn QVariant::QVariant(int typeId, const void *copy)
1765
1766 Constructs variant of type \a typeId, and initializes with
1767 \a copy if \a copy is not 0.
1768
1769 Note that you have to pass the address of the variable you want stored.
1770
1771 Usually, you never have to use this constructor, use QVariant::fromValue()
1772 instead to construct variants from the pointer types represented by
1773 \c QMetaType::VoidStar, and \c QMetaType::QObjectStar.
1774
1775 \sa QVariant::fromValue(), QMetaType::Type
1776*/
1777
1778/*!
1779 \fn QVariant::QVariant(Type type)
1780
1781 Constructs an uninitialized variant of type \a type. This will create a
1782 variant in a special null state that if accessed will return a default
1783 constructed value of the \a type.
1784
1785 \sa isNull()
1786*/
1787
1788
1789
1790/*!
1791 \fn QVariant::create(int type, const void *copy)
1792
1793 \internal
1794
1795 Constructs a variant private of type \a type, and initializes with \a copy if
1796 \a copy is not 0.
1797*/
1798
1799void QVariant::create(int type, const void *copy)
1800{
1801 d.type = type;
1802 handlerManager[type]->construct(&d, copy);
1803}
1804
1805/*!
1806 \fn QVariant::~QVariant()
1807
1808 Destroys the QVariant and the contained object.
1809
1810 Note that subclasses that reimplement clear() should reimplement
1811 the destructor to call clear(). This destructor calls clear(), but
1812 because it is the destructor, QVariant::clear() is called rather
1813 than a subclass's clear().
1814*/
1815
1816QVariant::~QVariant()
1817{
1818 if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
1819 handlerManager[d.type]->clear(&d);
1820}
1821
1822/*!
1823 \fn QVariant::QVariant(const QVariant &p)
1824
1825 Constructs a copy of the variant, \a p, passed as the argument to
1826 this constructor.
1827*/
1828
1829QVariant::QVariant(const QVariant &p)
1830 : d(p.d)
1831{
1832 if (d.is_shared) {
1833 d.data.shared->ref.ref();
1834 } else if (p.d.type > Char) {
1835 handlerManager[d.type]->construct(&d, p.constData());
1836 d.is_null = p.d.is_null;
1837 }
1838}
1839
1840#ifndef QT_NO_DATASTREAM
1841/*!
1842 Reads the variant from the data stream, \a s.
1843*/
1844QVariant::QVariant(QDataStream &s)
1845{
1846 d.is_null = true;
1847 s >> *this;
1848}
1849#endif //QT_NO_DATASTREAM
1850
1851/*!
1852 \fn QVariant::QVariant(const QString &val)
1853
1854 Constructs a new variant with a string value, \a val.
1855*/
1856
1857/*!
1858 \fn QVariant::QVariant(QLatin1String val)
1859
1860 Constructs a new variant with a string value, \a val.
1861*/
1862
1863/*!
1864 \fn QVariant::QVariant(const char *val)
1865
1866 Constructs a new variant with a string value of \a val.
1867 The variant creates a deep copy of \a val into a QString assuming
1868 UTF-8 encoding on the input \a val.
1869
1870 Note that \a val is converted to a QString for storing in the
1871 variant and QVariant::userType() will return QMetaType::QString for
1872 the variant.
1873
1874 You can disable this operator by defining \c
1875 QT_NO_CAST_FROM_ASCII when you compile your applications.
1876*/
1877
1878#ifndef QT_NO_CAST_FROM_ASCII
1879QVariant::QVariant(const char *val)
1880{
1881 QString s = QString::fromUtf8(val);
1882 create(String, &s);
1883}
1884#endif
1885
1886/*!
1887 \fn QVariant::QVariant(const QStringList &val)
1888
1889 Constructs a new variant with a string list value, \a val.
1890*/
1891
1892/*!
1893 \fn QVariant::QVariant(const QMap<QString, QVariant> &val)
1894
1895 Constructs a new variant with a map of \l {QVariant}s, \a val.
1896*/
1897
1898/*!
1899 \fn QVariant::QVariant(const QHash<QString, QVariant> &val)
1900
1901 Constructs a new variant with a hash of \l {QVariant}s, \a val.
1902*/
1903
1904/*!
1905 \fn QVariant::QVariant(const QDate &val)
1906
1907 Constructs a new variant with a date value, \a val.
1908*/
1909
1910/*!
1911 \fn QVariant::QVariant(const QTime &val)
1912
1913 Constructs a new variant with a time value, \a val.
1914*/
1915
1916/*!
1917 \fn QVariant::QVariant(const QDateTime &val)
1918
1919 Constructs a new variant with a date/time value, \a val.
1920*/
1921
1922/*!
1923 \since 4.7
1924 \fn QVariant::QVariant(const QEasingCurve &val)
1925
1926 Constructs a new variant with an easing curve value, \a val.
1927*/
1928
1929/*!
1930 \since 5.0
1931 \fn QVariant::QVariant(const QUuid &val)
1932
1933 Constructs a new variant with an uuid value, \a val.
1934*/
1935
1936/*!
1937 \since 5.0
1938 \fn QVariant::QVariant(const QModelIndex &val)
1939
1940 Constructs a new variant with a QModelIndex value, \a val.
1941*/
1942
1943/*!
1944 \since 5.5
1945 \fn QVariant::QVariant(const QPersistentModelIndex &val)
1946
1947 Constructs a new variant with a QPersistentModelIndex value, \a val.
1948*/
1949
1950/*!
1951 \since 5.0
1952 \fn QVariant::QVariant(const QJsonValue &val)
1953
1954 Constructs a new variant with a json value, \a val.
1955*/
1956
1957/*!
1958 \since 5.0
1959 \fn QVariant::QVariant(const QJsonObject &val)
1960
1961 Constructs a new variant with a json object value, \a val.
1962*/
1963
1964/*!
1965 \since 5.0
1966 \fn QVariant::QVariant(const QJsonArray &val)
1967
1968 Constructs a new variant with a json array value, \a val.
1969*/
1970
1971/*!
1972 \since 5.0
1973 \fn QVariant::QVariant(const QJsonDocument &val)
1974
1975 Constructs a new variant with a json document value, \a val.
1976*/
1977
1978/*!
1979 \fn QVariant::QVariant(const QByteArray &val)
1980
1981 Constructs a new variant with a bytearray value, \a val.
1982*/
1983
1984/*!
1985 \fn QVariant::QVariant(const QBitArray &val)
1986
1987 Constructs a new variant with a bitarray value, \a val.
1988*/
1989
1990/*!
1991 \fn QVariant::QVariant(const QPoint &val)
1992
1993 Constructs a new variant with a point value of \a val.
1994 */
1995
1996/*!
1997 \fn QVariant::QVariant(const QPointF &val)
1998
1999 Constructs a new variant with a point value of \a val.
2000 */
2001
2002/*!
2003 \fn QVariant::QVariant(const QRectF &val)
2004
2005 Constructs a new variant with a rect value of \a val.
2006 */
2007
2008/*!
2009 \fn QVariant::QVariant(const QLineF &val)
2010
2011 Constructs a new variant with a line value of \a val.
2012 */
2013
2014/*!
2015 \fn QVariant::QVariant(const QLine &val)
2016
2017 Constructs a new variant with a line value of \a val.
2018 */
2019
2020/*!
2021 \fn QVariant::QVariant(const QRect &val)
2022
2023 Constructs a new variant with a rect value of \a val.
2024 */
2025
2026/*!
2027 \fn QVariant::QVariant(const QSize &val)
2028
2029 Constructs a new variant with a size value of \a val.
2030 */
2031
2032/*!
2033 \fn QVariant::QVariant(const QSizeF &val)
2034
2035 Constructs a new variant with a size value of \a val.
2036 */
2037
2038/*!
2039 \fn QVariant::QVariant(const QUrl &val)
2040
2041 Constructs a new variant with a url value of \a val.
2042 */
2043
2044/*!
2045 \fn QVariant::QVariant(int val)
2046
2047 Constructs a new variant with an integer value, \a val.
2048*/
2049
2050/*!
2051 \fn QVariant::QVariant(uint val)
2052
2053 Constructs a new variant with an unsigned integer value, \a val.
2054*/
2055
2056/*!
2057 \fn QVariant::QVariant(qlonglong val)
2058
2059 Constructs a new variant with a long long integer value, \a val.
2060*/
2061
2062/*!
2063 \fn QVariant::QVariant(qulonglong val)
2064
2065 Constructs a new variant with an unsigned long long integer value, \a val.
2066*/
2067
2068
2069/*!
2070 \fn QVariant::QVariant(bool val)
2071
2072 Constructs a new variant with a boolean value, \a val.
2073*/
2074
2075/*!
2076 \fn QVariant::QVariant(double val)
2077
2078 Constructs a new variant with a floating point value, \a val.
2079*/
2080
2081/*!
2082 \fn QVariant::QVariant(float val)
2083
2084 Constructs a new variant with a floating point value, \a val.
2085 \since 4.6
2086*/
2087
2088/*!
2089 \fn QVariant::QVariant(const QList<QVariant> &val)
2090
2091 Constructs a new variant with a list value, \a val.
2092*/
2093
2094/*!
2095 \fn QVariant::QVariant(QChar c)
2096
2097 Constructs a new variant with a char value, \a c.
2098*/
2099
2100/*!
2101 \fn QVariant::QVariant(const QLocale &l)
2102
2103 Constructs a new variant with a locale value, \a l.
2104*/
2105
2106/*!
2107 \fn QVariant::QVariant(const QRegExp &regExp)
2108
2109 Constructs a new variant with the regexp value \a regExp.
2110*/
2111
2112/*!
2113 \fn QVariant::QVariant(const QRegularExpression &re)
2114
2115 \since 5.0
2116
2117 Constructs a new variant with the regular expression value \a re.
2118*/
2119
2120QVariant::QVariant(Type type)
2121{ create(type, 0); }
2122QVariant::QVariant(int typeId, const void *copy)
2123{ create(typeId, copy); d.is_null = false; }
2124
2125/*!
2126 \internal
2127 flags is true if it is a pointer type
2128 */
2129QVariant::QVariant(int typeId, const void *copy, uint flags)
2130{
2131 if (flags) { //type is a pointer type
2132 d.type = typeId;
2133 d.data.ptr = *reinterpret_cast<void *const*>(copy);
2134 } else {
2135 create(typeId, copy);
2136 }
2137 d.is_null = false;
2138}
2139
2140QVariant::QVariant(int val)
2141 : d(Int)
2142{ d.data.i = val; }
2143QVariant::QVariant(uint val)
2144 : d(UInt)
2145{ d.data.u = val; }
2146QVariant::QVariant(qlonglong val)
2147 : d(LongLong)
2148{ d.data.ll = val; }
2149QVariant::QVariant(qulonglong val)
2150 : d(ULongLong)
2151{ d.data.ull = val; }
2152QVariant::QVariant(bool val)
2153 : d(Bool)
2154{ d.data.b = val; }
2155QVariant::QVariant(double val)
2156 : d(Double)
2157{ d.data.d = val; }
2158QVariant::QVariant(float val)
2159 : d(QMetaType::Float)
2160{ d.data.f = val; }
2161
2162QVariant::QVariant(const QByteArray &val)
2163 : d(ByteArray)
2164{ v_construct<QByteArray>(&d, val); }
2165QVariant::QVariant(const QBitArray &val)
2166 : d(BitArray)
2167{ v_construct<QBitArray>(&d, val); }
2168QVariant::QVariant(const QString &val)
2169 : d(String)
2170{ v_construct<QString>(&d, val); }
2171QVariant::QVariant(QChar val)
2172 : d(Char)
2173{ v_construct<QChar>(&d, val); }
2174QVariant::QVariant(QLatin1String val)
2175 : d(String)
2176{ v_construct<QString>(&d, val); }
2177QVariant::QVariant(const QStringList &val)
2178 : d(StringList)
2179{ v_construct<QStringList>(&d, val); }
2180
2181QVariant::QVariant(const QDate &val)
2182 : d(Date)
2183{ v_construct<QDate>(&d, val); }
2184QVariant::QVariant(const QTime &val)
2185 : d(Time)
2186{ v_construct<QTime>(&d, val); }
2187QVariant::QVariant(const QDateTime &val)
2188 : d(DateTime)
2189{ v_construct<QDateTime>(&d, val); }
2190#ifndef QT_BOOTSTRAPPED
2191QVariant::QVariant(const QEasingCurve &val)
2192 : d(EasingCurve)
2193{ v_construct<QEasingCurve>(&d, val); }
2194#endif
2195QVariant::QVariant(const QList<QVariant> &list)
2196 : d(List)
2197{ v_construct<QVariantList>(&d, list); }
2198QVariant::QVariant(const QMap<QString, QVariant> &map)
2199 : d(Map)
2200{ v_construct<QVariantMap>(&d, map); }
2201QVariant::QVariant(const QHash<QString, QVariant> &hash)
2202 : d(Hash)
2203{ v_construct<QVariantHash>(&d, hash); }
2204#ifndef QT_NO_GEOM_VARIANT
2205QVariant::QVariant(const QPoint &pt)
2206 : d(Point)
2207{ v_construct<QPoint>(&d, pt); }
2208QVariant::QVariant(const QPointF &pt)
2209 : d(PointF)
2210{ v_construct<QPointF>(&d, pt); }
2211QVariant::QVariant(const QRectF &r)
2212 : d(RectF)
2213{ v_construct<QRectF>(&d, r); }
2214QVariant::QVariant(const QLineF &l)
2215 : d(LineF)
2216{ v_construct<QLineF>(&d, l); }
2217QVariant::QVariant(const QLine &l)
2218 : d(Line)
2219{ v_construct<QLine>(&d, l); }
2220QVariant::QVariant(const QRect &r)
2221 : d(Rect)
2222{ v_construct<QRect>(&d, r); }
2223QVariant::QVariant(const QSize &s)
2224 : d(Size)
2225{ v_construct<QSize>(&d, s); }
2226QVariant::QVariant(const QSizeF &s)
2227 : d(SizeF)
2228{ v_construct<QSizeF>(&d, s); }
2229#endif
2230#ifndef QT_BOOTSTRAPPED
2231QVariant::QVariant(const QUrl &u)
2232 : d(Url)
2233{ v_construct<QUrl>(&d, u); }
2234#endif
2235QVariant::QVariant(const QLocale &l)
2236 : d(Locale)
2237{ v_construct<QLocale>(&d, l); }
2238#ifndef QT_NO_REGEXP
2239QVariant::QVariant(const QRegExp &regExp)
2240 : d(RegExp)
2241{ v_construct<QRegExp>(&d, regExp); }
2242#endif // QT_NO_REGEXP
2243#if QT_CONFIG(regularexpression)
2244QVariant::QVariant(const QRegularExpression &re)
2245 : d(RegularExpression)
2246{ v_construct<QRegularExpression>(&d, re); }
2247#endif // QT_CONFIG(regularexpression)
2248#ifndef QT_BOOTSTRAPPED
2249QVariant::QVariant(const QUuid &uuid)
2250 : d(Uuid)
2251{ v_construct<QUuid>(&d, uuid); }
2252QVariant::QVariant(const QJsonValue &jsonValue)
2253 : d(QMetaType::QJsonValue)
2254{ v_construct<QJsonValue>(&d, jsonValue); }
2255QVariant::QVariant(const QJsonObject &jsonObject)
2256 : d(QMetaType::QJsonObject)
2257{ v_construct<QJsonObject>(&d, jsonObject); }
2258QVariant::QVariant(const QJsonArray &jsonArray)
2259 : d(QMetaType::QJsonArray)
2260{ v_construct<QJsonArray>(&d, jsonArray); }
2261QVariant::QVariant(const QJsonDocument &jsonDocument)
2262 : d(QMetaType::QJsonDocument)
2263{ v_construct<QJsonDocument>(&d, jsonDocument); }
2264#endif // QT_BOOTSTRAPPED
2265#if QT_CONFIG(itemmodel)
2266QVariant::QVariant(const QModelIndex &modelIndex)
2267 : d(ModelIndex)
2268{ v_construct<QModelIndex>(&d, modelIndex); }
2269QVariant::QVariant(const QPersistentModelIndex &modelIndex)
2270 : d(PersistentModelIndex)
2271{ v_construct<QPersistentModelIndex>(&d, modelIndex); }
2272#endif
2273
2274/*!
2275 Returns the storage type of the value stored in the variant.
2276 Although this function is declared as returning QVariant::Type,
2277 the return value should be interpreted as QMetaType::Type. In
2278 particular, QVariant::UserType is returned here only if the value
2279 is equal or greater than QMetaType::User.
2280
2281 Note that return values in the ranges QVariant::Char through
2282 QVariant::RegExp and QVariant::Font through QVariant::Transform
2283 correspond to the values in the ranges QMetaType::QChar through
2284 QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion.
2285
2286 Pay particular attention when working with char and QChar
2287 variants. Note that there is no QVariant constructor specifically
2288 for type char, but there is one for QChar. For a variant of type
2289 QChar, this function returns QVariant::Char, which is the same as
2290 QMetaType::QChar, but for a variant of type \c char, this function
2291 returns QMetaType::Char, which is \e not the same as
2292 QVariant::Char.
2293
2294 Also note that the types \c void*, \c long, \c short, \c unsigned
2295 \c long, \c unsigned \c short, \c unsigned \c char, \c float, \c
2296 QObject*, and \c QWidget* are represented in QMetaType::Type but
2297 not in QVariant::Type, and they can be returned by this function.
2298 However, they are considered to be user defined types when tested
2299 against QVariant::Type.
2300
2301 To test whether an instance of QVariant contains a data type that
2302 is compatible with the data type you are interested in, use
2303 canConvert().
2304*/
2305
2306QVariant::Type QVariant::type() const
2307{
2308 return d.type >= QMetaType::User ? UserType : static_cast<Type>(d.type);
2309}
2310
2311/*!
2312 Returns the storage type of the value stored in the variant. For
2313 non-user types, this is the same as type().
2314
2315 \sa type()
2316*/
2317
2318int QVariant::userType() const
2319{
2320 return d.type;
2321}
2322
2323/*!
2324 Assigns the value of the variant \a variant to this variant.
2325*/
2326QVariant& QVariant::operator=(const QVariant &variant)
2327{
2328 if (this == &variant)
2329 return *this;
2330
2331 clear();
2332 if (variant.d.is_shared) {
2333 variant.d.data.shared->ref.ref();
2334 d = variant.d;
2335 } else if (variant.d.type > Char) {
2336 d.type = variant.d.type;
2337 handlerManager[d.type]->construct(&d, variant.constData());
2338 d.is_null = variant.d.is_null;
2339 } else {
2340 d = variant.d;
2341 }
2342
2343 return *this;
2344}
2345
2346/*!
2347 \fn void QVariant::swap(QVariant &other)
2348 \since 4.8
2349
2350 Swaps variant \a other with this variant. This operation is very
2351 fast and never fails.
2352*/
2353
2354/*!
2355 \fn void QVariant::detach()
2356
2357 \internal
2358*/
2359
2360void QVariant::detach()
2361{
2362 if (!d.is_shared || d.data.shared->ref.load() == 1)
2363 return;
2364
2365 Private dd;
2366 dd.type = d.type;
2367 handlerManager[d.type]->construct(&dd, constData());
2368 if (!d.data.shared->ref.deref())
2369 handlerManager[d.type]->clear(&d);
2370 d.data.shared = dd.data.shared;
2371}
2372
2373/*!
2374 \fn bool QVariant::isDetached() const
2375
2376 \internal
2377*/
2378
2379/*!
2380 Returns the name of the type stored in the variant. The returned
2381 strings describe the C++ datatype used to store the data: for
2382 example, "QFont", "QString", or "QVariantList". An Invalid
2383 variant returns 0.
2384*/
2385const char *QVariant::typeName() const
2386{
2387 return QMetaType::typeName(d.type);
2388}
2389
2390/*!
2391 Convert this variant to type QMetaType::UnknownType and free up any resources
2392 used.
2393*/
2394void QVariant::clear()
2395{
2396 if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
2397 handlerManager[d.type]->clear(&d);
2398 d.type = Invalid;
2399 d.is_null = true;
2400 d.is_shared = false;
2401}
2402
2403/*!
2404 Converts the int representation of the storage type, \a typeId, to
2405 its string representation.
2406
2407 Returns a null pointer if the type is QMetaType::UnknownType or doesn't exist.
2408*/
2409const char *QVariant::typeToName(int typeId)
2410{
2411 return QMetaType::typeName(typeId);
2412}
2413
2414
2415/*!
2416 Converts the string representation of the storage type given in \a
2417 name, to its enum representation.
2418
2419 If the string representation cannot be converted to any enum
2420 representation, the variant is set to \c Invalid.
2421*/
2422QVariant::Type QVariant::nameToType(const char *name)
2423{
2424 int metaType = QMetaType::type(name);
2425 return metaType <= int(UserType) ? QVariant::Type(metaType) : UserType;
2426}
2427
2428#ifndef QT_NO_DATASTREAM
2429enum { MapFromThreeCount = 36 };
2430static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] =
2431{
2432 QVariant::Invalid,
2433 QVariant::Map,
2434 QVariant::List,
2435 QVariant::String,
2436 QVariant::StringList,
2437 QVariant::Font,
2438 QVariant::Pixmap,
2439 QVariant::Brush,
2440 QVariant::Rect,
2441 QVariant::Size,
2442 QVariant::Color,
2443 QVariant::Palette,
2444 0, // ColorGroup
2445 QVariant::Icon,
2446 QVariant::Point,
2447 QVariant::Image,
2448 QVariant::Int,
2449 QVariant::UInt,
2450 QVariant::Bool,
2451 QVariant::Double,
2452 0, // Buggy ByteArray, QByteArray never had id == 20
2453 QVariant::Polygon,
2454 QVariant::Region,
2455 QVariant::Bitmap,
2456 QVariant::Cursor,
2457 QVariant::SizePolicy,
2458 QVariant::Date,
2459 QVariant::Time,
2460 QVariant::DateTime,
2461 QVariant::ByteArray,
2462 QVariant::BitArray,
2463 QVariant::KeySequence,
2464 QVariant::Pen,
2465 QVariant::LongLong,
2466 QVariant::ULongLong,
2467 QVariant::EasingCurve
2468};
2469
2470/*!
2471 Internal function for loading a variant from stream \a s. Use the
2472 stream operators instead.
2473
2474 \internal
2475*/
2476void QVariant::load(QDataStream &s)
2477{
2478 clear();
2479
2480 quint32 typeId;
2481 s >> typeId;
2482 if (s.version() < QDataStream::Qt_4_0) {
2483 if (typeId >= MapFromThreeCount)
2484 return;
2485 typeId = mapIdFromQt3ToCurrent[typeId];
2486 } else if (s.version() < QDataStream::Qt_5_0) {
2487 if (typeId == 127 /* QVariant::UserType */) {
2488 typeId = QMetaType::User;
2489 } else if (typeId >= 128 && typeId != QVariant::UserType) {
2490 // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
2491 // by moving all ids down by 97.
2492 typeId -= 97;
2493 } else if (typeId == 75 /* QSizePolicy */) {
2494 typeId = QMetaType::QSizePolicy;
2495 } else if (typeId > 75 && typeId <= 86) {
2496 // and as a result these types received lower ids too
2497 // QKeySequence QPen QTextLength QTextFormat QMatrix QTransform QMatrix4x4 QVector2D QVector3D QVector4D QQuaternion
2498 typeId -=1;
2499 }
2500 }
2501
2502 qint8 is_null = false;
2503 if (s.version() >= QDataStream::Qt_4_2)
2504 s >> is_null;
2505 if (typeId == QVariant::UserType) {
2506 QByteArray name;
2507 s >> name;
2508 typeId = QMetaType::type(name.constData());
2509 if (typeId == QMetaType::UnknownType) {
2510 s.setStatus(QDataStream::ReadCorruptData);
2511 qWarning("QVariant::load: unknown user type with name %s.", name.constData());
2512 return;
2513 }
2514 }
2515 create(typeId, 0);
2516 d.is_null = is_null;
2517
2518 if (!isValid()) {
2519 if (s.version() < QDataStream::Qt_5_0) {
2520 // Since we wrote something, we should read something
2521 QString x;
2522 s >> x;
2523 }
2524 d.is_null = true;
2525 return;
2526 }
2527
2528 // const cast is safe since we operate on a newly constructed variant
2529 if (!QMetaType::load(s, d.type, const_cast<void *>(constData()))) {
2530 s.setStatus(QDataStream::ReadCorruptData);
2531 qWarning("QVariant::load: unable to load type %d.", d.type);
2532 }
2533}
2534
2535/*!
2536 Internal function for saving a variant to the stream \a s. Use the
2537 stream operators instead.
2538
2539 \internal
2540*/
2541void QVariant::save(QDataStream &s) const
2542{
2543 quint32 typeId = type();
2544 bool fakeUserType = false;
2545 if (s.version() < QDataStream::Qt_4_0) {
2546 int i;
2547 for (i = 0; i <= MapFromThreeCount - 1; ++i) {
2548 if (mapIdFromQt3ToCurrent[i] == typeId) {
2549 typeId = i;
2550 break;
2551 }
2552 }
2553 if (i >= MapFromThreeCount) {
2554 s << QVariant();
2555 return;
2556 }
2557 } else if (s.version() < QDataStream::Qt_5_0) {
2558 if (typeId == QMetaType::User) {
2559 typeId = 127; // QVariant::UserType had this value in Qt4
2560 } else if (typeId >= 128 - 97 && typeId <= LastCoreType) {
2561 // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
2562 // by moving all ids down by 97.
2563 typeId += 97;
2564 } else if (typeId == QMetaType::QSizePolicy) {
2565 typeId = 75;
2566 } else if (typeId >= QMetaType::QKeySequence && typeId <= QMetaType::QQuaternion) {
2567 // and as a result these types received lower ids too
2568 typeId +=1;
2569 } else if (typeId == QMetaType::QPolygonF) {
2570 // This existed in Qt 4 only as a custom type
2571 typeId = 127;
2572 fakeUserType = true;
2573 }
2574 }
2575 s << typeId;
2576 if (s.version() >= QDataStream::Qt_4_2)
2577 s << qint8(d.is_null);
2578 if (d.type >= QVariant::UserType || fakeUserType) {
2579 s << QMetaType::typeName(userType());
2580 }
2581
2582 if (!isValid()) {
2583 if (s.version() < QDataStream::Qt_5_0)
2584 s << QString();
2585 return;
2586 }
2587
2588 if (!QMetaType::save(s, d.type, constData())) {
2589 qWarning("QVariant::save: unable to save type '%s' (type id: %d).\n", QMetaType::typeName(d.type), d.type);
2590 Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
2591 }
2592}
2593
2594/*!
2595 \since 4.4
2596
2597 Reads a variant \a p from the stream \a s.
2598
2599 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2600*/
2601QDataStream& operator>>(QDataStream &s, QVariant &p)
2602{
2603 p.load(s);
2604 return s;
2605}
2606
2607/*!
2608 Writes a variant \a p to the stream \a s.
2609
2610 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
2611*/
2612QDataStream& operator<<(QDataStream &s, const QVariant &p)
2613{
2614 p.save(s);
2615 return s;
2616}
2617
2618/*!
2619 Reads a variant type \a p in enum representation from the stream \a s.
2620*/
2621QDataStream& operator>>(QDataStream &s, QVariant::Type &p)
2622{
2623 quint32 u;
2624 s >> u;
2625 p = (QVariant::Type)u;
2626
2627 return s;
2628}
2629
2630/*!
2631 Writes a variant type \a p to the stream \a s.
2632*/
2633QDataStream& operator<<(QDataStream &s, const QVariant::Type p)
2634{
2635 s << static_cast<quint32>(p);
2636
2637 return s;
2638}
2639
2640#endif //QT_NO_DATASTREAM
2641
2642/*!
2643 \fn bool QVariant::isValid() const
2644
2645 Returns \c true if the storage type of this variant is not
2646 QMetaType::UnknownType; otherwise returns \c false.
2647*/
2648
2649template <typename T>
2650inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &handlerManager)
2651{
2652 const uint targetType = qMetaTypeId<T>();
2653 if (d.type == targetType)
2654 return *v_cast<T>(&d);
2655
2656 T ret;
2657 if (d.type >= QMetaType::User || targetType >= QMetaType::User) {
2658 const void * const from = constData(d);
2659 if (QMetaType::convert(from, d.type, &ret, targetType))
2660 return ret;
2661 }
2662
2663 handlerManager[d.type]->convert(&d, targetType, &ret, 0);
2664 return ret;
2665}
2666
2667/*!
2668 \fn QStringList QVariant::toStringList() const
2669
2670 Returns the variant as a QStringList if the variant has userType()
2671 \l QMetaType::QStringList, \l QMetaType::QString, or
2672 \l QMetaType::QVariantList of a type that can be converted to QString;
2673 otherwise returns an empty list.
2674
2675 \sa canConvert(int targetTypeId), convert()
2676*/
2677QStringList QVariant::toStringList() const
2678{
2679 return qVariantToHelper<QStringList>(d, handlerManager);
2680}
2681
2682/*!
2683 Returns the variant as a QString if the variant has a userType()
2684 including, but not limited to:
2685
2686 \l QMetaType::QString, \l QMetaType::Bool, \l QMetaType::QByteArray,
2687 \l QMetaType::QChar, \l QMetaType::QDate, \l QMetaType::QDateTime,
2688 \l QMetaType::Double, \l QMetaType::Int, \l QMetaType::LongLong,
2689 \l QMetaType::QStringList, \l QMetaType::QTime, \l QMetaType::UInt, or
2690 \l QMetaType::ULongLong.
2691
2692 Calling QVariant::toString() on an unsupported variant returns an empty
2693 string.
2694
2695 \sa canConvert(int targetTypeId), convert()
2696*/
2697QString QVariant::toString() const
2698{
2699 return qVariantToHelper<QString>(d, handlerManager);
2700}
2701
2702/*!
2703 Returns the variant as a QMap<QString, QVariant> if the variant
2704 has type() \l QMetaType::QVariantMap; otherwise returns an empty map.
2705
2706 \sa canConvert(int targetTypeId), convert()
2707*/
2708QVariantMap QVariant::toMap() const
2709{
2710 return qVariantToHelper<QVariantMap>(d, handlerManager);
2711}
2712
2713/*!
2714 Returns the variant as a QHash<QString, QVariant> if the variant
2715 has type() \l QMetaType::QVariantHash; otherwise returns an empty map.
2716
2717 \sa canConvert(int targetTypeId), convert()
2718*/
2719QVariantHash QVariant::toHash() const
2720{
2721 return qVariantToHelper<QVariantHash>(d, handlerManager);
2722}
2723
2724/*!
2725 \fn QDate QVariant::toDate() const
2726
2727 Returns the variant as a QDate if the variant has userType()
2728 \l QMetaType::QDate, \l QMetaType::QDateTime, or \l QMetaType::QString;
2729 otherwise returns an invalid date.
2730
2731 If the type() is \l QMetaType::QString, an invalid date will be returned if
2732 the string cannot be parsed as a Qt::ISODate format date.
2733
2734 \sa canConvert(int targetTypeId), convert()
2735*/
2736QDate QVariant::toDate() const
2737{
2738 return qVariantToHelper<QDate>(d, handlerManager);
2739}
2740
2741/*!
2742 \fn QTime QVariant::toTime() const
2743
2744 Returns the variant as a QTime if the variant has userType()
2745 \l QMetaType::QTime, \l QMetaType::QDateTime, or \l QMetaType::QString;
2746 otherwise returns an invalid time.
2747
2748 If the type() is \l QMetaType::QString, an invalid time will be returned if
2749 the string cannot be parsed as a Qt::ISODate format time.
2750
2751 \sa canConvert(int targetTypeId), convert()
2752*/
2753QTime QVariant::toTime() const
2754{
2755 return qVariantToHelper<QTime>(d, handlerManager);
2756}
2757
2758/*!
2759 \fn QDateTime QVariant::toDateTime() const
2760
2761 Returns the variant as a QDateTime if the variant has userType()
2762 \l QMetaType::QDateTime, \l QMetaType::QDate, or \l QMetaType::QString;
2763 otherwise returns an invalid date/time.
2764
2765 If the type() is \l QMetaType::QString, an invalid date/time will be
2766 returned if the string cannot be parsed as a Qt::ISODate format date/time.
2767
2768 \sa canConvert(int targetTypeId), convert()
2769*/
2770QDateTime QVariant::toDateTime() const
2771{
2772 return qVariantToHelper<QDateTime>(d, handlerManager);
2773}
2774
2775/*!
2776 \since 4.7
2777 \fn QEasingCurve QVariant::toEasingCurve() const
2778
2779 Returns the variant as a QEasingCurve if the variant has userType()
2780 \l QMetaType::QEasingCurve; otherwise returns a default easing curve.
2781
2782 \sa canConvert(int targetTypeId), convert()
2783*/
2784#ifndef QT_BOOTSTRAPPED
2785QEasingCurve QVariant::toEasingCurve() const
2786{
2787 return qVariantToHelper<QEasingCurve>(d, handlerManager);
2788}
2789#endif
2790
2791/*!
2792 \fn QByteArray QVariant::toByteArray() const
2793
2794 Returns the variant as a QByteArray if the variant has userType()
2795 \l QMetaType::QByteArray or \l QMetaType::QString (converted using
2796 QString::fromUtf8()); otherwise returns an empty byte array.
2797
2798 \sa canConvert(int targetTypeId), convert()
2799*/
2800QByteArray QVariant::toByteArray() const
2801{
2802 return qVariantToHelper<QByteArray>(d, handlerManager);
2803}
2804
2805#ifndef QT_NO_GEOM_VARIANT
2806/*!
2807 \fn QPoint QVariant::toPoint() const
2808
2809 Returns the variant as a QPoint if the variant has userType()
2810 \l QMetaType::QPoint or \l QMetaType::QPointF; otherwise returns a null
2811 QPoint.
2812
2813 \sa canConvert(int targetTypeId), convert()
2814*/
2815QPoint QVariant::toPoint() const
2816{
2817 return qVariantToHelper<QPoint>(d, handlerManager);
2818}
2819
2820/*!
2821 \fn QRect QVariant::toRect() const
2822
2823 Returns the variant as a QRect if the variant has userType()
2824 \l QMetaType::QRect; otherwise returns an invalid QRect.
2825
2826 \sa canConvert(int targetTypeId), convert()
2827*/
2828QRect QVariant::toRect() const
2829{
2830 return qVariantToHelper<QRect>(d, handlerManager);
2831}
2832
2833/*!
2834 \fn QSize QVariant::toSize() const
2835
2836 Returns the variant as a QSize if the variant has userType()
2837 \l QMetaType::QSize; otherwise returns an invalid QSize.
2838
2839 \sa canConvert(int targetTypeId), convert()
2840*/
2841QSize QVariant::toSize() const
2842{
2843 return qVariantToHelper<QSize>(d, handlerManager);
2844}
2845
2846/*!
2847 \fn QSizeF QVariant::toSizeF() const
2848
2849 Returns the variant as a QSizeF if the variant has userType() \l
2850 QMetaType::QSizeF; otherwise returns an invalid QSizeF.
2851
2852 \sa canConvert(int targetTypeId), convert()
2853*/
2854QSizeF QVariant::toSizeF() const
2855{
2856 return qVariantToHelper<QSizeF>(d, handlerManager);
2857}
2858
2859/*!
2860 \fn QRectF QVariant::toRectF() const
2861
2862 Returns the variant as a QRectF if the variant has userType()
2863 \l QMetaType::QRect or \l QMetaType::QRectF; otherwise returns an invalid
2864 QRectF.
2865
2866 \sa canConvert(int targetTypeId), convert()
2867*/
2868QRectF QVariant::toRectF() const
2869{
2870 return qVariantToHelper<QRectF>(d, handlerManager);
2871}
2872
2873/*!
2874 \fn QLineF QVariant::toLineF() const
2875
2876 Returns the variant as a QLineF if the variant has userType()
2877 \l QMetaType::QLineF; otherwise returns an invalid QLineF.
2878
2879 \sa canConvert(int targetTypeId), convert()
2880*/
2881QLineF QVariant::toLineF() const
2882{
2883 return qVariantToHelper<QLineF>(d, handlerManager);
2884}
2885
2886/*!
2887 \fn QLine QVariant::toLine() const
2888
2889 Returns the variant as a QLine if the variant has userType()
2890 \l QMetaType::QLine; otherwise returns an invalid QLine.
2891
2892 \sa canConvert(int targetTypeId), convert()
2893*/
2894QLine QVariant::toLine() const
2895{
2896 return qVariantToHelper<QLine>(d, handlerManager);
2897}
2898
2899/*!
2900 \fn QPointF QVariant::toPointF() const
2901
2902 Returns the variant as a QPointF if the variant has userType() \l
2903 QMetaType::QPoint or \l QMetaType::QPointF; otherwise returns a null
2904 QPointF.
2905
2906 \sa canConvert(int targetTypeId), convert()
2907*/
2908QPointF QVariant::toPointF() const
2909{
2910 return qVariantToHelper<QPointF>(d, handlerManager);
2911}
2912
2913#endif // QT_NO_GEOM_VARIANT
2914
2915#ifndef QT_BOOTSTRAPPED
2916/*!
2917 \fn QUrl QVariant::toUrl() const
2918
2919 Returns the variant as a QUrl if the variant has userType()
2920 \l QMetaType::QUrl; otherwise returns an invalid QUrl.
2921
2922 \sa canConvert(int targetTypeId), convert()
2923*/
2924QUrl QVariant::toUrl() const
2925{
2926 return qVariantToHelper<QUrl>(d, handlerManager);
2927}
2928#endif
2929
2930/*!
2931 \fn QLocale QVariant::toLocale() const
2932
2933 Returns the variant as a QLocale if the variant has userType()
2934 \l QMetaType::QLocale; otherwise returns an invalid QLocale.
2935
2936 \sa canConvert(int targetTypeId), convert()
2937*/
2938QLocale QVariant::toLocale() const
2939{
2940 return qVariantToHelper<QLocale>(d, handlerManager);
2941}
2942
2943/*!
2944 \fn QRegExp QVariant::toRegExp() const
2945 \since 4.1
2946
2947 Returns the variant as a QRegExp if the variant has userType()
2948 \l QMetaType::QRegExp; otherwise returns an empty QRegExp.
2949
2950 \sa canConvert(int targetTypeId), convert()
2951*/
2952#ifndef QT_NO_REGEXP
2953QRegExp QVariant::toRegExp() const
2954{
2955 return qVariantToHelper<QRegExp>(d, handlerManager);
2956}
2957#endif
2958
2959#if QT_CONFIG(regularexpression)
2960/*!
2961 \fn QRegularExpression QVariant::toRegularExpression() const
2962 \since 5.0
2963
2964 Returns the variant as a QRegularExpression if the variant has userType() \l
2965 QRegularExpression; otherwise returns an empty QRegularExpression.
2966
2967 \sa canConvert(int targetTypeId), convert()
2968*/
2969QRegularExpression QVariant::toRegularExpression() const
2970{
2971 return qVariantToHelper<QRegularExpression>(d, handlerManager);
2972}
2973#endif // QT_CONFIG(regularexpression)
2974
2975#if QT_CONFIG(itemmodel)
2976/*!
2977 \since 5.0
2978
2979 Returns the variant as a QModelIndex if the variant has userType() \l
2980 QModelIndex; otherwise returns a default constructed QModelIndex.
2981
2982 \sa canConvert(int targetTypeId), convert(), toPersistentModelIndex()
2983*/
2984QModelIndex QVariant::toModelIndex() const
2985{
2986 return qVariantToHelper<QModelIndex>(d, handlerManager);
2987}
2988
2989/*!
2990 \since 5.5
2991
2992 Returns the variant as a QPersistentModelIndex if the variant has userType() \l
2993 QPersistentModelIndex; otherwise returns a default constructed QPersistentModelIndex.
2994
2995 \sa canConvert(int targetTypeId), convert(), toModelIndex()
2996*/
2997QPersistentModelIndex QVariant::toPersistentModelIndex() const
2998{
2999 return qVariantToHelper<QPersistentModelIndex>(d, handlerManager);
3000}
3001#endif // QT_CONFIG(itemmodel)
3002
3003#ifndef QT_BOOTSTRAPPED
3004/*!
3005 \since 5.0
3006
3007 Returns the variant as a QUuid if the variant has type()
3008 \l QMetaType::QUuid, \l QMetaType::QByteArray or \l QMetaType::QString;
3009 otherwise returns a default-constructed QUuid.
3010
3011 \sa canConvert(int targetTypeId), convert()
3012*/
3013QUuid QVariant::toUuid() const
3014{
3015 return qVariantToHelper<QUuid>(d, handlerManager);
3016}
3017
3018/*!
3019 \since 5.0
3020
3021 Returns the variant as a QJsonValue if the variant has userType() \l
3022 QJsonValue; otherwise returns a default constructed QJsonValue.
3023
3024 \sa canConvert(int targetTypeId), convert()
3025*/
3026QJsonValue QVariant::toJsonValue() const
3027{
3028 return qVariantToHelper<QJsonValue>(d, handlerManager);
3029}
3030
3031/*!
3032 \since 5.0
3033
3034 Returns the variant as a QJsonObject if the variant has userType() \l
3035 QJsonObject; otherwise returns a default constructed QJsonObject.
3036
3037 \sa canConvert(int targetTypeId), convert()
3038*/
3039QJsonObject QVariant::toJsonObject() const
3040{
3041 return qVariantToHelper<QJsonObject>(d, handlerManager);
3042}
3043
3044/*!
3045 \since 5.0
3046
3047 Returns the variant as a QJsonArray if the variant has userType() \l
3048 QJsonArray; otherwise returns a default constructed QJsonArray.
3049
3050 \sa canConvert(int targetTypeId), convert()
3051*/
3052QJsonArray QVariant::toJsonArray() const
3053{
3054 return qVariantToHelper<QJsonArray>(d, handlerManager);
3055}
3056
3057/*!
3058 \since 5.0
3059
3060 Returns the variant as a QJsonDocument if the variant has userType() \l
3061 QJsonDocument; otherwise returns a default constructed QJsonDocument.
3062
3063 \sa canConvert(int targetTypeId), convert()
3064*/
3065QJsonDocument QVariant::toJsonDocument() const
3066{
3067 return qVariantToHelper<QJsonDocument>(d, handlerManager);
3068}
3069#endif // QT_BOOTSTRAPPED
3070
3071/*!
3072 \fn QChar QVariant::toChar() const
3073
3074 Returns the variant as a QChar if the variant has userType()
3075 \l QMetaType::QChar, \l QMetaType::Int, or \l QMetaType::UInt; otherwise
3076 returns an invalid QChar.
3077
3078 \sa canConvert(int targetTypeId), convert()
3079*/
3080QChar QVariant::toChar() const
3081{
3082 return qVariantToHelper<QChar>(d, handlerManager);
3083}
3084
3085/*!
3086 Returns the variant as a QBitArray if the variant has userType()
3087 \l QMetaType::QBitArray; otherwise returns an empty bit array.
3088
3089 \sa canConvert(int targetTypeId), convert()
3090*/
3091QBitArray QVariant::toBitArray() const
3092{
3093 return qVariantToHelper<QBitArray>(d, handlerManager);
3094}
3095
3096template <typename T>
3097inline T qNumVariantToHelper(const QVariant::Private &d,
3098 const HandlersManager &handlerManager, bool *ok, const T& val)
3099{
3100 const uint t = qMetaTypeId<T>();
3101 if (ok)
3102 *ok = true;
3103
3104 if (d.type == t)
3105 return val;
3106
3107 T ret = 0;
3108 if ((d.type >= QMetaType::User || t >= QMetaType::User)
3109 && QMetaType::convert(constData(d), d.type, &ret, t))
3110 return ret;
3111
3112 if (!handlerManager[d.type]->convert(&d, t, &ret, ok) && ok)
3113 *ok = false;
3114 return ret;
3115}
3116
3117/*!
3118 Returns the variant as an int if the variant has userType()
3119 \l QMetaType::Int, \l QMetaType::Bool, \l QMetaType::QByteArray,
3120 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::LongLong,
3121 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3122 otherwise returns 0.
3123
3124 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3125 converted to an int; otherwise \c{*}\a{ok} is set to false.
3126
3127 \b{Warning:} If the value is convertible to a \l QMetaType::LongLong but is
3128 too large to be represented in an int, the resulting arithmetic overflow
3129 will not be reflected in \a ok. A simple workaround is to use
3130 QString::toInt().
3131
3132 \sa canConvert(int targetTypeId), convert()
3133*/
3134int QVariant::toInt(bool *ok) const
3135{
3136 return qNumVariantToHelper<int>(d, handlerManager, ok, d.data.i);
3137}
3138
3139/*!
3140 Returns the variant as an unsigned int if the variant has userType()
3141 \l QMetaType::UInt, \l QMetaType::Bool, \l QMetaType::QByteArray,
3142 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
3143 \l QMetaType::LongLong, \l QMetaType::QString, or \l QMetaType::ULongLong;
3144 otherwise returns 0.
3145
3146 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3147 converted to an unsigned int; otherwise \c{*}\a{ok} is set to false.
3148
3149 \b{Warning:} If the value is convertible to a \l QMetaType::ULongLong but is
3150 too large to be represented in an unsigned int, the resulting arithmetic
3151 overflow will not be reflected in \a ok. A simple workaround is to use
3152 QString::toUInt().
3153
3154 \sa canConvert(int targetTypeId), convert()
3155*/
3156uint QVariant::toUInt(bool *ok) const
3157{
3158 return qNumVariantToHelper<uint>(d, handlerManager, ok, d.data.u);
3159}
3160
3161/*!
3162 Returns the variant as a long long int if the variant has userType()
3163 \l QMetaType::LongLong, \l QMetaType::Bool, \l QMetaType::QByteArray,
3164 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
3165 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3166 otherwise returns 0.
3167
3168 If \a ok is non-null: \c{*}\c{ok} is set to true if the value could be
3169 converted to an int; otherwise \c{*}\c{ok} is set to false.
3170
3171 \sa canConvert(int targetTypeId), convert()
3172*/
3173qlonglong QVariant::toLongLong(bool *ok) const
3174{
3175 return qNumVariantToHelper<qlonglong>(d, handlerManager, ok, d.data.ll);
3176}
3177
3178/*!
3179 Returns the variant as an unsigned long long int if the
3180 variant has type() \l QMetaType::ULongLong, \l QMetaType::Bool,
3181 \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::Double,
3182 \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString, or
3183 \l QMetaType::UInt; otherwise returns 0.
3184
3185 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3186 converted to an int; otherwise \c{*}\a{ok} is set to false.
3187
3188 \sa canConvert(int targetTypeId), convert()
3189*/
3190qulonglong QVariant::toULongLong(bool *ok) const
3191{
3192 return qNumVariantToHelper<qulonglong>(d, handlerManager, ok, d.data.ull);
3193}
3194
3195/*!
3196 Returns the variant as a bool if the variant has userType() Bool.
3197
3198 Returns \c true if the variant has userType() \l QMetaType::Bool,
3199 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
3200 \l QMetaType::LongLong, \l QMetaType::UInt, or \l QMetaType::ULongLong and
3201 the value is non-zero, or if the variant has type \l QMetaType::QString or
3202 \l QMetaType::QByteArray and its lower-case content is not one of the
3203 following: empty, "0" or "false"; otherwise returns \c false.
3204
3205 \sa canConvert(int targetTypeId), convert()
3206*/
3207bool QVariant::toBool() const
3208{
3209 if (d.type == Bool)
3210 return d.data.b;
3211
3212 bool res = false;
3213 handlerManager[d.type]->convert(&d, Bool, &res, 0);
3214
3215 return res;
3216}
3217
3218/*!
3219 Returns the variant as a double if the variant has userType()
3220 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
3221 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
3222 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3223 otherwise returns 0.0.
3224
3225 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3226 converted to a double; otherwise \c{*}\a{ok} is set to false.
3227
3228 \sa canConvert(int targetTypeId), convert()
3229*/
3230double QVariant::toDouble(bool *ok) const
3231{
3232 return qNumVariantToHelper<double>(d, handlerManager, ok, d.data.d);
3233}
3234
3235/*!
3236 Returns the variant as a float if the variant has userType()
3237 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
3238 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
3239 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3240 otherwise returns 0.0.
3241
3242 \since 4.6
3243
3244 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3245 converted to a double; otherwise \c{*}\a{ok} is set to false.
3246
3247 \sa canConvert(int targetTypeId), convert()
3248*/
3249float QVariant::toFloat(bool *ok) const
3250{
3251 return qNumVariantToHelper<float>(d, handlerManager, ok, d.data.f);
3252}
3253
3254/*!
3255 Returns the variant as a qreal if the variant has userType()
3256 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
3257 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
3258 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
3259 otherwise returns 0.0.
3260
3261 \since 4.6
3262
3263 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
3264 converted to a double; otherwise \c{*}\a{ok} is set to false.
3265
3266 \sa canConvert(int targetTypeId), convert()
3267*/
3268qreal QVariant::toReal(bool *ok) const
3269{
3270 return qNumVariantToHelper<qreal>(d, handlerManager, ok, d.data.real);
3271}
3272
3273/*!
3274 Returns the variant as a QVariantList if the variant has userType()
3275 \l QMetaType::QVariantList or \l QMetaType::QStringList; otherwise returns
3276 an empty list.
3277
3278 \sa canConvert(int targetTypeId), convert()
3279*/
3280QVariantList QVariant::toList() const
3281{
3282 return qVariantToHelper<QVariantList>(d, handlerManager);
3283}
3284
3285
3286static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
3287{
3288/*Invalid*/ 0,
3289
3290/*Bool*/ 1 << QVariant::Double | 1 << QVariant::Int | 1 << QVariant::UInt
3291 | 1 << QVariant::LongLong | 1 << QVariant::ULongLong | 1 << QVariant::ByteArray
3292 | 1 << QVariant::String | 1 << QVariant::Char,
3293
3294/*Int*/ 1 << QVariant::UInt | 1 << QVariant::String | 1 << QVariant::Double
3295 | 1 << QVariant::Bool | 1 << QVariant::LongLong | 1 << QVariant::ULongLong
3296 | 1 << QVariant::Char | 1 << QVariant::ByteArray | 1 << QVariant::Int,
3297
3298/*UInt*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::Double
3299 | 1 << QVariant::Bool | 1 << QVariant::LongLong | 1 << QVariant::ULongLong
3300 | 1 << QVariant::Char | 1 << QVariant::ByteArray,
3301
3302/*LLong*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::Double
3303 | 1 << QVariant::Bool | 1 << QVariant::UInt | 1 << QVariant::ULongLong
3304 | 1 << QVariant::Char | 1 << QVariant::ByteArray,
3305
3306/*ULlong*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::Double
3307 | 1 << QVariant::Bool | 1 << QVariant::UInt | 1 << QVariant::LongLong
3308 | 1 << QVariant::Char | 1 << QVariant::ByteArray,
3309
3310/*double*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::ULongLong
3311 | 1 << QVariant::Bool | 1 << QVariant::UInt | 1 << QVariant::LongLong
3312 | 1 << QVariant::ByteArray,
3313
3314/*QChar*/ 1 << QVariant::Int | 1 << QVariant::UInt | 1 << QVariant::LongLong
3315 | 1 << QVariant::ULongLong,
3316
3317/*QMap*/ 0,
3318
3319/*QList*/ 1 << QVariant::StringList,
3320
3321/*QString*/ 1 << QVariant::StringList | 1 << QVariant::ByteArray | 1 << QVariant::Int
3322 | 1 << QVariant::UInt | 1 << QVariant::