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