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