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