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
1469 has metaType() \l QMetaType::QVariantHash; otherwise returns an empty map.
1470
1471 \sa canConvert(), convert()
1472*/
1473QVariantHash QVariant::toHash() const
1474{
1475 return qvariant_cast<QVariantHash>(*this);
1476}
1477
1478/*!
1479 \fn QDate QVariant::toDate() const
1480
1481 Returns the variant as a QDate if the variant has userType()
1482 \l QMetaType::QDate, \l QMetaType::QDateTime, or \l QMetaType::QString;
1483 otherwise returns an invalid date.
1484
1485 If the metaType() is \l QMetaType::QString, an invalid date will be returned if
1486 the string cannot be parsed as a Qt::ISODate format date.
1487
1488 \sa canConvert(), convert()
1489*/
1490QDate QVariant::toDate() const
1491{
1492 return qvariant_cast<QDate>(*this);
1493}
1494
1495/*!
1496 \fn QTime QVariant::toTime() const
1497
1498 Returns the variant as a QTime if the variant has userType()
1499 \l QMetaType::QTime, \l QMetaType::QDateTime, or \l QMetaType::QString;
1500 otherwise returns an invalid time.
1501
1502 If the metaType() is \l QMetaType::QString, an invalid time will be returned if
1503 the string cannot be parsed as a Qt::ISODate format time.
1504
1505 \sa canConvert(), convert()
1506*/
1507QTime QVariant::toTime() const
1508{
1509 return qvariant_cast<QTime>(*this);
1510}
1511
1512/*!
1513 \fn QDateTime QVariant::toDateTime() const
1514
1515 Returns the variant as a QDateTime if the variant has userType()
1516 \l QMetaType::QDateTime, \l QMetaType::QDate, or \l QMetaType::QString;
1517 otherwise returns an invalid date/time.
1518
1519 If the metaType() is \l QMetaType::QString, an invalid date/time will be
1520 returned if the string cannot be parsed as a Qt::ISODate format date/time.
1521
1522 \sa canConvert(), convert()
1523*/
1524QDateTime QVariant::toDateTime() const
1525{
1526 return qvariant_cast<QDateTime>(*this);
1527}
1528
1529/*!
1530 \since 4.7
1531 \fn QEasingCurve QVariant::toEasingCurve() const
1532
1533 Returns the variant as a QEasingCurve if the variant has userType()
1534 \l QMetaType::QEasingCurve; otherwise returns a default easing curve.
1535
1536 \sa canConvert(), convert()
1537*/
1538#if QT_CONFIG(easingcurve)
1539QEasingCurve QVariant::toEasingCurve() const
1540{
1541 return qvariant_cast<QEasingCurve>(*this);
1542}
1543#endif
1544
1545/*!
1546 \fn QByteArray QVariant::toByteArray() const
1547
1548 Returns the variant as a QByteArray if the variant has userType()
1549 \l QMetaType::QByteArray or \l QMetaType::QString (converted using
1550 QString::fromUtf8()); otherwise returns an empty byte array.
1551
1552 \sa canConvert(), convert()
1553*/
1554QByteArray QVariant::toByteArray() const
1555{
1556 return qvariant_cast<QByteArray>(*this);
1557}
1558
1559/*!
1560 \fn QPoint QVariant::toPoint() const
1561
1562 Returns the variant as a QPoint if the variant has userType()
1563 \l QMetaType::QPoint or \l QMetaType::QPointF; otherwise returns a null
1564 QPoint.
1565
1566 \sa canConvert(), convert()
1567*/
1568QPoint QVariant::toPoint() const
1569{
1570 return qvariant_cast<QPoint>(*this);
1571}
1572
1573/*!
1574 \fn QRect QVariant::toRect() const
1575
1576 Returns the variant as a QRect if the variant has userType()
1577 \l QMetaType::QRect; otherwise returns an invalid QRect.
1578
1579 \sa canConvert(), convert()
1580*/
1581QRect QVariant::toRect() const
1582{
1583 return qvariant_cast<QRect>(*this);
1584}
1585
1586/*!
1587 \fn QSize QVariant::toSize() const
1588
1589 Returns the variant as a QSize if the variant has userType()
1590 \l QMetaType::QSize; otherwise returns an invalid QSize.
1591
1592 \sa canConvert(), convert()
1593*/
1594QSize QVariant::toSize() const
1595{
1596 return qvariant_cast<QSize>(*this);
1597}
1598
1599/*!
1600 \fn QSizeF QVariant::toSizeF() const
1601
1602 Returns the variant as a QSizeF if the variant has userType() \l
1603 QMetaType::QSizeF; otherwise returns an invalid QSizeF.
1604
1605 \sa canConvert(), convert()
1606*/
1607QSizeF QVariant::toSizeF() const
1608{
1609 return qvariant_cast<QSizeF>(*this);
1610}
1611
1612/*!
1613 \fn QRectF QVariant::toRectF() const
1614
1615 Returns the variant as a QRectF if the variant has userType()
1616 \l QMetaType::QRect or \l QMetaType::QRectF; otherwise returns an invalid
1617 QRectF.
1618
1619 \sa canConvert(), convert()
1620*/
1621QRectF QVariant::toRectF() const
1622{
1623 return qvariant_cast<QRectF>(*this);
1624}
1625
1626/*!
1627 \fn QLineF QVariant::toLineF() const
1628
1629 Returns the variant as a QLineF if the variant has userType()
1630 \l QMetaType::QLineF; otherwise returns an invalid QLineF.
1631
1632 \sa canConvert(), convert()
1633*/
1634QLineF QVariant::toLineF() const
1635{
1636 return qvariant_cast<QLineF>(*this);
1637}
1638
1639/*!
1640 \fn QLine QVariant::toLine() const
1641
1642 Returns the variant as a QLine if the variant has userType()
1643 \l QMetaType::QLine; otherwise returns an invalid QLine.
1644
1645 \sa canConvert(), convert()
1646*/
1647QLine QVariant::toLine() const
1648{
1649 return qvariant_cast<QLine>(*this);
1650}
1651
1652/*!
1653 \fn QPointF QVariant::toPointF() const
1654
1655 Returns the variant as a QPointF if the variant has userType() \l
1656 QMetaType::QPoint or \l QMetaType::QPointF; otherwise returns a null
1657 QPointF.
1658
1659 \sa canConvert(), convert()
1660*/
1661QPointF QVariant::toPointF() const
1662{
1663 return qvariant_cast<QPointF>(*this);
1664}
1665
1666/*!
1667 \fn QUrl QVariant::toUrl() const
1668
1669 Returns the variant as a QUrl if the variant has userType()
1670 \l QMetaType::QUrl; otherwise returns an invalid QUrl.
1671
1672 \sa canConvert(), convert()
1673*/
1674QUrl QVariant::toUrl() const
1675{
1676 return qvariant_cast<QUrl>(*this);
1677}
1678
1679/*!
1680 \fn QLocale QVariant::toLocale() const
1681
1682 Returns the variant as a QLocale if the variant has userType()
1683 \l QMetaType::QLocale; otherwise returns an invalid QLocale.
1684
1685 \sa canConvert(), convert()
1686*/
1687QLocale QVariant::toLocale() const
1688{
1689 return qvariant_cast<QLocale>(*this);
1690}
1691
1692#if QT_CONFIG(regularexpression)
1693/*!
1694 \fn QRegularExpression QVariant::toRegularExpression() const
1695 \since 5.0
1696
1697 Returns the variant as a QRegularExpression if the variant has userType() \l
1698 QRegularExpression; otherwise returns an empty QRegularExpression.
1699
1700 \sa canConvert(), convert()
1701*/
1702QRegularExpression QVariant::toRegularExpression() const
1703{
1704 return qvariant_cast<QRegularExpression>(*this);
1705}
1706#endif // QT_CONFIG(regularexpression)
1707
1708#if QT_CONFIG(itemmodel)
1709/*!
1710 \since 5.0
1711
1712 Returns the variant as a QModelIndex if the variant has userType() \l
1713 QModelIndex; otherwise returns a default constructed QModelIndex.
1714
1715 \sa canConvert(), convert(), toPersistentModelIndex()
1716*/
1717QModelIndex QVariant::toModelIndex() const
1718{
1719 return qvariant_cast<QModelIndex>(*this);
1720}
1721
1722/*!
1723 \since 5.5
1724
1725 Returns the variant as a QPersistentModelIndex if the variant has userType() \l
1726 QPersistentModelIndex; otherwise returns a default constructed QPersistentModelIndex.
1727
1728 \sa canConvert(), convert(), toModelIndex()
1729*/
1730QPersistentModelIndex QVariant::toPersistentModelIndex() const
1731{
1732 return qvariant_cast<QPersistentModelIndex>(*this);
1733}
1734#endif // QT_CONFIG(itemmodel)
1735
1736/*!
1737 \since 5.0
1738
1739 Returns the variant as a QUuid if the variant has metaType()
1740 \l QMetaType::QUuid, \l QMetaType::QByteArray or \l QMetaType::QString;
1741 otherwise returns a default-constructed QUuid.
1742
1743 \sa canConvert(), convert()
1744*/
1745QUuid QVariant::toUuid() const
1746{
1747 return qvariant_cast<QUuid>(*this);
1748}
1749
1750/*!
1751 \since 5.0
1752
1753 Returns the variant as a QJsonValue if the variant has userType() \l
1754 QJsonValue; otherwise returns a default constructed QJsonValue.
1755
1756 \sa canConvert(), convert()
1757*/
1758QJsonValue QVariant::toJsonValue() const
1759{
1760 return qvariant_cast<QJsonValue>(*this);
1761}
1762
1763/*!
1764 \since 5.0
1765
1766 Returns the variant as a QJsonObject if the variant has userType() \l
1767 QJsonObject; otherwise returns a default constructed QJsonObject.
1768
1769 \sa canConvert(), convert()
1770*/
1771QJsonObject QVariant::toJsonObject() const
1772{
1773 return qvariant_cast<QJsonObject>(*this);
1774}
1775
1776/*!
1777 \since 5.0
1778
1779 Returns the variant as a QJsonArray if the variant has userType() \l
1780 QJsonArray; otherwise returns a default constructed QJsonArray.
1781
1782 \sa canConvert(), convert()
1783*/
1784QJsonArray QVariant::toJsonArray() const
1785{
1786 return qvariant_cast<QJsonArray>(*this);
1787}
1788
1789/*!
1790 \since 5.0
1791
1792 Returns the variant as a QJsonDocument if the variant has userType() \l
1793 QJsonDocument; otherwise returns a default constructed QJsonDocument.
1794
1795 \sa canConvert(), convert()
1796*/
1797QJsonDocument QVariant::toJsonDocument() const
1798{
1799 return qvariant_cast<QJsonDocument>(*this);
1800}
1801
1802/*!
1803 \fn QChar QVariant::toChar() const
1804
1805 Returns the variant as a QChar if the variant has userType()
1806 \l QMetaType::QChar, \l QMetaType::Int, or \l QMetaType::UInt; otherwise
1807 returns an invalid QChar.
1808
1809 \sa canConvert(), convert()
1810*/
1811QChar QVariant::toChar() const
1812{
1813 return qvariant_cast<QChar>(*this);
1814}
1815
1816/*!
1817 Returns the variant as a QBitArray if the variant has userType()
1818 \l QMetaType::QBitArray; otherwise returns an empty bit array.
1819
1820 \sa canConvert(), convert()
1821*/
1822QBitArray QVariant::toBitArray() const
1823{
1824 return qvariant_cast<QBitArray>(*this);
1825}
1826
1827template <typename T>
1828inline T qNumVariantToHelper(const QVariant::Private &d, bool *ok)
1829{
1830 QMetaType t = QMetaType::fromType<T>();
1831 if (ok)
1832 *ok = true;
1833
1834 if (d.type() == t)
1835 return d.get<T>();
1836
1837 T ret = 0;
1838 bool success = QMetaType::convert(d.type(), d.storage(), t, &ret);
1839 if (ok)
1840 *ok = success;
1841 return ret;
1842}
1843
1844/*!
1845 Returns the variant as an int if the variant has userType()
1846 \l QMetaType::Int, \l QMetaType::Bool, \l QMetaType::QByteArray,
1847 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::LongLong,
1848 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
1849 otherwise returns 0.
1850
1851 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1852 converted to an int; otherwise \c{*}\a{ok} is set to false.
1853
1854 \b{Warning:} If the value is convertible to a \l QMetaType::LongLong but is
1855 too large to be represented in an int, the resulting arithmetic overflow
1856 will not be reflected in \a ok. A simple workaround is to use
1857 QString::toInt().
1858
1859 \sa canConvert(), convert()
1860*/
1861int QVariant::toInt(bool *ok) const
1862{
1863 return qNumVariantToHelper<int>(d, ok);
1864}
1865
1866/*!
1867 Returns the variant as an unsigned int if the variant has userType()
1868 \l QMetaType::UInt, \l QMetaType::Bool, \l QMetaType::QByteArray,
1869 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
1870 \l QMetaType::LongLong, \l QMetaType::QString, or \l QMetaType::ULongLong;
1871 otherwise returns 0.
1872
1873 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1874 converted to an unsigned int; otherwise \c{*}\a{ok} is set to false.
1875
1876 \b{Warning:} If the value is convertible to a \l QMetaType::ULongLong but is
1877 too large to be represented in an unsigned int, the resulting arithmetic
1878 overflow will not be reflected in \a ok. A simple workaround is to use
1879 QString::toUInt().
1880
1881 \sa canConvert(), convert()
1882*/
1883uint QVariant::toUInt(bool *ok) const
1884{
1885 return qNumVariantToHelper<uint>(d, ok);
1886}
1887
1888/*!
1889 Returns the variant as a long long int if the variant has userType()
1890 \l QMetaType::LongLong, \l QMetaType::Bool, \l QMetaType::QByteArray,
1891 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
1892 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
1893 otherwise returns 0.
1894
1895 If \a ok is non-null: \c{*}\c{ok} is set to true if the value could be
1896 converted to an int; otherwise \c{*}\c{ok} is set to false.
1897
1898 \sa canConvert(), convert()
1899*/
1900qlonglong QVariant::toLongLong(bool *ok) const
1901{
1902 return qNumVariantToHelper<qlonglong>(d, ok);
1903}
1904
1905/*!
1906 Returns the variant as an unsigned long long int if the
1907 variant has metaType() \l QMetaType::ULongLong, \l QMetaType::Bool,
1908 \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::Double,
1909 \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString, or
1910 \l QMetaType::UInt; otherwise returns 0.
1911
1912 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1913 converted to an int; otherwise \c{*}\a{ok} is set to false.
1914
1915 \sa canConvert(), convert()
1916*/
1917qulonglong QVariant::toULongLong(bool *ok) const
1918{
1919 return qNumVariantToHelper<qulonglong>(d, ok);
1920}
1921
1922/*!
1923 Returns the variant as a bool if the variant has userType() Bool.
1924
1925 Returns \c true if the variant has userType() \l QMetaType::Bool,
1926 \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
1927 \l QMetaType::LongLong, \l QMetaType::UInt, or \l QMetaType::ULongLong and
1928 the value is non-zero, or if the variant has type \l QMetaType::QString or
1929 \l QMetaType::QByteArray and its lower-case content is not one of the
1930 following: empty, "0" or "false"; otherwise returns \c false.
1931
1932 \sa canConvert(), convert()
1933*/
1934bool QVariant::toBool() const
1935{
1936 auto boolType = QMetaType::fromType<bool>();
1937 if (d.type() == boolType)
1938 return d.get<bool>();
1939
1940 bool res = false;
1941 QMetaType::convert(d.type(), constData(), boolType, &res);
1942 return res;
1943}
1944
1945/*!
1946 Returns the variant as a double if the variant has userType()
1947 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
1948 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
1949 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
1950 otherwise returns 0.0.
1951
1952 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1953 converted to a double; otherwise \c{*}\a{ok} is set to false.
1954
1955 \sa canConvert(), convert()
1956*/
1957double QVariant::toDouble(bool *ok) const
1958{
1959 return qNumVariantToHelper<double>(d, ok);
1960}
1961
1962/*!
1963 Returns the variant as a float if the variant has userType()
1964 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
1965 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
1966 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
1967 otherwise returns 0.0.
1968
1969 \since 4.6
1970
1971 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1972 converted to a double; otherwise \c{*}\a{ok} is set to false.
1973
1974 \sa canConvert(), convert()
1975*/
1976float QVariant::toFloat(bool *ok) const
1977{
1978 return qNumVariantToHelper<float>(d, ok);
1979}
1980
1981/*!
1982 Returns the variant as a qreal if the variant has userType()
1983 \l QMetaType::Double, \l QMetaType::Float, \l QMetaType::Bool,
1984 \l QMetaType::QByteArray, \l QMetaType::Int, \l QMetaType::LongLong,
1985 \l QMetaType::QString, \l QMetaType::UInt, or \l QMetaType::ULongLong;
1986 otherwise returns 0.0.
1987
1988 \since 4.6
1989
1990 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
1991 converted to a double; otherwise \c{*}\a{ok} is set to false.
1992
1993 \sa canConvert(), convert()
1994*/
1995qreal QVariant::toReal(bool *ok) const
1996{
1997 return qNumVariantToHelper<qreal>(d, ok);
1998}
1999
2000/*!
2001 Returns the variant as a QVariantList if the variant has userType() \l
2002 QMetaType::QVariantList. If it doesn't, QVariant will attempt to convert
2003 the type to a list and then return it. This will succeed for any type that
2004 has registered a converter to QVariantList or which was declared as a
2005 sequential container using \l{Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE}. If
2006 none of those conditions are true, this function will return an empty
2007 list.
2008
2009 \sa canConvert(), convert()
2010*/
2011QVariantList QVariant::toList() const
2012{
2013 return qvariant_cast<QVariantList>(*this);
2014}
2015
2016/*!
2017 \fn bool QVariant::canConvert(int targetTypeId) const
2018 \overload
2019 \deprecated [6.0] Use \c canConvert(QMetaType(targetTypeId)) instead.
2020
2021 \sa QMetaType::canConvert()
2022*/
2023
2024/*!
2025 \fn bool QVariant::canConvert(QMetaType type) const
2026 \since 6.0
2027
2028 Returns \c true if the variant's type can be cast to the requested
2029 type, \a type. Such casting is done automatically when calling the
2030 toInt(), toBool(), ... methods.
2031
2032 Note this function operates only on the variant's type, not the contents.
2033 It indicates whether there is a conversion path from this variant to \a
2034 type, not that the conversion will succeed when attempted.
2035
2036 \sa QMetaType::canConvert()
2037*/
2038
2039
2040/*!
2041 \fn bool QVariant::convert(int targetTypeId)
2042 \deprecated [6.0] Use \c convert(QMetaType(targetTypeId)) instead.
2043
2044 Casts the variant to the requested type, \a targetTypeId. If the cast cannot be
2045 done, the variant is still changed to the requested type, but is left in a cleared
2046 null state similar to that constructed by QVariant(Type).
2047
2048 Returns \c true if the current type of the variant was successfully cast;
2049 otherwise returns \c false.
2050
2051 A QVariant containing a pointer to a type derived from QObject will also convert
2052 and return true for this function if a qobject_cast to the type described
2053 by \a targetTypeId would succeed. Note that this only works for QObject subclasses
2054 which use the Q_OBJECT macro.
2055
2056 \note converting QVariants that are null due to not being initialized or having
2057 failed a previous conversion will always fail, changing the type, remaining null,
2058 and returning \c false.
2059
2060 \sa canConvert(), clear()
2061*/
2062
2063/*!
2064 Casts the variant to the requested type, \a targetType. If the cast cannot be
2065 done, the variant is still changed to the requested type, but is left in a cleared
2066 null state similar to that constructed by QVariant(Type).
2067
2068 Returns \c true if the current type of the variant was successfully cast;
2069 otherwise returns \c false.
2070
2071 A QVariant containing a pointer to a type derived from QObject will also convert
2072 and return true for this function if a qobject_cast to the type described
2073 by \a targetType would succeed. Note that this only works for QObject subclasses
2074 which use the Q_OBJECT macro.
2075
2076 \note converting QVariants that are null due to not being initialized or having
2077 failed a previous conversion will always fail, changing the type, remaining null,
2078 and returning \c false.
2079
2080 \since 6.0
2081
2082 \sa canConvert(), clear()
2083*/
2084
2085bool QVariant::convert(QMetaType targetType)
2086{
2087 if (d.type() == targetType)
2088 return targetType.isValid();
2089
2090 QVariant oldValue = *this;
2091
2092 clear();
2093 create(targetType, nullptr);
2094 if (!oldValue.canConvert(targetType))
2095 return false;
2096
2097 // Fail if the value is not initialized or was forced null by a previous failed convert.
2098 if (oldValue.d.is_null && oldValue.d.type().id() != QMetaType::Nullptr)
2099 return false;
2100
2101 bool ok = QMetaType::convert(oldValue.d.type(), oldValue.constData(), targetType, data());
2102 d.is_null = !ok;
2103 return ok;
2104}
2105
2106/*!
2107 \fn bool QVariant::convert(int type, void *ptr) const
2108 \internal
2109 Created for qvariant_cast() usage
2110*/
2111bool QVariant::convert(int type, void *ptr) const
2112{
2113 return QMetaType::convert(d.type(), constData(), QMetaType(type), ptr);
2114}
2115
2116/*!
2117 \internal
2118*/
2119bool QVariant::view(int type, void *ptr)
2120{
2121 return QMetaType::view(d.type(), data(), QMetaType(type), ptr);
2122}
2123
2124/*!
2125 \fn bool QVariant::operator==(const QVariant &lhs, const QVariant &rhs)
2126
2127 Returns \c true if \a lhs and \a rhs are equal; otherwise returns \c false.
2128
2129 QVariant uses the equality operator of the metaType() contained to check for
2130 equality.
2131
2132 Variants of different types will always compare as not equal with a few
2133 exceptions:
2134
2135 \list
2136 \li If both types are numeric types (integers and floatins point numbers)
2137 Qt will compare those types using standard C++ type promotion rules.
2138 \li If one type is numeric and the other one a QString, Qt will try to
2139 convert the QString to a matching numeric type and if successful compare
2140 those.
2141 \li If both variants contain pointers to QObject derived types, QVariant
2142 will check whether the types are related and point to the same object.
2143 \endlist
2144
2145 The result of the function is not affected by the result of QVariant::isNull,
2146 which means that two values can be equal even if one of them is null and
2147 another is not.
2148*/
2149
2150/*!
2151 \fn bool QVariant::operator!=(const QVariant &lhs, const QVariant &rhs)
2152
2153 Returns \c false if \a lhs and \a rhs are equal; otherwise returns \c true.
2154
2155 QVariant uses the equality operator of the metaType() contained to check for
2156 equality.
2157
2158 Variants of different types will always compare as not equal with a few
2159 exceptions:
2160
2161 \list
2162 \li If both types are numeric types (integers and floatins point numbers)
2163 Qt will compare those types using standard C++ type promotion rules.
2164 \li If one type is numeric and the other one a QString, Qt will try to
2165 convert the QString to a matching numeric type and if successful compare
2166 those.
2167 \li If both variants contain pointers to QObject derived types, QVariant
2168 will check whether the types are related and point to the same object.
2169 \endlist
2170*/
2171
2172static bool qIsNumericType(uint tp)
2173{
2174 static const qulonglong numericTypeBits =
2175 Q_UINT64_C(1) << QMetaType::QString |
2176 Q_UINT64_C(1) << QMetaType::Bool |
2177 Q_UINT64_C(1) << QMetaType::Double |
2178 Q_UINT64_C(1) << QMetaType::Float16 |
2179 Q_UINT64_C(1) << QMetaType::Float |
2180 Q_UINT64_C(1) << QMetaType::Char |
2181 Q_UINT64_C(1) << QMetaType::Char16 |
2182 Q_UINT64_C(1) << QMetaType::Char32 |
2183 Q_UINT64_C(1) << QMetaType::SChar |
2184 Q_UINT64_C(1) << QMetaType::UChar |
2185 Q_UINT64_C(1) << QMetaType::Short |
2186 Q_UINT64_C(1) << QMetaType::UShort |
2187 Q_UINT64_C(1) << QMetaType::Int |
2188 Q_UINT64_C(1) << QMetaType::UInt |
2189 Q_UINT64_C(1) << QMetaType::Long |
2190 Q_UINT64_C(1) << QMetaType::ULong |
2191 Q_UINT64_C(1) << QMetaType::LongLong |
2192 Q_UINT64_C(1) << QMetaType::ULongLong;
2193 return tp < (CHAR_BIT * sizeof numericTypeBits) ? numericTypeBits & (Q_UINT64_C(1) << tp) : false;
2194}
2195
2196static bool qIsFloatingPoint(uint tp)
2197{
2198 return tp == QMetaType::Double || tp == QMetaType::Float || tp == QMetaType::Float16;
2199}
2200
2202 const QtPrivate::QMetaTypeInterface *iface2)
2203{
2204 if (!iface1 || !iface2)
2205 return false;
2206
2207 // We don't need QMetaType::id() here because the type Id is always stored
2208 // directly for all built-in types.
2209 bool isNumeric1 = qIsNumericType(iface1->typeId);
2210 bool isNumeric2 = qIsNumericType(iface2->typeId);
2211
2212 // if they're both numeric (or QString), then they can be compared
2213 if (isNumeric1 && isNumeric2)
2214 return true;
2215
2216 bool isEnum1 = iface1->flags & QMetaType::IsEnumeration;
2217 bool isEnum2 = iface2->flags & QMetaType::IsEnumeration;
2218
2219 // if both are enums, we can only compare if they are the same enum
2220 // (the language does allow comparing two different enum types, but that's
2221 // usually considered poor coding and produces a warning)
2222 if (isEnum1 && isEnum2)
2223 return QMetaType(iface1) == QMetaType(iface2);
2224
2225 // if one is an enum and the other is a numeric, we can compare too
2226 if (isEnum1 && isNumeric2)
2227 return true;
2228 if (isNumeric1 && isEnum2)
2229 return true;
2230
2231 // we need at least one enum and one numeric...
2232 return false;
2233}
2234
2236 const QtPrivate::QMetaTypeInterface *iface2)
2237{
2238 Q_ASSERT(canBeNumericallyCompared(iface1, iface2));
2239
2240 // We don't need QMetaType::id() here because the type Id is always stored
2241 // directly for the types we're comparing against below.
2242 uint t1 = iface1->typeId;
2243 uint t2 = iface2->typeId;
2244
2245 if ((t1 == QMetaType::Bool && t2 == QMetaType::QString) ||
2246 (t2 == QMetaType::Bool && t1 == QMetaType::QString))
2247 return QMetaType::Bool;
2248
2249 // C++ integral ranks: (4.13 Integer conversion rank [conv.rank])
2250 // bool < signed char < short < int < long < long long
2251 // unsigneds have the same rank as their signed counterparts
2252 // C++ integral promotion rules (4.5 Integral Promotions [conv.prom])
2253 // - any type with rank less than int can be converted to int or unsigned int
2254 // 5 Expressions [expr] paragraph 9:
2255 // - if either operand is double, the other shall be converted to double
2256 // - " " float, " " " float
2257 // - if both operands have the same type, no further conversion is needed.
2258 // - if both are signed or if both are unsigned, convert to the one with highest rank
2259 // - if the unsigned has higher or same rank, convert the signed to the unsigned one
2260 // - if the signed can represent all values of the unsigned, convert to the signed
2261 // - otherwise, convert to the unsigned corresponding to the rank of the signed
2262
2263 // floating point: we deviate from the C++ standard by always using qreal
2264 if (qIsFloatingPoint(t1) || qIsFloatingPoint(t2))
2265 return QMetaType::QReal;
2266
2267 auto isUnsigned = [](uint tp) {
2268 // only types for which sizeof(T) >= sizeof(int); lesser ones promote to int
2269 return tp == QMetaType::ULongLong || tp == QMetaType::ULong ||
2270 tp == QMetaType::UInt || tp == QMetaType::Char32;
2271 };
2272 bool isUnsigned1 = isUnsigned(t1);
2273 bool isUnsigned2 = isUnsigned(t2);
2274
2275 // integral rules:
2276 // 1) if either type is a 64-bit unsigned, compare as 64-bit unsigned
2277 if (isUnsigned1 && iface1->size > sizeof(int))
2278 return QMetaType::ULongLong;
2279 if (isUnsigned2 && iface2->size > sizeof(int))
2280 return QMetaType::ULongLong;
2281
2282 // 2) if either type is 64-bit, compare as 64-bit signed
2283 if (iface1->size > sizeof(int) || iface2->size > sizeof(int))
2284 return QMetaType::LongLong;
2285
2286 // 3) if either type is 32-bit unsigned, compare as 32-bit unsigned
2287 if (isUnsigned1 || isUnsigned2)
2288 return QMetaType::UInt;
2289
2290 // 4) otherwise, just do int promotion
2291 return QMetaType::Int;
2292}
2293
2294static QPartialOrdering integralCompare(uint promotedType, const QVariant::Private *d1, const QVariant::Private *d2)
2295{
2296 // use toLongLong to retrieve the data, it gets us all the bits
2297 std::optional<qlonglong> l1 = qConvertToNumber(d1, promotedType == QMetaType::Bool);
2298 std::optional<qlonglong> l2 = qConvertToNumber(d2, promotedType == QMetaType::Bool);
2299 if (!l1 || !l2)
2300 return QPartialOrdering::Unordered;
2301 if (promotedType == QMetaType::UInt)
2302 return Qt::compareThreeWay(uint(*l1), uint(*l2));
2303 if (promotedType == QMetaType::LongLong)
2304 return Qt::compareThreeWay(qlonglong(*l1), qlonglong(*l2));
2305 if (promotedType == QMetaType::ULongLong)
2306 return Qt::compareThreeWay(qulonglong(*l1), qulonglong(*l2));
2307
2308 return Qt::compareThreeWay(int(*l1), int(*l2));
2309}
2310
2311static QPartialOrdering numericCompare(const QVariant::Private *d1, const QVariant::Private *d2)
2312{
2313 uint promotedType = numericTypePromotion(d1->typeInterface(), d2->typeInterface());
2314 if (promotedType != QMetaType::QReal)
2315 return integralCompare(promotedType, d1, d2);
2316
2317 // floating point comparison
2318 const auto r1 = qConvertToRealNumber(d1);
2319 const auto r2 = qConvertToRealNumber(d2);
2320 if (!r1 || !r2)
2321 return QPartialOrdering::Unordered;
2322
2323 return Qt::compareThreeWay(*r1, *r2);
2324}
2325
2326static bool qvCanConvertMetaObject(QMetaType fromType, QMetaType toType)
2327{
2328 if ((fromType.flags() & QMetaType::PointerToQObject)
2329 && (toType.flags() & QMetaType::PointerToQObject)) {
2330 const QMetaObject *f = fromType.metaObject();
2331 const QMetaObject *t = toType.metaObject();
2332 return f && t && (f->inherits(t) || t->inherits(f));
2333 }
2334 return false;
2335}
2336
2337static QPartialOrdering pointerCompare(const QVariant::Private *d1, const QVariant::Private *d2)
2338{
2339 return Qt::compareThreeWay(Qt::totally_ordered_wrapper(d1->get<QObject *>()),
2340 Qt::totally_ordered_wrapper(d2->get<QObject *>()));
2341}
2342
2343/*!
2344 \internal
2345 */
2346bool QVariant::equals(const QVariant &v) const
2347{
2348 auto metatype = d.type();
2349
2350 if (metatype != v.metaType()) {
2351 // try numeric comparisons, with C++ type promotion rules (no conversion)
2352 if (canBeNumericallyCompared(metatype.iface(), v.d.type().iface()))
2353 return numericCompare(&d, &v.d) == QPartialOrdering::Equivalent;
2354 // if both types are related pointers to QObjects, check if they point to the same object
2355 if (qvCanConvertMetaObject(metatype, v.metaType()))
2356 return pointerCompare(&d, &v.d) == QPartialOrdering::Equivalent;
2357 return false;
2358 }
2359
2360 // For historical reasons: QVariant() == QVariant()
2361 if (!metatype.isValid())
2362 return true;
2363
2364 return metatype.equals(d.storage(), v.d.storage());
2365}
2366
2367/*!
2368 Compares the objects at \a lhs and \a rhs for ordering.
2369
2370 Returns QPartialOrdering::Unordered if comparison is not supported
2371 or the values are unordered. Otherwise, returns
2372 QPartialOrdering::Less, QPartialOrdering::Equivalent or
2373 QPartialOrdering::Greater if \a lhs is less than, equivalent
2374 to or greater than \a rhs, respectively.
2375
2376 If the variants contain data with a different metatype, the values are considered
2377 unordered unless they are both of numeric or pointer types, where regular numeric or
2378 pointer comparison rules will be used.
2379 \note: If a numeric comparison is done and at least one value is NaN, QPartialOrdering::Unordered
2380 is returned.
2381
2382 If both variants contain data of the same metatype, the method will use the
2383 QMetaType::compare method to determine the ordering of the two variants, which can
2384 also indicate that it can't establish an ordering between the two values.
2385
2386 \since 6.0
2387 \sa QMetaType::compare(), QMetaType::isOrdered()
2388*/
2389QPartialOrdering QVariant::compare(const QVariant &lhs, const QVariant &rhs)
2390{
2391 QMetaType t = lhs.d.type();
2392 if (t != rhs.d.type()) {
2393 // try numeric comparisons, with C++ type promotion rules (no conversion)
2394 if (canBeNumericallyCompared(lhs.d.type().iface(), rhs.d.type().iface()))
2395 return numericCompare(&lhs.d, &rhs.d);
2396 if (qvCanConvertMetaObject(lhs.metaType(), rhs.metaType()))
2397 return pointerCompare(&lhs.d, &rhs.d);
2398 return QPartialOrdering::Unordered;
2399 }
2400 return t.compare(lhs.constData(), rhs.constData());
2401}
2402
2403/*!
2404 \fn const void *QVariant::constData() const
2405 \fn const void* QVariant::data() const
2406
2407 Returns a pointer to the contained object as a generic void* that cannot be
2408 written to.
2409
2410 \sa get_if(), QMetaType
2411 */
2412
2413/*!
2414 Returns a pointer to the contained object as a generic void* that can be
2415 written to.
2416
2417 This function detaches the QVariant. When called on a \l{isNull}{null-QVariant},
2418 the QVariant will not be null after the call.
2419
2420 \sa get_if(), QMetaType
2421*/
2422void *QVariant::data()
2423{
2424 detach();
2425 // set is_null to false, as the caller is likely to write some data into this variant
2426 d.is_null = false;
2427 return const_cast<void *>(constData());
2428}
2429
2430/*!
2431 \since 6.6
2432 \fn template <typename T> const T* QVariant::get_if(const QVariant *v)
2433 \fn template <typename T> T* QVariant::get_if(QVariant *v)
2434
2435 If \a v contains an object of type \c T, returns a pointer to the contained
2436 object, otherwise returns \nullptr.
2437
2438 The overload taking a mutable \a v detaches \a v: When called on a
2439 \l{isNull()}{null} \a v with matching type \c T, \a v will not be null
2440 after the call.
2441
2442 These functions are provided for compatibility with \c{std::variant}.
2443
2444 \sa data()
2445*/
2446
2447/*!
2448 \since 6.6
2449 \fn template <typename T> T &QVariant::get(QVariant &v)
2450 \fn template <typename T> const T &QVariant::get(const QVariant &v)
2451 \fn template <typename T> T &&QVariant::get(QVariant &&v)
2452 \fn template <typename T> const T &&QVariant::get(const QVariant &&v)
2453
2454 If \a v contains an object of type \c T, returns a reference to the contained
2455 object, otherwise the call has undefined behavior.
2456
2457 The overloads taking a mutable \a v detach \a v: When called on a
2458 \l{isNull()}{null} \a v with matching type \c T, \a v will not be null
2459 after the call.
2460
2461 These functions are provided for compatibility with \c{std::variant}.
2462
2463 \sa get_if(), data()
2464*/
2465
2466/*!
2467 Returns \c true if this is a null variant, false otherwise.
2468
2469 A variant is considered null if it contains no initialized value or a null pointer.
2470
2471 \note This behavior has been changed from Qt 5, where isNull() would also
2472 return true if the variant contained an object of a builtin type with an isNull()
2473 method that returned true for that object.
2474
2475 \sa convert()
2476*/
2477bool QVariant::isNull() const
2478{
2479 if (d.is_null || !metaType().isValid())
2480 return true;
2481 if (metaType().flags() & QMetaType::IsPointer)
2482 return d.get<void *>() == nullptr;
2483 return false;
2484}
2485
2486#ifndef QT_NO_DEBUG_STREAM
2487QDebug QVariant::qdebugHelper(QDebug dbg) const
2488{
2489 QDebugStateSaver saver(dbg);
2490 const uint typeId = d.type().id();
2491 dbg.nospace() << "QVariant(";
2492 if (typeId != QMetaType::UnknownType) {
2493 dbg << d.type().name() << ", ";
2494 bool streamed = d.type().debugStream(dbg, d.storage());
2495 if (!streamed && canConvert<QString>())
2496 dbg << toString();
2497 } else {
2498 dbg << "Invalid";
2499 }
2500 dbg << ')';
2501 return dbg;
2502}
2503
2504QVariant QVariant::moveConstruct(QMetaType type, void *data)
2505{
2506 QVariant var;
2507 var.d = QVariant::Private(type.d_ptr);
2508 customConstruct<ForceMove, NonNull>(type.d_ptr, &var.d, data);
2509 return var;
2510}
2511
2512QVariant QVariant::copyConstruct(QMetaType type, const void *data)
2513{
2514 QVariant var;
2515 var.d = QVariant::Private(type.d_ptr);
2516 customConstruct<UseCopy, NonNull>(type.d_ptr, &var.d, data);
2517 return var;
2518}
2519
2520#if QT_DEPRECATED_SINCE(6, 0)
2521QT_WARNING_PUSH
2522QT_WARNING_DISABLE_DEPRECATED
2523
2524QDebug operator<<(QDebug dbg, const QVariant::Type p)
2525{
2526 QDebugStateSaver saver(dbg);
2527 dbg.nospace() << "QVariant::"
2528 << (int(p) != int(QMetaType::UnknownType)
2529 ? QMetaType(p).name()
2530 : "Invalid");
2531 return dbg;
2532}
2533
2534QT_WARNING_POP
2535#endif
2536
2537#endif
2538
2539/*! \fn template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, QVariant>>> void QVariant::setValue(T &&value)
2540
2541 Stores a copy of \a value. If \c{T} is a type that QVariant
2542 doesn't support, QMetaType is used to store the value. A compile
2543 error will occur if QMetaType doesn't handle the type.
2544
2545 Example:
2546
2547 \snippet code/src_corelib_kernel_qvariant.cpp 4
2548
2549 \sa value(), fromValue(), canConvert()
2550 */
2551
2552/*! \fn void QVariant::setValue(const QVariant &value)
2553
2554 Copies \a value over this QVariant. It is equivalent to simply
2555 assigning \a value to this QVariant.
2556*/
2557
2558/*! \fn void QVariant::setValue(QVariant &&value)
2559
2560 Moves \a value over this QVariant. It is equivalent to simply
2561 move assigning \a value to this QVariant.
2562*/
2563
2564/*! \fn template<typename T> T QVariant::value() const &
2565
2566 Returns the stored value converted to the template type \c{T}.
2567 Call canConvert() to find out whether a type can be converted.
2568 If the value cannot be converted, a \l{default-constructed value}
2569 will be returned.
2570
2571 If the type \c{T} is supported by QVariant, this function behaves
2572 exactly as toString(), toInt() etc.
2573
2574 Example:
2575
2576 \snippet code/src_corelib_kernel_qvariant.cpp 5
2577
2578 If the QVariant contains a pointer to a type derived from QObject then
2579 \c{T} may be any QObject type. If the pointer stored in the QVariant can be
2580 qobject_cast to T, then that result is returned. Otherwise \nullptr is
2581 returned. Note that this only works for QObject subclasses which use
2582 the Q_OBJECT macro.
2583
2584 If the QVariant contains a sequential container and \c{T} is QVariantList, the
2585 elements of the container will be converted into \l {QVariant}s and returned as a QVariantList.
2586
2587 \snippet code/src_corelib_kernel_qvariant.cpp 9
2588
2589 \sa setValue(), fromValue(), canConvert(), Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE()
2590*/
2591
2592/*! \fn template<typename T> T QVariant::view()
2593
2594 Returns a mutable view of template type \c{T} on the stored value.
2595 Call canView() to find out whether such a view is supported.
2596 If no such view can be created, returns the stored value converted to the
2597 template type \c{T}. Call canConvert() to find out whether a type can be
2598 converted. If the value can neither be viewed nor converted, a
2599 \l{default-constructed value} will be returned.
2600
2601 \sa canView(), Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE()
2602*/
2603
2604/*! \fn template<typename T> bool QVariant::canConvert() const
2605
2606 Returns \c true if the variant can be converted to the template type \c{T},
2607 otherwise false.
2608
2609 Example:
2610
2611 \snippet code/src_corelib_kernel_qvariant.cpp 6
2612
2613 A QVariant containing a pointer to a type derived from QObject will also return true for this
2614 function if a qobject_cast to the template type \c{T} would succeed. Note that this only works
2615 for QObject subclasses which use the Q_OBJECT macro.
2616
2617 \sa convert()
2618*/
2619
2620/*! \fn template<typename T> bool QVariant::canView() const
2621
2622 Returns \c true if a mutable view of the template type \c{T} can be created on this variant,
2623 otherwise \c false.
2624
2625 \sa value()
2626*/
2627
2628/*! \fn template<typename T> static QVariant QVariant::fromValue(const T &value)
2629
2630 Returns a QVariant containing a copy of \a value. Behaves
2631 exactly like setValue() otherwise.
2632
2633 Example:
2634
2635 \snippet code/src_corelib_kernel_qvariant.cpp 7
2636
2637 \sa setValue(), value()
2638*/
2639
2640/*! \fn template<typename T, QVariant::if_rvalue<T> = true> static QVariant QVariant::fromValue(T &&value)
2641
2642 \since 6.6
2643 \overload
2644*/
2645
2646/*! \fn template<typename... Types> QVariant QVariant::fromStdVariant(const std::variant<Types...> &value)
2647 \since 5.11
2648
2649 Returns a QVariant with the type and value of the active variant of \a value. If
2650 the active type is std::monostate a default QVariant is returned.
2651
2652 \note With this method you do not need to register the variant as a Qt metatype,
2653 since the std::variant is resolved before being stored. The component types
2654 should be registered however.
2655
2656 \sa fromValue()
2657*/
2658
2659/*!
2660 \fn template<typename... Types> QVariant QVariant::fromStdVariant(std::variant<Types...> &&value)
2661 \since 6.6
2662 \overload
2663*/
2664
2665
2666/*!
2667 \since 6.7
2668
2669 Creates a variant of type \a type, and initializes it with
2670 a copy of \c{*copy} if \a copy is not \nullptr (in which case, \a copy
2671 must point to an object of type \a type).
2672
2673 Note that you have to pass the address of the object you want stored.
2674
2675 Usually, you never have to use this constructor, use QVariant::fromValue()
2676 instead to construct variants from the pointer types represented by
2677 \c QMetaType::VoidStar, and \c QMetaType::QObjectStar.
2678
2679 If \a type does not support copy construction and \a copy is not \nullptr,
2680 the variant will be invalid. Similarly, if \a copy is \nullptr and
2681 \a type does not support default construction, the variant will be
2682 invalid.
2683
2684 Returns the QVariant created as described above.
2685
2686 \sa QVariant::fromValue(), QMetaType::Type
2687*/
2688QVariant QVariant::fromMetaType(QMetaType type, const void *copy)
2689{
2690 QVariant result;
2691 type.registerType();
2692 const auto iface = type.iface();
2693 if (isValidMetaTypeForVariant(iface, copy)) {
2694 result.d = Private(iface);
2695 customConstruct(iface, &result.d, copy);
2696 }
2697 return result;
2698}
2699
2700/*!
2701 \fn template<typename T> T qvariant_cast(const QVariant &value)
2702 \relates QVariant
2703
2704 Returns the given \a value converted to the template type \c{T}.
2705
2706 This function is equivalent to QVariant::value().
2707
2708 \sa QVariant::value()
2709*/
2710
2711/*!
2712 \fn template<typename T> T QVariant::qvariant_cast(QVariant &&value)
2713 \overload
2714 \since 6.7
2715
2716 Returns the given \a value converted to the template type \c{T}.
2717*/
2718
2719/*! \fn template<typename T> T qVariantValue(const QVariant &value)
2720 \relates QVariant
2721 \deprecated
2722
2723 Returns the given \a value converted to the template type \c{T}.
2724
2725 This function is equivalent to
2726 \l{QVariant::value()}{QVariant::value}<T>(\a value).
2727
2728 \note This function was provided as a workaround for MSVC 6
2729 which did not support member template functions. It is advised
2730 to use the other form in new code.
2731
2732 \sa QVariant::value(), qvariant_cast()
2733*/
2734
2735/*! \fn bool qVariantCanConvert(const QVariant &value)
2736 \relates QVariant
2737 \deprecated
2738
2739 Returns \c true if the given \a value can be converted to the
2740 template type specified; otherwise returns \c false.
2741
2742 This function is equivalent to QVariant::canConvert(\a value).
2743
2744 \note This function was provided as a workaround for MSVC 6
2745 which did not support member template functions. It is advised
2746 to use the other form in new code.
2747
2748 \sa QVariant::canConvert()
2749*/
2750
2751/*!
2752 \typedef QVariantList
2753 \relates QVariant
2754
2755 Synonym for QList<QVariant>.
2756*/
2757
2758/*!
2759 \typedef QVariantMap
2760 \relates QVariant
2761
2762 Synonym for QMap<QString, QVariant>.
2763*/
2764
2765/*!
2766 \typedef QVariantHash
2767 \relates QVariant
2768 \since 4.5
2769
2770 Synonym for QHash<QString, QVariant>.
2771*/
2772
2773/*!
2774 \typedef QVariant::DataPtr
2775 \internal
2776*/
2777/*! \typedef QVariant::f_construct
2778 \internal
2779*/
2780
2781/*! \typedef QVariant::f_clear
2782 \internal
2783*/
2784
2785/*! \typedef QVariant::f_null
2786 \internal
2787*/
2788
2789/*! \typedef QVariant::f_load
2790 \internal
2791*/
2792
2793/*! \typedef QVariant::f_save
2794 \internal
2795*/
2796
2797/*! \typedef QVariant::f_compare
2798 \internal
2799*/
2800
2801/*! \typedef QVariant::f_convert
2802 \internal
2803*/
2804
2805/*! \typedef QVariant::f_canConvert
2806 \internal
2807*/
2808
2809/*! \typedef QVariant::f_debugStream
2810 \internal
2811*/
2812
2813/*!
2814 \fn DataPtr &QVariant::data_ptr()
2815 \internal
2816*/
2817
2818/*!
2819 \fn const DataPtr &QVariant::data_ptr() const
2820 \internal
2821*/
2822
2823/*!
2824 \internal
2825 */
2826const void *QtPrivate::QVariantTypeCoercer::convert(const QVariant &value, const QMetaType &type)
2827{
2828 if (type == QMetaType::fromType<QVariant>())
2829 return &value;
2830
2831 if (type == value.metaType())
2832 return value.constData();
2833
2834 if (value.canConvert(type)) {
2835 converted = value;
2836 if (converted.convert(type))
2837 return converted.constData();
2838 }
2839
2840 return nullptr;
2841}
2842
2843/*!
2844 \internal
2845 */
2846const void *QtPrivate::QVariantTypeCoercer::coerce(const QVariant &value, const QMetaType &type)
2847{
2848 if (const void *result = convert(value, type))
2849 return result;
2850
2851 converted = QVariant(type);
2852 return converted.constData();
2853}
2854
2855/*!
2856 \class QVariantRef
2857 \since 6.0
2858 \inmodule QtCore
2859 \brief The QVariantRef acts as a non-const reference to a QVariant.
2860
2861 As the generic iterators don't actually instantiate a QVariant on each
2862 step, they cannot return a reference to one from operator*(). QVariantRef
2863 provides the same functionality as an actual reference to a QVariant would,
2864 but is backed by a pointer given as template parameter. The template is
2865 implemented for pointers of type QSequentialIterator and
2866 QAssociativeIterator.
2867*/
2868
2869/*!
2870 \fn template<typename Pointer> QVariantRef<Pointer>::QVariantRef(const Pointer *pointer)
2871
2872 Creates a QVariantRef from an \a pointer.
2873 */
2874
2875/*!
2876 \fn template<typename Pointer> QVariantRef<Pointer> &QVariantRef<Pointer>::operator=(const QVariant &value)
2877
2878 Assigns a new \a value to the value pointed to by the pointer this
2879 QVariantRef refers to.
2880 */
2881
2882/*!
2883 \fn template<typename Pointer> QVariantRef<Pointer> &QVariantRef<Pointer>::operator=(const QVariantRef &value)
2884
2885 Assigns a new \a value to the value pointed to by the pointer this
2886 QVariantRef refers to.
2887 */
2888
2889/*!
2890 \fn template<typename Pointer> QVariantRef<Pointer> &QVariantRef<Pointer>::operator=(QVariantRef &&value)
2891
2892 Assigns a new \a value to the value pointed to by the pointer this
2893 QVariantRef refers to.
2894*/
2895
2896/*!
2897 \fn template<typename Pointer> QVariantRef<Pointer>::operator QVariant() const
2898
2899 Resolves the QVariantRef to an actual QVariant.
2900*/
2901
2902/*!
2903 \fn template<typename Pointer> void swap(QVariantRef<Pointer> a, QVariantRef<Pointer> b)
2904
2905 Swaps the values pointed to by the pointers the QVariantRefs
2906 \a a and \a b refer to.
2907*/
2908
2909/*!
2910 \class QVariantConstPointer
2911 \since 6.0
2912 \inmodule QtCore
2913 \brief Emulated const pointer to QVariant based on a pointer.
2914
2915 QVariantConstPointer wraps a QVariant and returns it from its operator*().
2916 This makes it suitable as replacement for an actual const pointer. We cannot
2917 return an actual const pointer from generic iterators as the iterators don't
2918 hold an actual QVariant.
2919*/
2920
2921/*!
2922 Constructs a QVariantConstPointer from a \a variant.
2923 */
2924QVariantConstPointer::QVariantConstPointer(QVariant variant)
2925 : m_variant(std::move(variant))
2926{
2927}
2928
2929/*!
2930 Dereferences the QVariantConstPointer to retrieve its internal QVariant.
2931 */
2932QVariant QVariantConstPointer::operator*() const
2933{
2934 return m_variant;
2935}
2936
2937/*!
2938 Returns a const pointer to the QVariant, conforming to the
2939 conventions for operator->().
2940 */
2941const QVariant *QVariantConstPointer::operator->() const
2942{
2943 return &m_variant;
2944}
2945
2946/*!
2947 \class QVariantPointer
2948 \since 6.0
2949 \inmodule QtCore
2950 \brief QVariantPointer is a template class that emulates a pointer to QVariant based on a pointer.
2951
2952 QVariantConstPointer wraps a pointer and returns QVariantRef to it from its
2953 operator*(). This makes it suitable as replacement for an actual pointer. We
2954 cannot return an actual pointer from generic iterators as the iterators don't
2955 hold an actual QVariant.
2956*/
2957
2958/*!
2959 \fn template<typename Pointer> QVariantPointer<Pointer>::QVariantPointer(const Pointer *pointer)
2960
2961 Constructs a QVariantPointer from the given \a pointer.
2962 */
2963
2964/*!
2965 \fn template<typename Pointer> QVariantRef<Pointer> QVariantPointer<Pointer>::operator*() const
2966
2967 Dereferences the QVariantPointer to a QVariantRef.
2968 */
2969
2970/*!
2971 \fn template<typename Pointer> Pointer QVariantPointer<Pointer>::operator->() const
2972
2973 Dereferences and returns the pointer. The pointer is expected to also
2974 implement operator->().
2975 */
2976
2977QT_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:48
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)