1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Copyright (C) 2018 Intel Corporation.
5** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
6** Contact: https://www.qt.io/licensing/
7**
8** This file is part of the QtCore module of the Qt Toolkit.
9**
10** $QT_BEGIN_LICENSE:LGPL$
11** Commercial License Usage
12** Licensees holding valid commercial Qt licenses may use this file in
13** accordance with the commercial license agreement provided with the
14** Software or, alternatively, in accordance with the terms contained in
15** a written agreement between you and The Qt Company. For licensing terms
16** and conditions see https://www.qt.io/terms-conditions. For further
17** information use the contact form at https://www.qt.io/contact-us.
18**
19** GNU Lesser General Public License Usage
20** Alternatively, this file may be used under the terms of the GNU Lesser
21** General Public License version 3 as published by the Free Software
22** Foundation and appearing in the file LICENSE.LGPL3 included in the
23** packaging of this file. Please review the following information to
24** ensure the GNU Lesser General Public License version 3 requirements
25** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26**
27** GNU General Public License Usage
28** Alternatively, this file may be used under the terms of the GNU
29** General Public License version 2.0 or (at your option) the GNU General
30** Public license version 3 or any later version approved by the KDE Free
31** Qt Foundation. The licenses are as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33** included in the packaging of this file. Please review the following
34** information to ensure the GNU General Public License requirements will
35** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36** https://www.gnu.org/licenses/gpl-3.0.html.
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qvariant.h"
43#include "qbitarray.h"
44#include "qbytearray.h"
45#include "qdatastream.h"
46#include "qdebug.h"
47#include "qmap.h"
48#include "qdatetime.h"
49#if QT_CONFIG(easingcurve)
50#include "qeasingcurve.h"
51#endif
52#include "qlist.h"
53#if QT_CONFIG(regularexpression)
54#include "qregularexpression.h"
55#endif
56#include "qstring.h"
57#include "qstringlist.h"
58#include "qurl.h"
59#include "qlocale.h"
60#include "quuid.h"
61#if QT_CONFIG(itemmodel)
62#include "qabstractitemmodel.h"
63#endif
64#ifndef QT_BOOTSTRAPPED
65#include "qcborarray.h"
66#include "qcborcommon.h"
67#include "qcbormap.h"
68#include "qjsonvalue.h"
69#include "qjsonobject.h"
70#include "qjsonarray.h"
71#include "qjsondocument.h"
72#include "qbytearraylist.h"
73#endif
74#include "private/qvariant_p.h"
75#include "private/qlocale_p.h"
76#include "qmetatype_p.h"
77#include <qmetaobject.h>
78
79#ifndef QT_NO_GEOM_VARIANT
80#include "qsize.h"
81#include "qpoint.h"
82#include "qrect.h"
83#include "qline.h"
84#endif
85
86#include <cmath>
87#include <float.h>
88#include <cstring>
89
90QT_BEGIN_NAMESPACE
91
92namespace { // annonymous used to hide QVariant handlers
93
94/*!
95 \internal
96 */
97static qlonglong qMetaTypeNumber(const QVariant::Private *d)
98{
99 switch (d->typeId()) {
100 case QMetaType::Int:
101 return d->get<int>();
102 case QMetaType::LongLong:
103 return d->get<qlonglong>();
104 case QMetaType::Char:
105 return qlonglong(d->get<char>());
106 case QMetaType::SChar:
107 return qlonglong(d->get<signed char>());
108 case QMetaType::Short:
109 return qlonglong(d->get<short>());
110 case QMetaType::Long:
111 return qlonglong(d->get<long>());
112 case QMetaType::Float:
113 return qRound64(d->get<float>());
114 case QMetaType::Double:
115 return qRound64(d->get<double>());
116#ifndef QT_BOOTSTRAPPED
117 case QMetaType::QJsonValue:
118 return d->get<QJsonValue>().toDouble();
119 case QMetaType::QCborValue:
120 return d->get<QCborValue>().toInteger();
121#endif
122 }
123 Q_ASSERT(false);
124 return 0;
125}
126
127static qulonglong qMetaTypeUNumber(const QVariant::Private *d)
128{
129 switch (d->typeId()) {
130 case QMetaType::UInt:
131 return d->get<unsigned int>();
132 case QMetaType::ULongLong:
133 return d->get<qulonglong>();
134 case QMetaType::UChar:
135 return d->get<unsigned char>();
136 case QMetaType::UShort:
137 return d->get<unsigned short>();
138 case QMetaType::ULong:
139 return d->get<unsigned long>();
140 }
141 Q_ASSERT(false);
142 return 0;
143}
144
145static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok, bool allowStringToBool = false)
146{
147 *ok = true;
148
149 switch (uint(d->typeId())) {
150 case QMetaType::QString: {
151 const QString &s = d->get<QString>();
152 qlonglong l = s.toLongLong(ok);
153 if (*ok)
154 return l;
155 if (allowStringToBool) {
156 if (s == QLatin1String("false") || s == QLatin1String("0")) {
157 *ok = true;
158 return 0;
159 }
160 if (s == QLatin1String("true") || s == QLatin1String("1")) {
161 *ok = true;
162 return 1;
163 }
164 }
165 return 0;
166 }
167 case QMetaType::QChar:
168 return d->get<QChar>().unicode();
169 case QMetaType::QByteArray:
170 return d->get<QByteArray>().toLongLong(ok);
171 case QMetaType::Bool:
172 return qlonglong(d->get<bool>());
173#ifndef QT_BOOTSTRAPPED
174 case QMetaType::QCborValue:
175 if (!d->get<QCborValue>().isInteger() && !d->get<QCborValue>().isDouble())
176 break;
177 return qMetaTypeNumber(d);
178 case QMetaType::QJsonValue:
179 if (!d->get<QJsonValue>().isDouble())
180 break;
181 Q_FALLTHROUGH();
182#endif
183 case QMetaType::Double:
184 case QMetaType::Int:
185 case QMetaType::Char:
186 case QMetaType::SChar:
187 case QMetaType::Short:
188 case QMetaType::Long:
189 case QMetaType::Float:
190 case QMetaType::LongLong:
191 return qMetaTypeNumber(d);
192 case QMetaType::ULongLong:
193 case QMetaType::UInt:
194 case QMetaType::UChar:
195 case QMetaType::UShort:
196 case QMetaType::ULong:
197
198 return qlonglong(qMetaTypeUNumber(d));
199 }
200
201 QMetaType typeInfo = d->type();
202 if (typeInfo.flags() & QMetaType::IsEnumeration
203 || d->typeId() == QMetaType::QCborSimpleType) {
204 switch (typeInfo.sizeOf()) {
205 case 1:
206 return d->get<signed char>();
207 case 2:
208 return d->get<short>();
209 case 4:
210 return d->get<int>();
211 case 8:
212 return d->get<qlonglong>();
213 }
214 }
215
216 *ok = false;
217 return Q_INT64_C(0);
218}
219
220static qreal qConvertToRealNumber(const QVariant::Private *d, bool *ok)
221{
222 *ok = true;
223 switch (uint(d->typeId())) {
224 case QMetaType::QString:
225 return d->get<QString>().toDouble(ok);
226 case QMetaType::Double:
227 return qreal(d->get<double>());
228 case QMetaType::Float:
229 return qreal(d->get<float>());
230 case QMetaType::ULongLong:
231 case QMetaType::UInt:
232 case QMetaType::UChar:
233 case QMetaType::UShort:
234 case QMetaType::ULong:
235 return qreal(qMetaTypeUNumber(d));
236#ifndef QT_BOOTSTRAPPED
237 case QMetaType::QCborValue:
238 return d->get<QCborValue>().toDouble();
239 case QMetaType::QJsonValue:
240 return d->get<QJsonValue>().toDouble();
241#endif
242 default:
243 // includes enum conversion as well as invalid types
244 return qreal(qConvertToNumber(d, ok));
245 }
246}
247
248// the type of d has already been set, but other field are not set
249static void customConstruct(QVariant::Private *d, const void *copy)
250{
251 const QMetaType type = d->type();
252 const uint size = type.sizeOf();
253 if (!size) {
254 *d = QVariant::Private();
255 return;
256 }
257
258 if (QVariant::Private::canUseInternalSpace(type)) {
259 type.construct(&d->data, copy);
260 d->is_shared = false;
261 } else {
262 d->data.shared = QVariant::PrivateShared::create(type);
263 type.construct(d->data.shared->data(), copy);
264 d->is_shared = true;
265 }
266 // need to check for nullptr_t here, as this can get called by fromValue(nullptr). fromValue() uses
267 // std::addressof(value) which in this case returns the address of the nullptr object.
268 d->is_null = !copy || type == QMetaType::fromType<std::nullptr_t>();
269}
270
271static void customClear(QVariant::Private *d)
272{
273 if (!d->is_shared) {
274 d->type().destruct(&d->data);
275 } else {
276 d->type().destruct(d->data.shared->data());
277 QVariant::PrivateShared::free(d->data.shared);
278 }
279}
280
281
282} // annonymous used to hide QVariant handlers
283
284/*!
285 \class QVariant
286 \inmodule QtCore
287 \brief The QVariant class acts like a union for the most common Qt data types.
288
289 \ingroup objectmodel
290 \ingroup shared
291
292
293 Because C++ forbids unions from including types that have
294 non-default constructors or destructors, most interesting Qt
295 classes cannot be used in unions. Without QVariant, this would be
296 a problem for QObject::property() and for database work, etc.
297
298 A QVariant object holds a single value of a single type() at a
299 time. (Some type()s are multi-valued, for example a string list.)
300 You can find out what type, T, the variant holds, convert it to a
301 different type using convert(), get its value using one of the
302 toT() functions (e.g., toSize()) and check whether the type can
303 be converted to a particular type using canConvert().
304
305 The methods named toT() (e.g., toInt(), toString()) are const. If
306 you ask for the stored type, they return a copy of the stored
307 object. If you ask for a type that can be generated from the
308 stored type, toT() copies and converts and leaves the object
309 itself unchanged. If you ask for a type that cannot be generated
310 from the stored type, the result depends on the type; see the
311 function documentation for details.
312
313 Here is some example code to demonstrate the use of QVariant:
314
315 \snippet code/src_corelib_kernel_qvariant.cpp 0
316
317 You can even store QList<QVariant> and QMap<QString, QVariant>
318 values in a variant, so you can easily construct arbitrarily
319 complex data structures of arbitrary types. This is very powerful
320 and versatile, but may prove less memory and speed efficient than
321 storing specific types in standard data structures.
322
323 QVariant also supports the notion of null values, where you can
324 have a defined type with no value set. However, note that QVariant
325 types can only be cast when they have had a value set.
326
327 \snippet code/src_corelib_kernel_qvariant.cpp 1
328
329 QVariant can be extended to support other types than those
330 mentioned in the \l Type enum. See \l{Creating Custom Qt Types}{Creating Custom Qt Types}
331 for details.
332
333 \section1 A Note on GUI Types
334
335 Because QVariant is part of the Qt Core module, it cannot provide
336 conversion functions to data types defined in Qt GUI, such as
337 QColor, QImage, and QPixmap. In other words, there is no \c
338 toColor() function. Instead, you can use the QVariant::value() or
339 the qvariant_cast() template function. For example:
340
341 \snippet code/src_corelib_kernel_qvariant.cpp 2
342
343 The inverse conversion (e.g., from QColor to QVariant) is
344 automatic for all data types supported by QVariant, including
345 GUI-related types:
346
347 \snippet code/src_corelib_kernel_qvariant.cpp 3
348
349 \section1 Using canConvert() and convert() Consecutively
350
351 When using canConvert() and convert() consecutively, it is possible for
352 canConvert() to return true, but convert() to return false. This
353 is typically because canConvert() only reports the general ability of
354 QVariant to convert between types given suitable data; it is still
355 possible to supply data which cannot actually be converted.
356
357 For example, canConvert(Int) would return true when called on a variant
358 containing a string because, in principle, QVariant is able to convert
359 strings of numbers to integers.
360 However, if the string contains non-numeric characters, it cannot be
361 converted to an integer, and any attempt to convert it will fail.
362 Hence, it is important to have both functions return true for a
363 successful conversion.
364
365 \sa QMetaType
366*/
367
368/*!
369 \obsolete Use QMetaType::Type instead
370 \enum QVariant::Type
371
372 This enum type defines the types of variable that a QVariant can
373 contain.
374
375 \value Invalid no type
376 \value BitArray a QBitArray
377 \value Bitmap a QBitmap
378 \value Bool a bool
379 \value Brush a QBrush
380 \value ByteArray a QByteArray
381 \value Char a QChar
382 \value Color a QColor
383 \value Cursor a QCursor
384 \value Date a QDate
385 \value DateTime a QDateTime
386 \value Double a double
387 \value EasingCurve a QEasingCurve
388 \value Uuid a QUuid
389 \value ModelIndex a QModelIndex
390 \value PersistentModelIndex a QPersistentModelIndex (since 5.5)
391 \value Font a QFont
392 \value Hash a QVariantHash
393 \value Icon a QIcon
394 \value Image a QImage
395 \value Int an int
396 \value KeySequence a QKeySequence
397 \value Line a QLine
398 \value LineF a QLineF
399 \value List a QVariantList
400 \value Locale a QLocale
401 \value LongLong a \l qlonglong
402 \value Map a QVariantMap
403 \value Transform a QTransform
404 \value Matrix4x4 a QMatrix4x4
405 \value Palette a QPalette
406 \value Pen a QPen
407 \value Pixmap a QPixmap
408 \value Point a QPoint
409 \value PointF a QPointF
410 \value Polygon a QPolygon
411 \value PolygonF a QPolygonF
412 \value Quaternion a QQuaternion
413 \value Rect a QRect
414 \value RectF a QRectF
415 \value RegularExpression a QRegularExpression
416 \value Region a QRegion
417 \value Size a QSize
418 \value SizeF a QSizeF
419 \value SizePolicy a QSizePolicy
420 \value String a QString
421 \value StringList a QStringList
422 \value TextFormat a QTextFormat
423 \value TextLength a QTextLength
424 \value Time a QTime
425 \value UInt a \l uint
426 \value ULongLong a \l qulonglong
427 \value Url a QUrl
428 \value Vector2D a QVector2D
429 \value Vector3D a QVector3D
430 \value Vector4D a QVector4D
431
432 \value UserType Base value for user-defined types.
433
434 \omitvalue LastGuiType
435 \omitvalue LastCoreType
436 \omitvalue LastType
437*/
438
439/*!
440 \fn QVariant::QVariant(QVariant &&other)
441
442 Move-constructs a QVariant instance, making it point at the same
443 object that \a other was pointing to.
444
445 \since 5.2
446*/
447
448/*!
449 \fn QVariant &QVariant::operator=(QVariant &&other)
450
451 Move-assigns \a other to this QVariant instance.
452
453 \since 5.2
454*/
455
456/*!
457 \fn QVariant::QVariant()
458
459 Constructs an invalid variant.
460*/
461
462/*!
463 \fn QVariant::create(int type, const void *copy)
464
465 \internal
466
467 Constructs a variant private of type \a type, and initializes with \a copy if
468 \a copy is not \nullptr.
469*/
470
471void QVariant::create(int type, const void *copy)
472{
473 d = Private(QMetaType(type));
474 customConstruct(&d, copy);
475}
476
477/*!
478 \fn QVariant::~QVariant()
479
480 Destroys the QVariant and the contained object.
481
482 Note that subclasses that reimplement clear() should reimplement
483 the destructor to call clear(). This destructor calls clear(), but
484 because it is the destructor, QVariant::clear() is called rather
485 than a subclass's clear().
486*/
487
488QVariant::~QVariant()
489{
490 if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared))
491 customClear(&d);
492}
493
494/*!
495 \fn QVariant::QVariant(const QVariant &p)
496
497 Constructs a copy of the variant, \a p, passed as the argument to
498 this constructor.
499*/
500
501QVariant::QVariant(const QVariant &p)
502 : d(p.d)
503{
504 if (d.is_shared) {
505 d.data.shared->ref.ref();
506 return;
507 }
508 QMetaType t = d.type();
509 if (t.isValid())
510 t.construct(&d, p.constData());
511}
512
513/*!
514 \fn QVariant::QVariant(const QString &val)
515
516 Constructs a new variant with a string value, \a val.
517*/
518
519/*!
520 \fn QVariant::QVariant(QLatin1String val)
521
522 Constructs a new variant with a string value, \a val.
523*/
524
525/*!
526 \fn QVariant::QVariant(const char *val)
527
528 Constructs a new variant with a string value of \a val.
529 The variant creates a deep copy of \a val into a QString assuming
530 UTF-8 encoding on the input \a val.
531
532 Note that \a val is converted to a QString for storing in the
533 variant and QVariant::userType() will return QMetaType::QString for
534 the variant.
535
536 You can disable this operator by defining \c
537 QT_NO_CAST_FROM_ASCII when you compile your applications.
538*/
539
540/*!
541 \fn QVariant::QVariant(const QStringList &val)
542
543 Constructs a new variant with a string list value, \a val.
544*/
545
546/*!
547 \fn QVariant::QVariant(const QMap<QString, QVariant> &val)
548
549 Constructs a new variant with a map of \l {QVariant}s, \a val.
550*/
551
552/*!
553 \fn QVariant::QVariant(const QHash<QString, QVariant> &val)
554
555 Constructs a new variant with a hash of \l {QVariant}s, \a val.
556*/
557
558/*!
559 \fn QVariant::QVariant(QDate val)
560
561 Constructs a new variant with a date value, \a val.
562*/
563
564/*!
565 \fn QVariant::QVariant(QTime val)
566
567 Constructs a new variant with a time value, \a val.
568*/
569
570/*!
571 \fn QVariant::QVariant(const QDateTime &val)
572
573 Constructs a new variant with a date/time value, \a val.
574*/
575
576/*!
577 \since 4.7
578 \fn QVariant::QVariant(const QEasingCurve &val)
579
580 Constructs a new variant with an easing curve value, \a val.
581*/
582
583/*!
584 \since 5.0
585 \fn QVariant::QVariant(const QUuid &val)
586
587 Constructs a new variant with an uuid value, \a val.
588*/
589
590/*!
591 \since 5.0
592 \fn QVariant::QVariant(const QModelIndex &val)
593
594 Constructs a new variant with a QModelIndex value, \a val.
595*/
596
597/*!
598 \since 5.5
599 \fn QVariant::QVariant(const QPersistentModelIndex &val)
600
601 Constructs a new variant with a QPersistentModelIndex value, \a val.
602*/
603
604/*!
605 \since 5.0
606 \fn QVariant::QVariant(const QJsonValue &val)
607
608 Constructs a new variant with a json value, \a val.
609*/
610
611/*!
612 \since 5.0
613 \fn QVariant::QVariant(const QJsonObject &val)
614
615 Constructs a new variant with a json object value, \a val.
616*/
617
618/*!
619 \since 5.0
620 \fn QVariant::QVariant(const QJsonArray &val)
621
622 Constructs a new variant with a json array value, \a val.
623*/
624
625/*!
626 \since 5.0
627 \fn QVariant::QVariant(const QJsonDocument &val)
628
629 Constructs a new variant with a json document value, \a val.
630*/
631
632/*!
633 \fn QVariant::QVariant(const QByteArray &val)
634
635 Constructs a new variant with a bytearray value, \a val.
636*/
637
638/*!
639 \fn QVariant::QVariant(const QBitArray &val)
640
641 Constructs a new variant with a bitarray value, \a val.
642*/
643
644/*!
645 \fn QVariant::QVariant(const QPoint &val)
646
647 Constructs a new variant with a point value of \a val.
648 */
649
650/*!
651 \fn QVariant::QVariant(const QPointF &val)
652
653 Constructs a new variant with a point value of \a val.
654 */
655
656/*!
657 \fn QVariant::QVariant(const QRectF &val)
658
659 Constructs a new variant with a rect value of \a val.
660 */
661
662/*!
663 \fn QVariant::QVariant(const QLineF &val)
664
665 Constructs a new variant with a line value of \a val.
666 */
667
668/*!
669 \fn QVariant::QVariant(const QLine &val)
670
671 Constructs a new variant with a line value of \a val.
672 */
673
674/*!
675 \fn QVariant::QVariant(const QRect &val)
676
677 Constructs a new variant with a rect value of \a val.
678 */
679
680/*!
681 \fn QVariant::QVariant(const QSize &val)
682
683 Constructs a new variant with a size value of \a val.
684 */
685
686/*!
687 \fn QVariant::QVariant(const QSizeF &val)
688
689 Constructs a new variant with a size value of \a val.
690 */
691
692/*!
693 \fn QVariant::QVariant(const QUrl &val)
694
695 Constructs a new variant with a url value of \a val.
696 */
697
698/*!
699 \fn QVariant::QVariant(int val)
700
701 Constructs a new variant with an integer value, \a val.
702*/
703
704/*!
705 \fn QVariant::QVariant(uint val)
706
707 Constructs a new variant with an unsigned integer value, \a val.
708*/
709
710/*!
711 \fn QVariant::QVariant(qlonglong val)
712
713 Constructs a new variant with a long long integer value, \a val.
714*/
715
716/*!
717 \fn QVariant::QVariant(qulonglong val)
718
719 Constructs a new variant with an unsigned long long integer value, \a val.
720*/
721
722
723/*!
724 \fn QVariant::QVariant(bool val)
725
726 Constructs a new variant with a boolean value, \a val.
727*/
728
729/*!
730 \fn QVariant::QVariant(double val)
731
732 Constructs a new variant with a floating point value, \a val.
733*/
734
735/*!
736 \fn QVariant::QVariant(float val)
737
738 Constructs a new variant with a floating point value, \a val.
739 \since 4.6
740*/
741
742/*!
743 \fn QVariant::QVariant(const QList<QVariant> &val)
744
745 Constructs a new variant with a list value, \a val.
746*/
747
748/*!
749 \fn QVariant::QVariant(QChar c)
750
751 Constructs a new variant with a char value, \a c.
752*/
753
754/*!
755 \fn QVariant::QVariant(const QLocale &l)
756
757 Constructs a new variant with a locale value, \a l.
758*/
759
760/*!
761 \fn QVariant::QVariant(const QRegularExpression &re)
762
763 \since 5.0
764
765 Constructs a new variant with the regular expression value \a re.
766*/
767
768/*! \fn QVariant::QVariant(Type type)
769 \deprecated
770
771 Constructs an uninitialized variant of type \a type. This will create a
772 variant in a special null state that if accessed will return a default
773 constructed value of the \a type.
774
775 \sa isNull()
776*/
777
778/*!
779 Constructs variant of type \a type, and initializes with
780 \a copy if \a copy is not \nullptr.
781
782 Note that you have to pass the address of the variable you want stored.
783
784 Usually, you never have to use this constructor, use QVariant::fromValue()
785 instead to construct variants from the pointer types represented by
786 \c QMetaType::VoidStar, and \c QMetaType::QObjectStar.
787
788 \sa QVariant::fromValue(), QMetaType::Type
789*/
790QVariant::QVariant(QMetaType type, const void *copy) : d(type)
791{
792 customConstruct(&d, copy);
793}
794
795QVariant::QVariant(int val)
796 : d(QMetaType::Int)
797{ d.set(val); }
798QVariant::QVariant(uint val)
799 : d(QMetaType::UInt)
800{ d.set(val); }
801QVariant::QVariant(qlonglong val)
802 : d(QMetaType::LongLong)
803{ d.set(val); }
804QVariant::QVariant(qulonglong val)
805 : d(QMetaType::ULongLong)
806{ d.set(val); }
807QVariant::QVariant(bool val)
808 : d(QMetaType::Bool)
809{ d.set(val); }
810QVariant::QVariant(double val)
811 : d(QMetaType::Double)
812{ d.set(val); }
813QVariant::QVariant(float val)
814 : d(QMetaType::Float)
815{ d.set(val); }
816
817QVariant::QVariant(const QByteArray &val)
818 : d(QMetaType::QByteArray)
819{ v_construct<QByteArray>(&d, val); }
820QVariant::QVariant(const QBitArray &val)
821 : d(QMetaType::QBitArray)
822{ v_construct<QBitArray>(&d, val); }
823QVariant::QVariant(const QString &val)
824 : d(QMetaType::QString)
825{ v_construct<QString>(&d, val); }
826QVariant::QVariant(QChar val)
827 : d(QMetaType::QChar)
828{ v_construct<QChar>(&d, val); }
829QVariant::QVariant(QLatin1String val)
830 : d(QMetaType::QString)
831{ v_construct<QString>(&d, val); }
832QVariant::QVariant(const QStringList &val)
833 : d(QMetaType::QStringList)
834{ v_construct<QStringList>(&d, val); }
835
836QVariant::QVariant(QDate val)
837 : d(QMetaType::QDate)
838{ v_construct<QDate>(&d, val); }
839QVariant::QVariant(QTime val)
840 : d(QMetaType::QTime)
841{ v_construct<QTime>(&d, val); }
842QVariant::QVariant(const QDateTime &val)
843 : d(QMetaType::QDateTime)
844{ v_construct<QDateTime>(&d, val); }
845#if QT_CONFIG(easingcurve)
846QVariant::QVariant(const QEasingCurve &val)
847 : d(QMetaType::QEasingCurve)
848{ v_construct<QEasingCurve>(&d, val); }
849#endif
850QVariant::QVariant(const QList<QVariant> &list)
851 : d(QMetaType::QVariantList)
852{ v_construct<QVariantList>(&d, list); }
853QVariant::QVariant(const QMap<QString, QVariant> &map)
854 : d(QMetaType::QVariantMap)
855{ v_construct<QVariantMap>(&d, map); }
856QVariant::QVariant(const QHash<QString, QVariant> &hash)
857 : d(QMetaType::QVariantHash)
858{ v_construct<QVariantHash>(&d, hash); }
859#ifndef QT_NO_GEOM_VARIANT
860QVariant::QVariant(const QPoint &pt)
861 : d(QMetaType::QPoint)
862{ v_construct<QPoint>(&d, pt); }
863QVariant::QVariant(const QPointF &pt)
864 : d(QMetaType::QPointF)
865{ v_construct<QPointF>(&d, pt); }
866QVariant::QVariant(const QRectF &r)
867 : d(QMetaType::QRectF)
868{ v_construct<QRectF>(&d, r); }
869QVariant::QVariant(const QLineF &l)
870 : d(QMetaType::QLineF)
871{ v_construct<QLineF>(&d, l); }
872QVariant::QVariant(const QLine &l)
873 : d(QMetaType::QLine)
874{ v_construct<QLine>(&d, l); }
875QVariant::QVariant(const QRect &r)
876 : d(QMetaType::QRect)
877{ v_construct<QRect>(&d, r); }
878QVariant::QVariant(const QSize &s)
879 : d(QMetaType::QSize)
880{ v_construct<QSize>(&d, s); }
881QVariant::QVariant(const QSizeF &s)
882 : d(QMetaType::QSizeF)
883{ v_construct<QSizeF>(&d, s); }
884#endif
885#ifndef QT_BOOTSTRAPPED
886QVariant::QVariant(const QUrl &u)
887 : d(QMetaType::QUrl)
888{ v_construct<QUrl>(&d, u); }
889#endif
890QVariant::QVariant(const QLocale &l)
891 : d(QMetaType::QLocale)
892{ v_construct<QLocale>(&d, l); }
893#if QT_CONFIG(regularexpression)
894QVariant::QVariant(const QRegularExpression &re)
895 : d(QMetaType::QRegularExpression)
896{ v_construct<QRegularExpression>(&d, re); }
897#endif // QT_CONFIG(regularexpression)
898QVariant::QVariant(const QUuid &uuid)
899 : d(QMetaType::QUuid)
900{ v_construct<QUuid>(&d, uuid); }
901#ifndef QT_BOOTSTRAPPED
902QVariant::QVariant(const QJsonValue &jsonValue)
903 : d(QMetaType::QJsonValue)
904{ v_construct<QJsonValue>(&d, jsonValue); }
905QVariant::QVariant(const QJsonObject &jsonObject)
906 : d(QMetaType::QJsonObject)
907{ v_construct<QJsonObject>(&d, jsonObject); }
908QVariant::QVariant(const QJsonArray &jsonArray)
909 : d(QMetaType::QJsonArray)
910{ v_construct<QJsonArray>(&d, jsonArray); }
911QVariant::QVariant(const QJsonDocument &jsonDocument)
912 : d(QMetaType::QJsonDocument)
913{ v_construct<QJsonDocument>(&d, jsonDocument); }
914#endif // QT_BOOTSTRAPPED
915#if QT_CONFIG(itemmodel)
916QVariant::QVariant(const QModelIndex &modelIndex)
917 : d(QMetaType::QModelIndex)
918{ v_construct<QModelIndex>(&d, modelIndex); }
919QVariant::QVariant(const QPersistentModelIndex &modelIndex)
920 : d(QMetaType::QPersistentModelIndex)
921{ v_construct<QPersistentModelIndex>(&d, modelIndex); }
922#endif
923
924/*! \fn QVariant::Type QVariant::type() const
925 \deprecated
926
927 Returns the storage type of the value stored in the variant.
928 Although this function is declared as returning QVariant::Type,
929 the return value should be interpreted as QMetaType::Type. In
930 particular, QVariant::UserType is returned here only if the value
931 is equal or greater than QMetaType::User.
932
933 Note that return values in the ranges QVariant::Char through
934 QVariant::RegExp and QVariant::Font through QVariant::Transform
935 correspond to the values in the ranges QMetaType::QChar through
936 QMetaType::QRegularExpression and QMetaType::QFont through QMetaType::QQuaternion.
937
938 Pay particular attention when working with char and QChar
939 variants. Note that there is no QVariant constructor specifically
940 for type char, but there is one for QChar. For a variant of type
941 QChar, this function returns QVariant::Char, which is the same as
942 QMetaType::QChar, but for a variant of type \c char, this function
943 returns QMetaType::Char, which is \e not the same as
944 QVariant::Char.
945
946 Also note that the types \c void*, \c long, \c short, \c unsigned
947 \c long, \c unsigned \c short, \c unsigned \c char, \c float, \c
948 QObject*, and \c QWidget* are represented in QMetaType::Type but
949 not in QVariant::Type, and they can be returned by this function.
950 However, they are considered to be user defined types when tested
951 against QVariant::Type.
952
953 To test whether an instance of QVariant contains a data type that
954 is compatible with the data type you are interested in, use
955 canConvert().
956
957 \sa userType(), metaType()
958*/
959
960/*! \fn int QVariant::userType() const
961 \fn int QVariant::typeId() const
962
963 Returns the storage type of the value stored in the variant. This is
964 the same as metaType().id().
965
966 \sa type(), metaType()
967*/
968
969/*!
970 \since 6.0
971
972 Returns the QMetaType of the value stored in the variant.
973*/
974QMetaType QVariant::metaType() const
975{
976 return d.type();
977}
978
979/*!
980 Assigns the value of the variant \a variant to this variant.
981*/
982QVariant &QVariant::operator=(const QVariant &variant)
983{
984 if (this == &variant)
985 return *this;
986
987 clear();
988 if (variant.d.is_shared) {
989 variant.d.data.shared->ref.ref();
990 d = variant.d;
991 } else {
992 d = variant.d;
993 QMetaType t = d.type();
994 if (t.isValid())
995 t.construct(&d, variant.constData());
996 }
997
998 return *this;
999}
1000
1001/*!
1002 \fn void QVariant::swap(QVariant &other)
1003 \since 4.8
1004
1005 Swaps variant \a other with this variant. This operation is very
1006 fast and never fails.
1007*/
1008
1009/*!
1010 \fn void QVariant::detach()
1011
1012 \internal
1013*/
1014
1015void QVariant::detach()
1016{
1017 if (!d.is_shared || d.data.shared->ref.loadRelaxed() == 1)
1018 return;
1019
1020 Private dd(d.type());
1021 customConstruct(&dd, constData());
1022 if (!d.data.shared->ref.deref())
1023 customClear(&d);
1024 d.data.shared = dd.data.shared;
1025}
1026
1027/*!
1028 \fn bool QVariant::isDetached() const
1029
1030 \internal
1031*/
1032
1033/*!
1034 Returns the name of the type stored in the variant. The returned
1035 strings describe the C++ datatype used to store the data: for
1036 example, "QFont", "QString", or "QVariantList". An Invalid
1037 variant returns 0.
1038*/
1039const char *QVariant::typeName() const
1040{
1041 return d.type().name();
1042}
1043
1044/*!
1045 Convert this variant to type QMetaType::UnknownType and free up any resources
1046 used.
1047*/
1048void QVariant::clear()
1049{
1050 if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared))
1051 customClear(&d);
1052 d = {};
1053}
1054
1055/*!
1056 \fn const char *QVariant::typeToName(int typeId)
1057 \deprecated Use QMetaType instead
1058
1059 Converts the int representation of the storage type, \a typeId, to
1060 its string representation.
1061
1062 Returns \nullptr if the type is QMetaType::UnknownType or doesn't exist.
1063*/
1064
1065/*!
1066 \fn QVariant::Type QVariant::nameToType(const char *name)
1067 \deprecated Use QMetaType instead
1068
1069 Converts the string representation of the storage type given in \a
1070 name, to its enum representation.
1071
1072 If the string representation cannot be converted to any enum
1073 representation, the variant is set to \c Invalid.
1074*/
1075
1076#ifndef QT_NO_DATASTREAM
1077enum { MapFromThreeCount = 36 };
1078static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] =
1079{
1080 QMetaType::UnknownType,
1081 QMetaType::QVariantMap,
1082 QMetaType::QVariantList,
1083 QMetaType::QString,
1084 QMetaType::QStringList,
1085 QMetaType::QFont,
1086 QMetaType::QPixmap,
1087 QMetaType::QBrush,
1088 QMetaType::QRect,
1089 QMetaType::QSize,
1090 QMetaType::QColor,
1091 QMetaType::QPalette,
1092 0, // ColorGroup
1093 QMetaType::QIcon,
1094 QMetaType::QPoint,
1095 QMetaType::QImage,
1096 QMetaType::Int,
1097 QMetaType::UInt,
1098 QMetaType::Bool,
1099 QMetaType::Double,
1100 0, // Buggy ByteArray, QByteArray never had id == 20
1101 QMetaType::QPolygon,
1102 QMetaType::QRegion,
1103 QMetaType::QBitmap,
1104 QMetaType::QCursor,
1105 QMetaType::QSizePolicy,
1106 QMetaType::QDate,
1107 QMetaType::QTime,
1108 QMetaType::QDateTime,
1109 QMetaType::QByteArray,
1110 QMetaType::QBitArray,
1111#if QT_CONFIG(shortcut)
1112 QMetaType::QKeySequence,
1113#else
1114 0, // QKeySequence
1115#endif
1116 QMetaType::QPen,
1117 QMetaType::LongLong,
1118 QMetaType::ULongLong,
1119#if QT_CONFIG(easingcurve)
1120 QMetaType::QEasingCurve
1121#endif
1122};
1123
1124// enum values needed to map Qt5 based type id's to Qt6 based ones
1125enum Qt5Types {
1126 Qt5UserType = 1024,
1127 Qt5LastCoreType = QMetaType::QCborMap,
1128 Qt5FirstGuiType = 64,
1129 Qt5LastGuiType = 87,
1130 Qt5SizePolicy = 121,
1131 Qt5RegExp = 27,
1132 Qt5KeySequence = 75,
1133 Qt5QQuaternion = 85
1134};
1135
1136/*!
1137 Internal function for loading a variant from stream \a s. Use the
1138 stream operators instead.
1139
1140 \internal
1141*/
1142void QVariant::load(QDataStream &s)
1143{
1144 clear();
1145
1146 quint32 typeId;
1147 s >> typeId;
1148 if (s.version() < QDataStream::Qt_4_0) {
1149 // map to Qt 5 ids
1150 if (typeId >= MapFromThreeCount)
1151 return;
1152 typeId = mapIdFromQt3ToCurrent[typeId];
1153 } else if (s.version() < QDataStream::Qt_5_0) {
1154 // map to Qt 5 type ids
1155 if (typeId == 127 /* QVariant::UserType */) {
1156 typeId = Qt5UserType;
1157 } else if (typeId >= 128 && typeId != Qt5UserType) {
1158 // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
1159 // by moving all ids down by 97.
1160 typeId -= 97;
1161 } else if (typeId == 75 /* QSizePolicy */) {
1162 typeId = Qt5SizePolicy;
1163 } else if (typeId > 75 && typeId <= 86) {
1164 // and as a result these types received lower ids too
1165 // QKeySequence QPen QTextLength QTextFormat QTransform QMatrix4x4 QVector2D QVector3D QVector4D QQuaternion
1166 typeId -=1;
1167 }
1168 }
1169 if (s.version() < QDataStream::Qt_6_0) {
1170 // map from Qt 5 to Qt 6 values
1171 if (typeId == Qt5UserType) {
1172 typeId = QMetaType::User;
1173 } else if (typeId >= Qt5FirstGuiType && typeId <= Qt5LastGuiType) {
1174 typeId += QMetaType::FirstGuiType - Qt5FirstGuiType;
1175 } else if (typeId == Qt5SizePolicy) {
1176 typeId = QMetaType::QSizePolicy;
1177 } else if (typeId == Qt5RegExp) {
1178 typeId = QMetaType::fromName("QRegExp").id();
1179 }
1180 }
1181
1182 qint8 is_null = false;
1183 if (s.version() >= QDataStream::Qt_4_2)
1184 s >> is_null;
1185 if (typeId == QMetaType::User) {
1186 QByteArray name;
1187 s >> name;
1188 typeId = QMetaType::fromName(name).id();
1189 if (typeId == QMetaType::UnknownType) {
1190 s.setStatus(QDataStream::ReadCorruptData);
1191 qWarning("QVariant::load: unknown user type with name %s.", name.constData());
1192 return;
1193 }
1194 }
1195 create(typeId, nullptr);
1196 d.is_null = is_null;
1197
1198 if (!isValid()) {
1199 if (s.version() < QDataStream::Qt_5_0) {
1200 // Since we wrote something, we should read something
1201 QString x;
1202 s >> x;
1203 }
1204 d.is_null = true;
1205 return;
1206 }
1207
1208 // const cast is safe since we operate on a newly constructed variant
1209 void *data = const_cast<void *>(constData());
1210 if (!d.type().load(s, data)) {
1211 s.setStatus(QDataStream::ReadCorruptData);
1212 qWarning("QVariant::load: unable to load type %d.", d.typeId());
1213 }
1214}
1215
1216/*!
1217 Internal function for saving a variant to the stream \a s. Use the
1218 stream operators instead.
1219
1220 \internal
1221*/
1222void QVariant::save(QDataStream &s) const
1223{
1224 quint32 typeId = d.typeId();
1225 bool saveAsUserType = false;
1226 if (typeId >= QMetaType::User) {
1227 typeId = QMetaType::User;
1228 saveAsUserType = true;
1229 }
1230 if (s.version() < QDataStream::Qt_6_0) {
1231 // map to Qt 5 values
1232 if (typeId == QMetaType::User) {
1233 typeId = Qt5UserType;
1234 if (!strcmp(d.type().name(), "QRegExp")) {
1235 typeId = 27; // QRegExp in Qt 4/5
1236 }
1237 } else if (typeId > Qt5LastCoreType && typeId <= QMetaType::LastCoreType) {
1238 // the type didn't exist in Qt 5
1239 typeId = Qt5UserType;
1240 saveAsUserType = true;
1241 } else if (typeId >= QMetaType::FirstGuiType && typeId <= QMetaType::LastGuiType) {
1242 typeId -= QMetaType::FirstGuiType - Qt5FirstGuiType;
1243 if (typeId > Qt5LastGuiType) {
1244 typeId = Qt5UserType;
1245 saveAsUserType = true;
1246 }
1247 } else if (typeId == QMetaType::QSizePolicy) {
1248 typeId = Qt5SizePolicy;
1249 }
1250 }
1251 if (s.version() < QDataStream::Qt_4_0) {
1252 int i;
1253 for (i = 0; i <= MapFromThreeCount - 1; ++i) {
1254 if (mapIdFromQt3ToCurrent[i] == typeId) {
1255 typeId = i;
1256 break;
1257 }
1258 }
1259 if (i >= MapFromThreeCount) {
1260 s << QVariant();
1261 return;
1262 }
1263 } else if (s.version() < QDataStream::Qt_5_0) {
1264 if (typeId == Qt5UserType) {
1265 typeId = 127; // QVariant::UserType had this value in Qt4
1266 saveAsUserType = true;
1267 } else if (typeId >= 128 - 97 && typeId <= Qt5LastCoreType) {
1268 // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
1269 // by moving all ids down by 97.
1270 typeId += 97;
1271 } else if (typeId == Qt5SizePolicy) {
1272 typeId = 75;
1273 } else if (typeId >= Qt5KeySequence && typeId <= Qt5QQuaternion) {
1274 // and as a result these types received lower ids too
1275 typeId += 1;
1276 } else if (typeId > Qt5QQuaternion || typeId == QMetaType::QUuid) {
1277 // These existed in Qt 4 only as a custom type
1278 typeId = 127;
1279 saveAsUserType = true;
1280 }
1281 }
1282 const char *typeName = nullptr;
1283 if (saveAsUserType)
1284 typeName = d.type().name();
1285 s << typeId;
1286 if (s.version() >= QDataStream::Qt_4_2)
1287 s << qint8(d.is_null);
1288 if (typeName)
1289 s << d.type().name();
1290
1291 if (!isValid()) {
1292 if (s.version() < QDataStream::Qt_5_0)
1293 s << QString();
1294 return;
1295 }
1296
1297 if (!d.type().save(s, constData())) {
1298 qWarning("QVariant::save: unable to save type '%s' (type id: %d).\n",
1299 d.type().name(), d.typeId());
1300 Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
1301 }
1302}
1303
1304/*!
1305 \since 4.4
1306
1307 Reads a variant \a p from the stream \a s.
1308
1309 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
1310*/
1311QDataStream &operator>>(QDataStream &s, QVariant &p)
1312{
1313 p.load(s);
1314 return s;
1315}
1316
1317/*!
1318 Writes a variant \a p to the stream \a s.
1319
1320 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
1321*/
1322QDataStream &operator<<(QDataStream &s, const QVariant &p)
1323{
1324 p.save(s);
1325 return s;
1326}
1327
1328/*! \fn QDataStream& operator>>(QDataStream &s, QVariant::Type &p)
1329 \deprecated
1330
1331 Reads a variant type \a p in enum representation from the stream \a s.
1332*/
1333
1334/*! \fn QDataStream& operator<<(QDataStream &s, const QVariant::Type p)
1335 \deprecated
1336
1337 Writes a variant type \a p to the stream \a s.
1338*/
1339#endif //QT_NO_DATASTREAM
1340
1341/*!
1342 \fn bool QVariant::isValid() const
1343
1344 Returns \c true if the storage type of this variant is not
1345 QMetaType::UnknownType; otherwise returns \c false.
1346*/
1347
1348/*!
1349 \fn QStringList QVariant::toStringList() const
1350
1351 Returns the variant as a QStringList if the variant has userType()
1352 \l QMetaType::QStringList, \l QMetaType::QString, or
1353 \l QMetaType::QVariantList of a type that can be converted to QString;
1354 otherwise returns an empty list.
1355
1356 \sa canConvert(int targetTypeId), convert()
1357*/
1358QStringList QVariant::toStringList() const
1359{
1360 return qvariant_cast<QStringList>(*this);
1361}
1362
1363/*!
1364 Returns the variant as a QString if the variant has a userType()
1365 including, but not limited to:
1366
1367 \l QMetaType::QString, \l QMetaType::Bool, \l QMetaType::QByteArray,
1368 \l QMetaType::QChar, \l QMetaType::QDate, \l QMetaType::QDateTime,
1369 \l QMetaType::Double, \l QMetaType::Int, \l QMetaType::LongLong,
1370 \l QMetaType::QStringList, \l QMetaType::QTime, \l QMetaType::UInt, or
1371 \l QMetaType::ULongLong.
1372
1373 Calling QVariant::toString() on an unsupported variant returns an empty
1374 string.
1375
1376 \sa canConvert(int targetTypeId), convert()
1377*/
1378QString QVariant::toString() const
1379{
1380 return qvariant_cast<QString>(*this);
1381}
1382
1383/*!
1384 Returns the variant as a QMap<QString, QVariant> if the variant
1385 has type() \l QMetaType::QVariantMap; otherwise returns an empty map.
1386
1387 \sa canConvert(int targetTypeId), convert()
1388*/
1389QVariantMap QVariant::toMap() const
1390{
1391 return qvariant_cast<QVariantMap>(*this);
1392}
1393
1394/*!
1395 Returns the variant as a QHash<QString, QVariant> if the variant
1396 has type() \l QMetaType::QVariantHash; otherwise returns an empty map.
1397
1398 \sa canConvert(int targetTypeId), convert()
1399*/
1400QVariantHash QVariant::toHash() const
1401{
1402 return qvariant_cast<QVariantHash>(*this);
1403}
1404
1405/*!
1406 \fn QDate QVariant::toDate() const
1407
1408 Returns the variant as a QDate if the variant has userType()
1409 \l QMetaType::QDate, \l QMetaType::QDateTime, or \l QMetaType::QString;
1410 otherwise returns an invalid date.
1411
1412 If the type() is \l QMetaType::QString, an invalid date will be returned if
1413 the string cannot be parsed as a Qt::ISODate format date.
1414
1415 \sa canConvert(int targetTypeId), convert()
1416*/
1417QDate QVariant::toDate() const
1418{
1419 return qvariant_cast<QDate>(*this);
1420}
1421
1422/*!
1423 \fn QTime QVariant::toTime() const
1424
1425 Returns the variant as a QTime if the variant has userType()
1426 \l QMetaType::QTime, \l QMetaType::QDateTime, or \l QMetaType::QString;
1427 otherwise returns an invalid time.
1428
1429 If the type() is \l QMetaType::QString, an invalid time will be returned if
1430 the string cannot be parsed as a Qt::ISODate format time.
1431
1432 \sa canConvert(int targetTypeId), convert()
1433*/
1434QTime QVariant::toTime() const
1435{
1436 return qvariant_cast<QTime>(*this);
1437}
1438
1439/*!
1440 \fn QDateTime QVariant::toDateTime() const
1441
1442 Returns the variant as a QDateTime if the variant has userType()
1443 \l QMetaType::QDateTime, \l QMetaType::QDate, or \l QMetaType::QString;
1444 otherwise returns an invalid date/time.
1445
1446 If the type() is \l QMetaType::QString, an invalid date/time will be
1447 returned if the string cannot be parsed as a Qt::ISODate format date/time.
1448
1449 \sa canConvert(int targetTypeId), convert()
1450*/
1451QDateTime QVariant::toDateTime() const
1452{
1453 return qvariant_cast<QDateTime>(*this);
1454}
1455
1456/*!
1457 \since 4.7
1458 \fn QEasingCurve QVariant::toEasingCurve() const
1459
1460 Returns the variant as a QEasingCurve if the variant has userType()
1461 \l QMetaType::QEasingCurve; otherwise returns a default easing curve.
1462
1463 \sa canConvert(int targetTypeId), convert()
1464*/
1465#if QT_CONFIG(easingcurve)
1466QEasingCurve QVariant::toEasingCurve() const
1467{
1468 return qvariant_cast<QEasingCurve>(*this);
1469}
1470#endif
1471
1472/*!
1473 \fn QByteArray QVariant::toByteArray() const
1474
1475 Returns the variant as a QByteArray if the variant has userType()
1476 \l QMetaType::QByteArray or \l QMetaType::QString (converted using
1477 QString::fromUtf8()); otherwise returns an empty byte array.
1478
1479 \sa canConvert(int targetTypeId), convert()
1480*/
1481QByteArray QVariant::toByteArray() const
1482{
1483 return qvariant_cast<QByteArray>(*this);
1484}
1485
1486#ifndef QT_NO_GEOM_VARIANT
1487/*!
1488 \fn QPoint QVariant::toPoint() const
1489
1490 Returns the variant as a QPoint if the variant has userType()
1491 \l QMetaType::QPoint or \l QMetaType::QPointF; otherwise returns a null
1492 QPoint.
1493
1494 \sa canConvert(int targetTypeId), convert()
1495*/
1496QPoint QVariant::toPoint() const
1497{
1498 return qvariant_cast<QPoint>(*this);
1499}
1500
1501/*!
1502 \fn QRect QVariant::toRect() const
1503
1504 Returns the variant as a QRect if the variant has userType()
1505 \l QMetaType::QRect; otherwise returns an invalid QRect.
1506
1507 \sa canConvert(int targetTypeId), convert()
1508*/
1509QRect QVariant::toRect() const
1510{
1511 return qvariant_cast<QRect>(*this);
1512}
1513
1514/*!
1515 \fn QSize QVariant::toSize() const
1516
1517 Returns the variant as a QSize if the variant has userType()
1518 \l QMetaType::QSize; otherwise returns an invalid QSize.
1519
1520 \sa canConvert(int targetTypeId), convert()
1521*/
1522QSize QVariant::toSize() const
1523{
1524 return qvariant_cast<QSize>(*this);
1525}
1526
1527/*!
1528 \fn QSizeF QVariant::toSizeF() const
1529
1530 Returns the variant as a QSizeF if the variant has userType() \l
1531 QMetaType::QSizeF; otherwise returns an invalid QSizeF.
1532
1533 \sa canConvert(int targetTypeId), convert()
1534*/
1535QSizeF QVariant::toSizeF() const
1536{
1537 return qvariant_cast<QSizeF>(*this);
1538}
1539
1540/*!
1541 \fn QRectF QVariant::toRectF() const
1542
1543 Returns the variant as a QRectF if the variant has userType()
1544 \l QMetaType::QRect or \l QMetaType::QRectF; otherwise returns an invalid
1545 QRectF.
1546
1547 \sa canConvert(int targetTypeId), convert()
1548*/
1549QRectF QVariant::toRectF() const
1550{
1551 return qvariant_cast<QRectF>(*this);
1552}
1553
1554/*!
1555 \fn QLineF QVariant::toLineF() const
1556
1557 Returns the variant as a QLineF if the variant has userType()
1558 \l QMetaType::QLineF; otherwise returns an invalid QLineF.
1559
1560 \sa canConvert(int targetTypeId), convert()
1561*/
1562QLineF QVariant::toLineF() const
1563{
1564 return qvariant_cast<QLineF>(*this);
1565}
1566
1567/*!
1568 \fn QLine QVariant::toLine() const
1569
1570 Returns the variant as a QLine if the variant has userType()
1571 \l QMetaType::QLine; otherwise returns an invalid QLine.
1572
1573 \sa canConvert(int targetTypeId), convert()
1574*/
1575QLine QVariant::toLine() const
1576{
1577 return qvariant_cast<QLine>(*this);
1578}
1579
1580/*!
1581 \fn QPointF QVariant::toPointF() const
1582
1583 Returns the variant as a QPointF if the variant has userType() \l
1584 QMetaType::QPoint or \l QMetaType::QPointF; otherwise returns a null
1585 QPointF.
1586
1587 \sa canConvert(int targetTypeId), convert()
1588*/
1589QPointF QVariant::toPointF() const
1590{
1591 return qvariant_cast<QPointF>(*this);
1592}
1593
1594#endif // QT_NO_GEOM_VARIANT
1595
1596#ifndef QT_BOOTSTRAPPED
1597/*!
1598 \fn QUrl QVariant::toUrl() const
1599
1600 Returns the variant as a QUrl if the variant has userType()
1601 \l QMetaType::QUrl; otherwise returns an invalid QUrl.
1602
1603 \sa canConvert(int targetTypeId), convert()
1604*/
1605QUrl QVariant::toUrl() const
1606{
1607 return qvariant_cast<QUrl>(*this);
1608}
1609#endif
1610
1611/*!
1612 \fn QLocale QVariant::toLocale() const
1613
1614 Returns the variant as a QLocale if the variant has userType()
1615 \l QMetaType::QLocale; otherwise returns an invalid QLocale.
1616
1617 \sa canConvert(int targetTypeId), convert()
1618*/
1619QLocale QVariant::toLocale() const
1620{
1621 return qvariant_cast<QLocale>(*this);
1622}
1623
1624#if QT_CONFIG(regularexpression)
1625/*!
1626 \fn QRegularExpression QVariant::toRegularExpression() const
1627 \since 5.0
1628
1629 Returns the variant as a QRegularExpression if the variant has userType() \l
1630 QRegularExpression; otherwise returns an empty QRegularExpression.
1631
1632 \sa canConvert(int targetTypeId), convert()
1633*/
1634QRegularExpression QVariant::toRegularExpression() const
1635{
1636 return qvariant_cast<QRegularExpression>(*this);
1637}
1638#endif // QT_CONFIG(regularexpression)
1639
1640#if QT_CONFIG(itemmodel)
1641/*!
1642 \since 5.0
1643
1644 Returns the variant as a QModelIndex if the variant has userType() \l
1645 QModelIndex; otherwise returns a default constructed QModelIndex.
1646
1647 \sa canConvert(int targetTypeId), convert(), toPersistentModelIndex()
1648*/
1649QModelIndex QVariant::toModelIndex() const
1650{
1651 return qvariant_cast<QModelIndex>(*this);
1652}
1653
1654/*!
1655 \since 5.5
1656
1657 Returns the variant as a QPersistentModelIndex if the variant has userType() \l
1658 QPersistentModelIndex; otherwise returns a default constructed QPersistentModelIndex.
1659
1660 \sa canConvert(int targetTypeId), convert(), toModelIndex()
1661*/
1662QPersistentModelIndex QVariant::toPersistentModelIndex() const
1663{
1664 return qvariant_cast<QPersistentModelIndex>(*this);
1665}
1666#endif // QT_CONFIG(itemmodel)
1667
1668/*!
1669 \since 5.0
1670
1671 Returns the variant as a QUuid if the variant has type()
1672 \l QMetaType::QUuid, \l QMetaType::QByteArray or \l QMetaType::QString;
1673 otherwise returns a default-constructed QUuid.
1674
1675 \sa canConvert(int targetTypeId), convert()
1676*/
1677QUuid QVariant::toUuid() const
1678{
1679 return qvariant_cast<QUuid>(*this);
1680}
1681
1682#ifndef QT_BOOTSTRAPPED
1683/*!
1684 \since 5.0
1685
1686 Returns the variant as a QJsonValue if the variant has userType() \l
1687 QJsonValue; otherwise returns a default constructed QJsonValue.
1688
1689 \sa canConvert(int targetTypeId), convert()
1690*/
1691QJsonValue QVariant::toJsonValue() const
1692{
1693 return qvariant_cast<QJsonValue>(*this);
1694}
1695
1696/*!
1697 \since 5.0
1698
1699 Returns the variant as a QJsonObject if the variant has userType() \l
1700 QJsonObject; otherwise returns a default constructed QJsonObject.
1701
1702 \sa canConvert(int targetTypeId), convert()
1703*/
1704QJsonObject QVariant::toJsonObject() const
1705{
1706 return qvariant_cast<QJsonObject>(*this);
1707}
1708
1709/*!
1710 \since 5.0
1711
1712 Returns the variant as a QJsonArray if the variant has userType() \l
1713 QJsonArray; otherwise returns a default constructed QJsonArray.
1714
1715 \sa canConvert(int targetTypeId), convert()
1716*/
1717QJsonArray QVariant::toJsonArray() const
1718{
1719 return qvariant_cast<QJsonArray>(*this);
1720}
1721
1722/*!
1723 \since 5.0
1724
1725 Returns the variant as a QJsonDocument if the variant has userType() \l
1726 QJsonDocument; otherwise returns a default constructed QJsonDocument.
1727
1728 \sa canConvert(int targetTypeId), convert()
1729*/
1730QJsonDocument QVariant::toJsonDocument() const
1731{
1732 return qvariant_cast<QJsonDocument>(*this);
1733}
1734#endif // QT_BOOTSTRAPPED
1735
1736/*!
1737 \fn QChar QVariant::toChar() const
1738
1739 Returns the variant as a QChar if the variant has userType()
1740 \l QMetaType::QChar, \l QMetaType::Int, or \l QMetaType::UInt; otherwise
1741 returns an invalid QChar.
1742
1743 \sa canConvert(int targetTypeId), convert()
1744*/
1745QChar QVariant::toChar() const
1746{
1747 return qvariant_cast<QChar>(*this);
1748}
1749
1750/*!
1751 Returns the variant as a QBitArray if the variant has userType()
1752 \l QMetaType::QBitArray; otherwise returns an empty bit array.
1753
1754 \sa canConvert(int targetTypeId), convert()
1755*/
1756QBitArray QVariant::toBitArray() const
1757{
1758 return qvariant_cast<QBitArray>(*this);
1759}
1760
1761template <typename T>
1762inline T qNumVariantToHelper(const QVariant::Private &d, bool *ok, const T& val)
1763{
1764 QMetaType t = QMetaType::fromType<T>();
1765 if (ok)
1766 *ok = true;
1767
1768 if (d.type() == t)
1769 return val;
1770
1771 T ret = 0;
1772 bool success = QMetaType::convert(d.type(), d.storage(), t, &ret);
1773 if (ok)
1774 *ok = success;
1775 return ret;
1776}
1777
1778/*!
1779 Returns the variant as an int if the variant has userType()
1780 \l QMetaType::Int, \l QMetaType::Bool, \l QMetaType::QByteArray,
1781 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::LongLong,
1782 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
1783 otherwise returns 0.
1784
1785 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1786 converted to an int; otherwise \c{*}\a{ok} is set to false.
1787
1788 \b{Warning:} If the value is convertible to a \l QMetaType::LongLong but is
1789 too large to be represented in an int, the resulting arithmetic overflow
1790 will not be reflected in \a ok. A simple workaround is to use
1791 QString::toInt().
1792
1793 \sa canConvert(int targetTypeId), convert()
1794*/
1795int QVariant::toInt(bool *ok) const
1796{
1797 return qNumVariantToHelper<int>(d, ok, d.get<int>());
1798}
1799
1800/*!
1801 Returns the variant as an unsigned int if the variant has userType()
1802 \l QMetaType::UInt, \l QMetaType::Bool, \l QMetaType::QByteArray,
1803 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
1804 \l QMetaType::LongLong, \l QMetaType::QString, or \l QMetaType::ULongLong;
1805 otherwise returns 0.
1806
1807 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1808 converted to an unsigned int; otherwise \c{*}\a{ok} is set to false.
1809
1810 \b{Warning:} If the value is convertible to a \l QMetaType::ULongLong but is
1811 too large to be represented in an unsigned int, the resulting arithmetic
1812 overflow will not be reflected in \a ok. A simple workaround is to use
1813 QString::toUInt().
1814
1815 \sa canConvert(int targetTypeId), convert()
1816*/
1817uint QVariant::toUInt(bool *ok) const
1818{
1819 return qNumVariantToHelper<uint>(d, ok, d.get<unsigned int>());
1820}
1821
1822/*!
1823 Returns the variant as a long long int if the variant has userType()
1824 \l QMetaType::LongLong, \l QMetaType::Bool, \l QMetaType::QByteArray,
1825 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
1826 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
1827 otherwise returns 0.
1828
1829 If \a ok is non-null: \c{*}\c{ok} is set to true if the value could be
1830 converted to an int; otherwise \c{*}\c{ok} is set to false.
1831
1832 \sa canConvert(int targetTypeId), convert()
1833*/
1834qlonglong QVariant::toLongLong(bool *ok) const
1835{
1836 return qNumVariantToHelper<qlonglong>(d, ok, d.get<qlonglong>());
1837}
1838
1839/*!
1840 Returns the variant as an unsigned long long int if the
1841 variant has type() \l QMetaType::ULongLong, \l QMetaType::Bool,
1842 \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::Double,
1843 \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString, or
1844 \l QMetaType::UInt; otherwise returns 0.
1845
1846 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1847 converted to an int; otherwise \c{*}\a{ok} is set to false.
1848
1849 \sa canConvert(int targetTypeId), convert()
1850*/
1851qulonglong QVariant::toULongLong(bool *ok) const
1852{
1853 return qNumVariantToHelper<qulonglong>(d, ok, d.get<qulonglong>());
1854}
1855
1856/*!
1857 Returns the variant as a bool if the variant has userType() Bool.
1858
1859 Returns \c true if the variant has userType() \l QMetaType::Bool,
1860 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
1861 \l QMetaType::LongLong, \l QMetaType::UInt, or \l QMetaType::ULongLong and
1862 the value is non-zero, or if the variant has type \l QMetaType::QString or
1863 \l QMetaType::QByteArray and its lower-case content is not one of the
1864 following: empty, "0" or "false"; otherwise returns \c false.
1865
1866 \sa canConvert(int targetTypeId), convert()
1867*/
1868bool QVariant::toBool() const
1869{
1870 auto boolType = QMetaType::fromType<bool>();
1871 if (d.type() == boolType)
1872 return d.get<bool>();
1873
1874 bool res = false;
1875 QMetaType::convert(d.type(), constData(), boolType, &res);
1876 return res;
1877}
1878
1879/*!
1880 Returns the variant as a double if the variant has userType()
1881 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
1882 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
1883 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
1884 otherwise returns 0.0.
1885
1886 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1887 converted to a double; otherwise \c{*}\a{ok} is set to false.
1888
1889 \sa canConvert(int targetTypeId), convert()
1890*/
1891double QVariant::toDouble(bool *ok) const
1892{
1893 return qNumVariantToHelper<double>(d, ok, d.get<double>());
1894}
1895
1896/*!
1897 Returns the variant as a float if the variant has userType()
1898 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
1899 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
1900 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
1901 otherwise returns 0.0.
1902
1903 \since 4.6
1904
1905 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1906 converted to a double; otherwise \c{*}\a{ok} is set to false.
1907
1908 \sa canConvert(int targetTypeId), convert()
1909*/
1910float QVariant::toFloat(bool *ok) const
1911{
1912 return qNumVariantToHelper<float>(d, ok, d.get<float>());
1913}
1914
1915/*!
1916 Returns the variant as a qreal if the variant has userType()
1917 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
1918 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
1919 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
1920 otherwise returns 0.0.
1921
1922 \since 4.6
1923
1924 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1925 converted to a double; otherwise \c{*}\a{ok} is set to false.
1926
1927 \sa canConvert(int targetTypeId), convert()
1928*/
1929qreal QVariant::toReal(bool *ok) const
1930{
1931 return qNumVariantToHelper<qreal>(d, ok, d.get<qreal>());
1932}
1933
1934/*!
1935 Returns the variant as a QVariantList if the variant has userType()
1936 \l QMetaType::QVariantList or \l QMetaType::QStringList; otherwise returns
1937 an empty list.
1938
1939 \sa canConvert(int targetTypeId), convert()
1940*/
1941QVariantList QVariant::toList() const
1942{
1943 return qvariant_cast<QVariantList>(*this);
1944}
1945
1946/*!
1947 \fn bool QVariant::canConvert(int targetTypeId) const
1948 \overload
1949 \obsolete
1950
1951 \sa QMetaType::canConvert()
1952*/
1953
1954/*!
1955 \fn bool QVariant::canConvert(QMetaType type) const
1956 \since 6.0
1957
1958 Returns \c true if the variant's type can be cast to the requested
1959 type, \a type. Such casting is done automatically when calling the
1960 toInt(), toBool(), ... methods.
1961
1962 \sa QMetaType::canConvert()
1963*/
1964
1965
1966/*!
1967 \fn bool QVariant::convert(int targetTypeId)
1968 \obsolete
1969
1970 Casts the variant to the requested type, \a targetTypeId. If the cast cannot be
1971 done, the variant is still changed to the requested type, but is left in a cleared
1972 null state similar to that constructed by QVariant(Type).
1973
1974 Returns \c true if the current type of the variant was successfully cast;
1975 otherwise returns \c false.
1976
1977 A QVariant containing a pointer to a type derived from QObject will also convert
1978 and return true for this function if a qobject_cast to the type described
1979 by \a targetTypeId would succeed. Note that this only works for QObject subclasses
1980 which use the Q_OBJECT macro.
1981
1982 \note converting QVariants that are null due to not being initialized or having
1983 failed a previous conversion will always fail, changing the type, remaining null,
1984 and returning \c false.
1985
1986 \sa canConvert(int targetTypeId), clear()
1987*/
1988
1989/*!
1990 Casts the variant to the requested type, \a targetType. If the cast cannot be
1991 done, the variant is still changed to the requested type, but is left in a cleared
1992 null state similar to that constructed by QVariant(Type).
1993
1994 Returns \c true if the current type of the variant was successfully cast;
1995 otherwise returns \c false.
1996
1997 A QVariant containing a pointer to a type derived from QObject will also convert
1998 and return true for this function if a qobject_cast to the type described
1999 by \a targetType would succeed. Note that this only works for QObject subclasses
2000 which use the Q_OBJECT macro.
2001
2002 \note converting QVariants that are null due to not being initialized or having
2003 failed a previous conversion will always fail, changing the type, remaining null,
2004 and returning \c false.
2005
2006 \since 6.0
2007
2008 \sa canConvert(int targetTypeId), clear()
2009*/
2010
2011bool QVariant::convert(QMetaType targetType)
2012{
2013 if (d.type() == targetType)
2014 return targetType.isValid();
2015
2016 QVariant oldValue = *this;
2017
2018 clear();
2019 create(targetType.id(), nullptr);
2020 if (!oldValue.canConvert(targetType))
2021 return false;
2022
2023 // Fail if the value is not initialized or was forced null by a previous failed convert.
2024 if (oldValue.d.is_null && oldValue.d.typeId() != QMetaType::Nullptr)
2025 return false;
2026
2027 bool ok = QMetaType::convert(oldValue.d.type(), oldValue.constData(), targetType, data());
2028 d.is_null = !ok;
2029 return ok;
2030}
2031
2032/*!
2033 \fn bool QVariant::convert(int type, void *ptr) const
2034 \internal
2035 Created for qvariant_cast() usage
2036*/
2037bool QVariant::convert(int type, void *ptr) const
2038{
2039 return QMetaType::convert(d.type(), constData(), QMetaType(type), ptr);
2040}
2041
2042/*!
2043 \internal
2044*/
2045bool QVariant::view(int type, void *ptr)
2046{
2047 return QMetaType::view(d.type(), data(), QMetaType(type), ptr);
2048}
2049
2050/*!
2051 \fn bool QVariant::operator==(const QVariant &v1, const QVariant &v2)
2052
2053 Returns \c true if \a v1 and \a v2 are equal; otherwise returns \c false.
2054
2055 QVariant uses the equality operator of the type() contained to check for
2056 equality.
2057
2058 Variants of different types will always compare as not equal with a few
2059 exceptions:
2060
2061 \list
2062 \li If both types are numeric types (integers and floatins point numbers)
2063 Qt will compare those types using standard C++ type promotion rules.
2064 \li If one type is numeric and the other one a QString, Qt will try to
2065 convert the QString to a matching numeric type and if successful compare
2066 those.
2067 \li If both variants contain pointers to QObject derived types, QVariant
2068 will check whether the types are related and point to the same object.
2069 \endlist
2070
2071 The result of the function is not affected by the result of QVariant::isNull,
2072 which means that two values can be equal even if one of them is null and
2073 another is not.
2074*/
2075
2076/*!
2077 \fn bool QVariant::operator!=(const QVariant &v1, const QVariant &v2)
2078
2079 Returns \c false if \a v1 and \a v2 are equal; otherwise returns \c true.
2080
2081 QVariant uses the equality operator of the type() contained to check for
2082 equality.
2083
2084 Variants of different types will always compare as not equal with a few
2085 exceptions:
2086
2087 \list
2088 \li If both types are numeric types (integers and floatins point numbers)
2089 Qt will compare those types using standard C++ type promotion rules.
2090 \li If one type is numeric and the other one a QString, Qt will try to
2091 convert the QString to a matching numeric type and if successful compare
2092 those.
2093 \li If both variants contain pointers to QObject derived types, QVariant
2094 will check whether the types are related and point to the same object.
2095 \endlist
2096*/
2097
2098static bool qIsNumericType(uint tp)
2099{
2100 static const qulonglong numericTypeBits =
2101 Q_UINT64_C(1) << QMetaType::QString |
2102 Q_UINT64_C(1) << QMetaType::Bool |
2103 Q_UINT64_C(1) << QMetaType::Double |
2104 Q_UINT64_C(1) << QMetaType::Float |
2105 Q_UINT64_C(1) << QMetaType::Char |
2106 Q_UINT64_C(1) << QMetaType::SChar |
2107 Q_UINT64_C(1) << QMetaType::UChar |
2108 Q_UINT64_C(1) << QMetaType::Short |
2109 Q_UINT64_C(1) << QMetaType::UShort |
2110 Q_UINT64_C(1) << QMetaType::Int |
2111 Q_UINT64_C(1) << QMetaType::UInt |
2112 Q_UINT64_C(1) << QMetaType::Long |
2113 Q_UINT64_C(1) << QMetaType::ULong |
2114 Q_UINT64_C(1) << QMetaType::LongLong |
2115 Q_UINT64_C(1) << QMetaType::ULongLong;
2116 return tp < (CHAR_BIT * sizeof numericTypeBits) ? numericTypeBits & (Q_UINT64_C(1) << tp) : false;
2117}
2118
2119static bool qIsFloatingPoint(uint tp)
2120{
2121 return tp == QMetaType::Double || tp == QMetaType::Float;
2122}
2123
2124static int normalizeLowerRanks(uint tp)
2125{
2126 static const qulonglong numericTypeBits =
2127 Q_UINT64_C(1) << QMetaType::Bool |
2128 Q_UINT64_C(1) << QMetaType::Char |
2129 Q_UINT64_C(1) << QMetaType::SChar |
2130 Q_UINT64_C(1) << QMetaType::UChar |
2131 Q_UINT64_C(1) << QMetaType::Short |
2132 Q_UINT64_C(1) << QMetaType::UShort;
2133 return numericTypeBits & (Q_UINT64_C(1) << tp) ? uint(QMetaType::Int) : tp;
2134}
2135
2136static int normalizeLong(uint tp)
2137{
2138 const uint IntType = sizeof(long) == sizeof(int) ? QMetaType::Int : QMetaType::LongLong;
2139 const uint UIntType = sizeof(ulong) == sizeof(uint) ? QMetaType::UInt : QMetaType::ULongLong;
2140 return tp == QMetaType::Long ? IntType :
2141 tp == QMetaType::ULong ? UIntType : tp;
2142}
2143
2144static int numericTypePromotion(uint t1, uint t2)
2145{
2146 Q_ASSERT(qIsNumericType(t1));
2147 Q_ASSERT(qIsNumericType(t2));
2148
2149 if ((t1 == QMetaType::Bool && t2 == QMetaType::QString) ||
2150 (t2 == QMetaType::Bool && t1 == QMetaType::QString))
2151 return QMetaType::Bool;
2152
2153 // C++ integral ranks: (4.13 Integer conversion rank [conv.rank])
2154 // bool < signed char < short < int < long < long long
2155 // unsigneds have the same rank as their signed counterparts
2156 // C++ integral promotion rules (4.5 Integral Promotions [conv.prom])
2157 // - any type with rank less than int can be converted to int or unsigned int
2158 // 5 Expressions [expr] paragraph 9:
2159 // - if either operand is double, the other shall be converted to double
2160 // - " " float, " " " float
2161 // - if both operands have the same type, no further conversion is needed.
2162 // - if both are signed or if both are unsigned, convert to the one with highest rank
2163 // - if the unsigned has higher or same rank, convert the signed to the unsigned one
2164 // - if the signed can represent all values of the unsigned, convert to the signed
2165 // - otherwise, convert to the unsigned corresponding to the rank of the signed
2166
2167 // floating point: we deviate from the C++ standard by always using qreal
2168 if (qIsFloatingPoint(t1) || qIsFloatingPoint(t2))
2169 return QMetaType::QReal;
2170
2171 // integral rules:
2172 // for all platforms we support, int can always hold the values of lower-ranked types
2173 t1 = normalizeLowerRanks(t1);
2174 t2 = normalizeLowerRanks(t2);
2175
2176 // normalize long / ulong: in all platforms we run, they're either the same as int or as long long
2177 t1 = normalizeLong(t1);
2178 t2 = normalizeLong(t2);
2179
2180 // implement the other rules
2181 // the four possibilities are Int, UInt, LongLong and ULongLong
2182 // if any of the two is ULongLong, then it wins (highest rank, unsigned)
2183 // otherwise, if one of the two is LongLong, then the other is either LongLong too or lower-ranked
2184 // otherwise, if one of the two is UInt, then the other is either UInt too or Int
2185 if (t1 == QMetaType::ULongLong || t2 == QMetaType::ULongLong)
2186 return QMetaType::ULongLong;
2187 if (t1 == QMetaType::LongLong || t2 == QMetaType::LongLong)
2188 return QMetaType::LongLong;
2189 if (t1 == QMetaType::UInt || t2 == QMetaType::UInt)
2190 return QMetaType::UInt;
2191 return QMetaType::Int;
2192}
2193
2194static bool integralEquals(uint promotedType, const QVariant::Private *d1, const QVariant::Private *d2)
2195{
2196 // use toLongLong to retrieve the data, it gets us all the bits
2197 bool ok;
2198 qlonglong l1 = qConvertToNumber(d1, &ok, promotedType == QMetaType::Bool);
2199 if (!ok)
2200 return false;
2201
2202 qlonglong l2 = qConvertToNumber(d2, &ok, promotedType == QMetaType::Bool);
2203 if (!ok)
2204 return false;
2205
2206 if (promotedType == QMetaType::Bool)
2207 return bool(l1) == bool(l2);
2208 if (promotedType == QMetaType::Int)
2209 return int(l1) == int(l2);
2210 if (promotedType == QMetaType::UInt)
2211 return uint(l1) == uint(l2);
2212 if (promotedType == QMetaType::LongLong)
2213 return l1 == l2;
2214 if (promotedType == QMetaType::ULongLong)
2215 return qulonglong(l1) == qulonglong(l2);
2216
2217 Q_UNREACHABLE();
2218 return 0;
2219}
2220
2221namespace {
2222template<typename Numeric>
2223int spaceShip(Numeric lhs, Numeric rhs)
2224{
2225 bool smaller;
2226 if constexpr (std::is_same_v<Numeric, QObject *>)
2227 smaller = std::less<QObject *>()(lhs, rhs); // can't use less all the time because of bool
2228 else
2229 smaller = lhs < rhs;
2230 if (smaller)
2231 return -1;
2232 else if (lhs == rhs)
2233 return 0;
2234 else
2235 return 1;
2236}
2237}
2238
2239static std::optional<int> integralCompare(uint promotedType, const QVariant::Private *d1, const QVariant::Private *d2)
2240{
2241 // use toLongLong to retrieve the data, it gets us all the bits
2242 bool ok;
2243 qlonglong l1 = qConvertToNumber(d1, &ok, promotedType == QMetaType::Bool);
2244 if (!ok)
2245 return std::nullopt;
2246
2247 qlonglong l2 = qConvertToNumber(d2, &ok, promotedType == QMetaType::Bool);
2248 if (!ok)
2249 return std::nullopt;
2250
2251 if (promotedType == QMetaType::Bool)
2252 return spaceShip<bool>(l1, l2);
2253 if (promotedType == QMetaType::Int)
2254 return spaceShip<int>(l1, l2);
2255 if (promotedType == QMetaType::UInt)
2256 return spaceShip<uint>(l1, l2);
2257 if (promotedType == QMetaType::LongLong)
2258 return spaceShip<qlonglong>(l1, l2);
2259 if (promotedType == QMetaType::ULongLong)
2260 return spaceShip<qulonglong>(l1, l2);
2261
2262 Q_UNREACHABLE();
2263 return 0;
2264}
2265
2266static std::optional<int> numericCompare(const QVariant::Private *d1, const QVariant::Private *d2)
2267{
2268 uint promotedType = numericTypePromotion(d1->typeId(), d2->typeId());
2269 if (promotedType != QMetaType::QReal)
2270 return integralCompare(promotedType, d1, d2);
2271 // qreal comparisons
2272 bool ok;
2273 qreal r1 = qConvertToRealNumber(d1, &ok);
2274 if (!ok)
2275 return std::nullopt;
2276 qreal r2 = qConvertToRealNumber(d2, &ok);
2277 if (!ok)
2278 return std::nullopt;
2279 if (r1 == r2)
2280 return 0;
2281
2282 if (std::isnan(r1) || std::isnan(r2))
2283 return std::nullopt;
2284 return spaceShip<qreal>(r1, r2);
2285}
2286
2287static bool numericEquals(const QVariant::Private *d1, const QVariant::Private *d2)
2288{
2289 uint promotedType = numericTypePromotion(d1->typeId(), d2->typeId());
2290 if (promotedType != QMetaType::QReal)
2291 return integralEquals(promotedType, d1, d2);
2292
2293 // qreal comparisons
2294 bool ok;
2295 qreal r1 = qConvertToRealNumber(d1, &ok);
2296 if (!ok)
2297 return false;
2298 qreal r2 = qConvertToRealNumber(d2, &ok);
2299 if (!ok)
2300 return false;
2301 if (r1 == r2)
2302 return true;
2303
2304 return false;
2305}
2306
2307#ifndef QT_BOOTSTRAPPED
2308static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
2309{
2310 if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
2311 return fromType.metaObject()->inherits(toType.metaObject()) ||
2312 toType.metaObject()->inherits(fromType.metaObject());
2313 }
2314 return false;
2315}
2316
2317static bool pointerEquals(const QVariant::Private *d1, const QVariant::Private *d2)
2318{
2319 // simply check whether both types point to the same data
2320 return d1->get<QObject *>() == d2->get<QObject *>();
2321}
2322
2323static int pointerCompare(const QVariant::Private *d1, const QVariant::Private *d2)
2324{
2325 return spaceShip<QObject *>(d1->get<QObject *>(), d2->get<QObject *>());
2326}
2327#endif
2328
2329/*!
2330 \internal
2331 */
2332bool QVariant::equals(const QVariant &v) const
2333{
2334 auto metatype = d.type();
2335
2336 if (metatype != v.metaType()) {
2337 // try numeric comparisons, with C++ type promotion rules (no conversion)
2338 if (qIsNumericType(metatype.id()) && qIsNumericType(v.d.typeId()))
2339 return numericEquals(&d, &v.d);
2340#ifndef QT_BOOTSTRAPPED
2341 // if both types are related pointers to QObjects, check if they point to the same object
2342 if (canConvertMetaObject(metatype, v.metaType()))
2343 return pointerEquals(&d, &v.d);
2344#endif
2345 return false;
2346 }
2347
2348 // For historical reasons: QVariant() == QVariant()
2349 if (!metatype.isValid())
2350 return true;
2351
2352 return metatype.equals(d.storage(), v.d.storage());
2353}
2354
2355/*!
2356 Compares the objects at \a lhs and \a rhs for ordering.
2357
2358 Returns an std::nullopt if comparison is not supported or the values are unordered.
2359 Otherwise, returns -1, 0 or +1 according as \a lhs is less than, equal to or greater
2360 than \a rhs.
2361
2362 If the variants contain data with a different metatype, the values are considered
2363 unordered unless they are both of numeric or pointer types, where regular numeric or
2364 pointer comparison rules will be used.
2365 \note: If a numeric comparison is done and at least one value is NaN, \c std::nullopt
2366 is returned.
2367
2368 If both variants contain data of the same metatype, the method will use the
2369 QMetaType::compare method to determine the ordering of the two variants, which can
2370 also indicate that it can't establish an ordering between the two values.
2371
2372 \since 6.0
2373 \sa QMetaType::compare(), QMetaType::isOrdered()
2374*/
2375std::optional<int> QVariant::compare(const QVariant &lhs, const QVariant &rhs)
2376{
2377 QMetaType t = lhs.d.type();
2378 if (t != rhs.d.type()) {
2379 // try numeric comparisons, with C++ type promotion rules (no conversion)
2380 if (qIsNumericType(lhs.d.typeId()) && qIsNumericType(rhs.d.typeId()))
2381 return numericCompare(&lhs.d, &rhs.d);
2382#ifndef QT_BOOTSTRAPPED
2383 if (canConvertMetaObject(lhs.metaType(), rhs.metaType()))
2384 return pointerCompare(&lhs.d, &rhs.d);
2385#endif
2386 return std::nullopt;
2387 }
2388 return t.compare(lhs.constData(), rhs.constData());
2389}
2390
2391/*!
2392 \fn const void *QVariant::constData() const
2393 \fn const void* QVariant::data() const
2394
2395 Returns a pointer to the contained object as a generic void* that cannot be
2396 written to.
2397
2398 \sa QMetaType
2399 */
2400
2401/*!
2402 Returns a pointer to the contained object as a generic void* that can be
2403 written to.
2404
2405 This function detaches the QVariant. When called on a \l{isNull}{null-QVariant},
2406 the QVariant will not be null after the call.
2407
2408 \sa QMetaType
2409*/
2410void *QVariant::data()
2411{
2412 detach();
2413 // set is_null to false, as the caller is likely to write some data into this variant
2414 d.is_null = false;
2415 return const_cast<void *>(constData());
2416}
2417
2418/*!
2419 Returns \c true if this is a null variant, false otherwise.
2420
2421 A variant is considered null if it contains no initialized value or a null pointer.
2422
2423 \note This behavior has been changed from Qt 5, where isNull() would also
2424 return true if the variant contained an object of a builtin type with an isNull()
2425 method that returned true for that object.
2426
2427 \sa convert(int)
2428*/
2429bool QVariant::isNull() const
2430{
2431 if (d.is_null || !metaType().isValid())
2432 return true;
2433 if (metaType().flags() & QMetaType::IsPointer)
2434 return d.get<void *>() == nullptr;
2435 return false;
2436}
2437
2438#ifndef QT_NO_DEBUG_STREAM
2439QDebug QVariant::qdebugHelper(QDebug dbg) const
2440{
2441 QDebugStateSaver saver(dbg);
2442 const uint typeId = d.typeId();
2443 dbg.nospace() << "QVariant(";
2444 if (typeId != QMetaType::UnknownType) {
2445 dbg << d.type().name() << ", ";
2446 bool streamed = d.type().debugStream(dbg, d.storage());
2447 if (!streamed && canConvert<QString>())
2448 dbg << toString();
2449 } else {
2450 dbg << "Invalid";
2451 }
2452 dbg << ')';
2453 return dbg;
2454}
2455
2456#if QT_DEPRECATED_SINCE(6, 0)
2457QT_WARNING_PUSH
2458QT_WARNING_DISABLE_DEPRECATED
2459
2460QDebug operator<<(QDebug dbg, const QVariant::Type p)
2461{
2462 QDebugStateSaver saver(dbg);
2463 dbg.nospace() << "QVariant::"
2464 << (int(p) != int(QMetaType::UnknownType)
2465 ? QMetaType(p).name()
2466 : "Invalid");
2467 return dbg;
2468}
2469
2470QT_WARNING_POP
2471#endif
2472
2473#endif
2474
2475/*! \fn template<typename T> void QVariant::setValue(T &&value)
2476
2477 Stores a copy of \a value. If \c{T} is a type that QVariant
2478 doesn't support, QMetaType is used to store the value. A compile
2479 error will occur if QMetaType doesn't handle the type.
2480
2481 Example:
2482
2483 \snippet code/src_corelib_kernel_qvariant.cpp 4
2484
2485 \sa value(), fromValue(), canConvert()
2486 */
2487
2488/*! \fn template<typename T> void QVariant::setValue(const QVariant &value)
2489
2490 Copies \a value over this QVariant. It is equivalent to simply
2491 assigning \a value to this QVariant.
2492*/
2493
2494/*! \fn template<typename T> void QVariant::setValue(QVariant &&value)
2495
2496 Moves \a value over this QVariant. It is equivalent to simply
2497 move assigning \a value to this QVariant.
2498*/
2499
2500/*! \fn template<typename T> T QVariant::value() const
2501
2502 Returns the stored value converted to the template type \c{T}.
2503 Call canConvert() to find out whether a type can be converted.
2504 If the value cannot be converted, a \l{default-constructed value}
2505 will be returned.
2506
2507 If the type \c{T} is supported by QVariant, this function behaves
2508 exactly as toString(), toInt() etc.
2509
2510 Example:
2511
2512 \snippet code/src_corelib_kernel_qvariant.cpp 5
2513
2514 If the QVariant contains a pointer to a type derived from QObject then
2515 \c{T} may be any QObject type. If the pointer stored in the QVariant can be
2516 qobject_cast to T, then that result is returned. Otherwise \nullptr is
2517 returned. Note that this only works for QObject subclasses which use
2518 the Q_OBJECT macro.
2519
2520 If the QVariant contains a sequential container and \c{T} is QVariantList, the
2521 elements of the container will be converted into \l {QVariant}s and returned as a QVariantList.
2522
2523 \snippet code/src_corelib_kernel_qvariant.cpp 9
2524
2525 \sa setValue(), fromValue(), canConvert(), Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE()
2526*/
2527
2528/*! \fn template<typename T> T QVariant::view()
2529
2530 Returns a mutable view of template type \c{T} on the stored value.
2531 Call canView() to find out whether such a view is supported.
2532 If no such view can be created, returns the stored value converted to the
2533 template type \c{T}. Call canConvert() to find out whether a type can be
2534 converted. If the value can neither be viewed nor converted, a
2535 \l{default-constructed value} will be returned.
2536
2537 \sa canView(), Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE()
2538*/
2539
2540/*! \fn bool QVariant::canConvert() const
2541
2542 Returns \c true if the variant can be converted to the template type \c{T},
2543 otherwise false.
2544
2545 Example:
2546
2547 \snippet code/src_corelib_kernel_qvariant.cpp 6
2548
2549 A QVariant containing a pointer to a type derived from QObject will also return true for this
2550 function if a qobject_cast to the template type \c{T} would succeed. Note that this only works
2551 for QObject subclasses which use the Q_OBJECT macro.
2552
2553 \sa convert()
2554*/
2555
2556/*! \fn bool QVariant::canView() const
2557
2558 Returns \c true if a mutable view of the template type \c{T} can be created on this variant,
2559 otherwise \c false.
2560
2561 \sa value()
2562*/
2563
2564/*! \fn template<typename T> static QVariant QVariant::fromValue(const T &value)
2565
2566 Returns a QVariant containing a copy of \a value. Behaves
2567 exactly like setValue() otherwise.
2568
2569 Example:
2570
2571 \snippet code/src_corelib_kernel_qvariant.cpp 7
2572
2573 \note If you are working with custom types, you should use
2574 the Q_DECLARE_METATYPE() macro to register your custom type.
2575
2576 \sa setValue(), value()
2577*/
2578
2579/*! \fn template<typename... Types> QVariant QVariant::fromStdVariant(const std::variant<Types...> &value)
2580 \since 5.11
2581
2582 Returns a QVariant with the type and value of the active variant of \a value. If
2583 the active type is std::monostate a default QVariant is returned.
2584
2585 \note With this method you do not need to register the variant as a Qt metatype,
2586 since the std::variant is resolved before being stored. The component types
2587 should be registered however.
2588
2589 \sa fromValue()
2590*/
2591
2592/*!
2593 \fn template<typename T> T qvariant_cast(const QVariant &value)
2594 \relates QVariant
2595
2596 Returns the given \a value converted to the template type \c{T}.
2597
2598 This function is equivalent to QVariant::value().
2599
2600 \sa QVariant::value()
2601*/
2602
2603/*! \fn template<typename T> T qVariantValue(const QVariant &value)
2604 \relates QVariant
2605 \obsolete
2606
2607 Returns the given \a value converted to the template type \c{T}.
2608
2609 This function is equivalent to
2610 \l{QVariant::value()}{QVariant::value}<T>(\a value).
2611
2612 \note This function was provided as a workaround for MSVC 6
2613 which did not support member template functions. It is advised
2614 to use the other form in new code.
2615
2616 \sa QVariant::value(), qvariant_cast()
2617*/
2618
2619/*! \fn bool qVariantCanConvert(const QVariant &value)
2620 \relates QVariant
2621 \obsolete
2622
2623 Returns \c true if the given \a value can be converted to the
2624 template type specified; otherwise returns \c false.
2625
2626 This function is equivalent to QVariant::canConvert(\a value).
2627
2628 \note This function was provided as a workaround for MSVC 6
2629 which did not support member template functions. It is advised
2630 to use the other form in new code.
2631
2632 \sa QVariant::canConvert()
2633*/
2634
2635/*!
2636 \typedef QVariantList
2637 \relates QVariant
2638
2639 Synonym for QList<QVariant>.
2640*/
2641
2642/*!
2643 \typedef QVariantMap
2644 \relates QVariant
2645
2646 Synonym for QMap<QString, QVariant>.
2647*/
2648
2649/*!
2650 \typedef QVariantHash
2651 \relates QVariant
2652 \since 4.5
2653
2654 Synonym for QHash<QString, QVariant>.
2655*/
2656
2657/*!
2658 \typedef QVariant::DataPtr
2659 \internal
2660*/
2661/*! \typedef QVariant::f_construct
2662 \internal
2663*/
2664
2665/*! \typedef QVariant::f_clear
2666 \internal
2667*/
2668
2669/*! \typedef QVariant::f_null
2670 \internal
2671*/
2672
2673/*! \typedef QVariant::f_load
2674 \internal
2675*/
2676
2677/*! \typedef QVariant::f_save
2678 \internal
2679*/
2680
2681/*! \typedef QVariant::f_compare
2682 \internal
2683*/
2684
2685/*! \typedef QVariant::f_convert
2686 \internal
2687*/
2688
2689/*! \typedef QVariant::f_canConvert
2690 \internal
2691*/
2692
2693/*! \typedef QVariant::f_debugStream
2694 \internal
2695*/
2696
2697/*!
2698 \fn DataPtr &QVariant::data_ptr()
2699 \internal
2700*/
2701
2702/*!
2703 \fn const DataPtr &QVariant::data_ptr() const
2704 \internal
2705*/
2706
2707/*!
2708 \internal
2709 */
2710const void *QtPrivate::QVariantTypeCoercer::convert(const QVariant &value, const QMetaType &type)
2711{
2712 if (type == QMetaType::fromType<QVariant>())
2713 return &value;
2714
2715 if (type == value.metaType())
2716 return value.constData();
2717
2718 if (value.canConvert(type)) {
2719 converted = value;
2720 if (converted.convert(type))
2721 return converted.constData();
2722 }
2723
2724 return nullptr;
2725}
2726
2727/*!
2728 \internal
2729 */
2730const void *QtPrivate::QVariantTypeCoercer::coerce(const QVariant &value, const QMetaType &type)
2731{
2732 if (const void *result = convert(value, type))
2733 return result;
2734
2735 converted = QVariant(type);
2736 return converted.constData();
2737}
2738
2739/*!
2740 \class QVariantRef
2741 \since 6.0
2742 \inmodule QtCore
2743 \brief The QVariantRef acts as a non-const reference to a QVariant.
2744
2745 As the generic iterators don't actually instantiate a QVariant on each
2746 step, they cannot return a reference to one from operator*(). QVariantRef
2747 provides the same functionality as an actual reference to a QVariant would,
2748 but is backed by a pointer given as template parameter. The template is
2749 implemented for pointers of type QSequentialIterator and
2750 QAssociativeIterator.
2751*/
2752
2753/*!
2754 \fn template<typename Pointer> QVariantRef<Pointer>::QVariantRef(const Pointer *pointer)
2755
2756 Creates a QVariantRef from an \a pointer.
2757 */
2758
2759/*!
2760 \fn template<typename Pointer> QVariantRef<Pointer> &QVariantRef<Pointer>::operator=(const QVariant &value)
2761
2762 Assigns a new \a value to the value pointed to by the pointer this
2763 QVariantRef refers to.
2764 */
2765
2766/*!
2767 \fn template<typename Pointer> QVariantRef<Pointer> &QVariantRef<Pointer>::operator=(const QVariantRef &value)
2768
2769 Assigns a new \a value to the value pointed to by the pointer this
2770 QVariantRef refers to.
2771 */
2772
2773/*!
2774 \fn template<typename Pointer> QVariantRef<Pointer> &QVariantRef<Pointer>::operator=(QVariantRef &&value)
2775
2776 Assigns a new \a value to the value pointed to by the pointer this
2777 QVariantRef refers to.
2778*/
2779
2780/*!
2781 \fn template<typename Pointer> QVariantRef<Pointer>::operator QVariant() const
2782
2783 Resolves the QVariantRef to an actual QVariant.
2784*/
2785
2786/*!
2787 \fn template<typename Pointer> void swap(QVariantRef<Pointer> a, QVariantRef<Pointer> b)
2788
2789 Swaps the values pointed to by the pointers the QVariantRefs
2790 \a a and \a b refer to.
2791*/
2792
2793/*!
2794 \class QVariantConstPointer
2795 \since 6.0
2796 \inmodule QtCore
2797 \brief Emulated const pointer to QVariant based on a pointer.
2798
2799 QVariantConstPointer wraps a QVariant and returns it from its operator*().
2800 This makes it suitable as replacement for an actual const pointer. We cannot
2801 return an actual const pointer from generic iterators as the iterators don't
2802 hold an actual QVariant.
2803*/
2804
2805/*!
2806 Constructs a QVariantConstPointer from a \a variant.
2807 */
2808QVariantConstPointer::QVariantConstPointer(QVariant variant)
2809 : m_variant(std::move(variant))
2810{
2811}
2812
2813/*!
2814 Dereferences the QVariantConstPointer to retrieve its internal QVariant.
2815 */
2816QVariant QVariantConstPointer::operator*() const
2817{
2818 return m_variant;
2819}
2820
2821/*!
2822 Returns a const pointer to the QVariant, conforming to the
2823 conventions for operator->().
2824 */
2825const QVariant *QVariantConstPointer::operator->() const
2826{
2827 return &m_variant;
2828}
2829
2830/*!
2831 \class QVariantPointer
2832 \since 6.0
2833 \inmodule QtCore
2834 \brief QVariantPointer is a template class that emulates a pointer to QVariant based on a pointer.
2835
2836 QVariantConstPointer wraps a pointer and returns QVariantRef to it from its
2837 operator*(). This makes it suitable as replacement for an actual pointer. We
2838 cannot return an actual pointer from generic iterators as the iterators don't
2839 hold an actual QVariant.
2840*/
2841
2842/*!
2843 \fn template<typename Pointer> QVariantPointer<Pointer>::QVariantPointer(const Pointer *pointer)
2844
2845 Constructs a QVariantPointer from the given \a pointer.
2846 */
2847
2848/*!
2849 \fn template<typename Pointer> QVariantRef<Pointer> QVariantPointer<Pointer>::operator*() const
2850
2851 Dereferences the QVariantPointer to a QVariantRef.
2852 */
2853
2854/*!
2855 \fn template<typename Pointer> Pointer QVariantPointer<Pointer>::operator->() const
2856
2857 Dereferences and returns the pointer. The pointer is expected to also
2858 implement operator->().
2859 */
2860
2861QT_END_NAMESPACE
2862