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