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::SChar |
2315 Q_UINT64_C(1) << QMetaType::UChar |
2316 Q_UINT64_C(1) << QMetaType::Short |
2317 Q_UINT64_C(1) << QMetaType::UShort |
2318 Q_UINT64_C(1) << QMetaType::Int |
2319 Q_UINT64_C(1) << QMetaType::UInt |
2320 Q_UINT64_C(1) << QMetaType::Long |
2321 Q_UINT64_C(1) << QMetaType::ULong |
2322 Q_UINT64_C(1) << QMetaType::LongLong |
2323 Q_UINT64_C(1) << QMetaType::ULongLong;
2324 return tp < (CHAR_BIT * sizeof numericTypeBits) ? numericTypeBits & (Q_UINT64_C(1) << tp) : false;
2325}
2326
2327static bool qIsFloatingPoint(uint tp)
2328{
2329 return tp == QMetaType::Double || tp == QMetaType::Float || tp == QMetaType::Float16;
2330}
2331
2333 const QtPrivate::QMetaTypeInterface *iface2)
2334{
2335 if (!iface1 || !iface2)
2336 return false;
2337
2338 // We don't need QMetaType::id() here because the type Id is always stored
2339 // directly for all built-in types.
2340 bool isNumeric1 = qIsNumericType(iface1->typeId);
2341 bool isNumeric2 = qIsNumericType(iface2->typeId);
2342
2343 // if they're both numeric (or QString), then they can be compared
2344 if (isNumeric1 && isNumeric2)
2345 return true;
2346
2347 bool isEnum1 = iface1->flags & QMetaType::IsEnumeration;
2348 bool isEnum2 = iface2->flags & QMetaType::IsEnumeration;
2349
2350 // if both are enums, we can only compare if they are the same enum
2351 // (the language does allow comparing two different enum types, but that's
2352 // usually considered poor coding and produces a warning)
2353 if (isEnum1 && isEnum2)
2354 return QMetaType(iface1) == QMetaType(iface2);
2355
2356 // if one is an enum and the other is a numeric, we can compare too
2357 if (isEnum1 && isNumeric2)
2358 return true;
2359 if (isNumeric1 && isEnum2)
2360 return true;
2361
2362 // we need at least one enum and one numeric...
2363 return false;
2364}
2365
2367 const QtPrivate::QMetaTypeInterface *iface2)
2368{
2369 Q_ASSERT(canBeNumericallyCompared(iface1, iface2));
2370
2371 // We don't need QMetaType::id() here because the type Id is always stored
2372 // directly for the types we're comparing against below.
2373 uint t1 = iface1->typeId;
2374 uint t2 = iface2->typeId;
2375
2376 if ((t1 == QMetaType::Bool && t2 == QMetaType::QString) ||
2377 (t2 == QMetaType::Bool && t1 == QMetaType::QString))
2378 return QMetaType::Bool;
2379
2380 // C++ integral ranks: (4.13 Integer conversion rank [conv.rank])
2381 // bool < signed char < short < int < long < long long
2382 // unsigneds have the same rank as their signed counterparts
2383 // C++ integral promotion rules (4.5 Integral Promotions [conv.prom])
2384 // - any type with rank less than int can be converted to int or unsigned int
2385 // 5 Expressions [expr] paragraph 9:
2386 // - if either operand is double, the other shall be converted to double
2387 // - " " float, " " " float
2388 // - if both operands have the same type, no further conversion is needed.
2389 // - if both are signed or if both are unsigned, convert to the one with highest rank
2390 // - if the unsigned has higher or same rank, convert the signed to the unsigned one
2391 // - if the signed can represent all values of the unsigned, convert to the signed
2392 // - otherwise, convert to the unsigned corresponding to the rank of the signed
2393
2394 // floating point: we deviate from the C++ standard by always using qreal
2395 if (qIsFloatingPoint(t1) || qIsFloatingPoint(t2))
2396 return QMetaType::QReal;
2397
2398 auto isUnsigned = [](uint tp, const QtPrivate::QMetaTypeInterface *iface) {
2399 // only types for which sizeof(T) >= sizeof(int); lesser ones promote to int
2400 return tp == QMetaType::ULongLong || tp == QMetaType::ULong ||
2401 tp == QMetaType::UInt || tp == QMetaType::Char32 ||
2402 (iface->flags & QMetaType::IsUnsignedEnumeration && iface->size >= sizeof(int));
2403 };
2404 bool isUnsigned1 = isUnsigned(t1, iface1);
2405 bool isUnsigned2 = isUnsigned(t2, iface2);
2406
2407 // integral rules:
2408 // 1) if either type is a 64-bit unsigned, compare as 64-bit unsigned
2409 if (isUnsigned1 && iface1->size > sizeof(int))
2410 return QMetaType::ULongLong;
2411 if (isUnsigned2 && iface2->size > sizeof(int))
2412 return QMetaType::ULongLong;
2413
2414 // 2) if either type is 64-bit, compare as 64-bit signed
2415 if (iface1->size > sizeof(int) || iface2->size > sizeof(int))
2416 return QMetaType::LongLong;
2417
2418 // 3) if either type is 32-bit unsigned, compare as 32-bit unsigned
2419 if (isUnsigned1 || isUnsigned2)
2420 return QMetaType::UInt;
2421
2422 // 4) otherwise, just do int promotion
2423 return QMetaType::Int;
2424}
2425
2426static QPartialOrdering integralCompare(uint promotedType, const QVariant::Private *d1, const QVariant::Private *d2)
2427{
2428 // use toLongLong to retrieve the data, it gets us all the bits
2429 std::optional<qlonglong> l1 = qConvertToNumber(d1, promotedType == QMetaType::Bool);
2430 std::optional<qlonglong> l2 = qConvertToNumber(d2, promotedType == QMetaType::Bool);
2431 if (!l1 || !l2)
2432 return QPartialOrdering::Unordered;
2433 if (promotedType == QMetaType::UInt)
2434 return Qt::compareThreeWay(uint(*l1), uint(*l2));
2435 if (promotedType == QMetaType::LongLong)
2436 return Qt::compareThreeWay(qlonglong(*l1), qlonglong(*l2));
2437 if (promotedType == QMetaType::ULongLong)
2438 return Qt::compareThreeWay(qulonglong(*l1), qulonglong(*l2));
2439
2440 return Qt::compareThreeWay(int(*l1), int(*l2));
2441}
2442
2443static QPartialOrdering numericCompare(const QVariant::Private *d1, const QVariant::Private *d2)
2444{
2445 uint promotedType = numericTypePromotion(d1->typeInterface(), d2->typeInterface());
2446 if (promotedType != QMetaType::QReal)
2447 return integralCompare(promotedType, d1, d2);
2448
2449 // floating point comparison
2450 const auto r1 = qConvertToRealNumber(d1);
2451 const auto r2 = qConvertToRealNumber(d2);
2452 if (!r1 || !r2)
2453 return QPartialOrdering::Unordered;
2454
2455 return Qt::compareThreeWay(*r1, *r2);
2456}
2457
2458static bool qvCanConvertMetaObject(QMetaType fromType, QMetaType toType)
2459{
2460 if ((fromType.flags() & QMetaType::PointerToQObject)
2461 && (toType.flags() & QMetaType::PointerToQObject)) {
2462 const QMetaObject *f = fromType.metaObject();
2463 const QMetaObject *t = toType.metaObject();
2464 return f && t && (f->inherits(t) || t->inherits(f));
2465 }
2466 return false;
2467}
2468
2469static QPartialOrdering pointerCompare(const QVariant::Private *d1, const QVariant::Private *d2)
2470{
2471 return Qt::compareThreeWay(Qt::totally_ordered_wrapper(d1->get<QObject *>()),
2472 Qt::totally_ordered_wrapper(d2->get<QObject *>()));
2473}
2474
2475/*!
2476 \internal
2477 */
2478bool QVariant::equals(const QVariant &v) const
2479{
2480 auto metatype = d.type();
2481
2482 if (metatype != v.metaType()) {
2483 // try numeric comparisons, with C++ type promotion rules (no conversion)
2484 if (canBeNumericallyCompared(metatype.iface(), v.d.type().iface()))
2485 return numericCompare(&d, &v.d) == QPartialOrdering::Equivalent;
2486 // if both types are related pointers to QObjects, check if they point to the same object
2487 if (qvCanConvertMetaObject(metatype, v.metaType()))
2488 return pointerCompare(&d, &v.d) == QPartialOrdering::Equivalent;
2489 return false;
2490 }
2491
2492 // For historical reasons: QVariant() == QVariant()
2493 if (!metatype.isValid())
2494 return true;
2495
2496 return metatype.equals(d.storage(), v.d.storage());
2497}
2498
2499/*!
2500 Compares the objects at \a lhs and \a rhs for ordering.
2501
2502 Returns QPartialOrdering::Unordered if comparison is not supported
2503 or the values are unordered. Otherwise, returns
2504 QPartialOrdering::Less, QPartialOrdering::Equivalent or
2505 QPartialOrdering::Greater if \a lhs is less than, equivalent
2506 to or greater than \a rhs, respectively.
2507
2508 If the variants contain data with a different metatype, the values are considered
2509 unordered unless they are both of numeric or pointer types, where regular numeric or
2510 pointer comparison rules will be used.
2511 \note: If a numeric comparison is done and at least one value is NaN, QPartialOrdering::Unordered
2512 is returned.
2513
2514 If both variants contain data of the same metatype, the method will use the
2515 QMetaType::compare method to determine the ordering of the two variants, which can
2516 also indicate that it can't establish an ordering between the two values.
2517
2518 \since 6.0
2519 \sa QMetaType::compare(), QMetaType::isOrdered()
2520*/
2521QPartialOrdering QVariant::compare(const QVariant &lhs, const QVariant &rhs)
2522{
2523 QMetaType t = lhs.d.type();
2524 if (t != rhs.d.type()) {
2525 // try numeric comparisons, with C++ type promotion rules (no conversion)
2526 if (canBeNumericallyCompared(lhs.d.type().iface(), rhs.d.type().iface()))
2527 return numericCompare(&lhs.d, &rhs.d);
2528 if (qvCanConvertMetaObject(lhs.metaType(), rhs.metaType()))
2529 return pointerCompare(&lhs.d, &rhs.d);
2530 return QPartialOrdering::Unordered;
2531 }
2532 return t.compare(lhs.constData(), rhs.constData());
2533}
2534
2535/*!
2536 \fn const void *QVariant::constData() const
2537 \fn const void* QVariant::data() const
2538
2539 Returns a pointer to the contained object as a generic void* that cannot be
2540 written to.
2541
2542 \sa get_if(), QMetaType
2543 */
2544
2545/*!
2546 Returns a pointer to the contained object as a generic void* that can be
2547 written to.
2548
2549 This function detaches the QVariant. When called on a \l{isNull}{null-QVariant},
2550 the QVariant will not be null after the call.
2551
2552 \sa get_if(), QMetaType
2553*/
2554void *QVariant::data()
2555{
2556 detach();
2557 // set is_null to false, as the caller is likely to write some data into this variant
2558 d.is_null = false;
2559 return const_cast<void *>(constData());
2560}
2561
2562/*!
2563 \since 6.6
2564 \fn template <typename T> const T* QVariant::get_if(const QVariant *v)
2565 \fn template <typename T> T* QVariant::get_if(QVariant *v)
2566
2567 If \a v contains an object of type \c T, returns a pointer to the contained
2568 object, otherwise returns \nullptr.
2569
2570 The overload taking a mutable \a v detaches \a v: When called on a
2571 \l{isNull()}{null} \a v with matching type \c T, \a v will not be null
2572 after the call.
2573
2574 These functions are provided for compatibility with \c{std::variant}.
2575
2576 \sa data()
2577*/
2578
2579/*!
2580 \since 6.6
2581 \fn template <typename T> T &QVariant::get(QVariant &v)
2582 \fn template <typename T> const T &QVariant::get(const QVariant &v)
2583 \fn template <typename T> T &&QVariant::get(QVariant &&v)
2584 \fn template <typename T> const T &&QVariant::get(const QVariant &&v)
2585
2586 If \a v contains an object of type \c T, returns a reference to the contained
2587 object, otherwise the call has undefined behavior.
2588
2589 The overloads taking a mutable \a v detach \a v: When called on a
2590 \l{isNull()}{null} \a v with matching type \c T, \a v will not be null
2591 after the call.
2592
2593 These functions are provided for compatibility with \c{std::variant}.
2594
2595 \sa get_if(), data()
2596*/
2597
2598/*!
2599 Returns \c true if this is a null variant, false otherwise.
2600
2601 A variant is considered null if it contains no initialized value or a null pointer.
2602
2603 \note This behavior has been changed from Qt 5, where isNull() would also
2604 return true if the variant contained an object of a builtin type with an isNull()
2605 method that returned true for that object.
2606
2607 \sa convert()
2608*/
2609bool QVariant::isNull() const
2610{
2611 if (d.is_null || !metaType().isValid())
2612 return true;
2613 if (metaType().flags() & QMetaType::IsPointer)
2614 return d.get<void *>() == nullptr;
2615 return false;
2616}
2617
2618#ifndef QT_NO_DEBUG_STREAM
2619QDebug QVariant::qdebugHelper(QDebug dbg) const
2620{
2621 QDebugStateSaver saver(dbg);
2622 const uint typeId = d.type().rawId();
2623 dbg.nospace() << "QVariant(";
2624 if (typeId != QMetaType::UnknownType) {
2625 dbg << d.type().name() << ", ";
2626 bool streamed = d.type().debugStream(dbg, d.storage());
2627 if (!streamed && canConvert<QString>())
2628 dbg << toString();
2629 } else {
2630 dbg << "Invalid";
2631 }
2632 dbg << ')';
2633 return dbg;
2634}
2635
2636QVariant QVariant::moveConstruct(QMetaType type, void *data)
2637{
2638 QVariant var;
2639 var.d = QVariant::Private(type.d_ptr);
2640 customConstruct<ForceMove, NonNull>(type.d_ptr, &var.d, data);
2641 return var;
2642}
2643
2644QVariant QVariant::copyConstruct(QMetaType type, const void *data)
2645{
2646 QVariant var;
2647 var.d = QVariant::Private(type.d_ptr);
2648 customConstruct<UseCopy, NonNull>(type.d_ptr, &var.d, data);
2649 return var;
2650}
2651
2652#if QT_DEPRECATED_SINCE(6, 0)
2653QT_WARNING_PUSH
2654QT_WARNING_DISABLE_DEPRECATED
2655
2656QDebug operator<<(QDebug dbg, const QVariant::Type p)
2657{
2658 QDebugStateSaver saver(dbg);
2659 dbg.nospace() << "QVariant::"
2660 << (int(p) != int(QMetaType::UnknownType)
2661 ? QMetaType(p).name()
2662 : "Invalid");
2663 return dbg;
2664}
2665
2666QT_WARNING_POP
2667#endif
2668
2669#endif
2670
2671/*! \fn template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, QVariant>>> void QVariant::setValue(T &&value)
2672
2673 Stores a copy of \a value. If \c{T} is a type that QVariant
2674 doesn't support, QMetaType is used to store the value. A compile
2675 error will occur if QMetaType doesn't handle the type.
2676
2677 Example:
2678
2679 \snippet code/src_corelib_kernel_qvariant.cpp 4
2680
2681 \sa value(), fromValue(), canConvert()
2682 */
2683
2684/*! \fn void QVariant::setValue(const QVariant &value)
2685
2686 Copies \a value over this QVariant. It is equivalent to simply
2687 assigning \a value to this QVariant.
2688*/
2689
2690/*! \fn void QVariant::setValue(QVariant &&value)
2691
2692 Moves \a value over this QVariant. It is equivalent to simply
2693 move assigning \a value to this QVariant.
2694*/
2695
2696/*! \fn template<typename T> T QVariant::value() const &
2697
2698 Returns the stored value converted to the template type \c{T}.
2699 Call canConvert() to find out whether a type can be converted.
2700 If the value cannot be converted, a \l{default-constructed value}
2701 will be returned.
2702
2703 If the type \c{T} is supported by QVariant, this function behaves
2704 exactly as toString(), toInt() etc.
2705
2706 Example:
2707
2708 \snippet code/src_corelib_kernel_qvariant.cpp 5
2709
2710 If the QVariant contains a pointer to a type derived from QObject then
2711 \c{T} may be any QObject type. If the pointer stored in the QVariant can be
2712 qobject_cast to T, then that result is returned. Otherwise \nullptr is
2713 returned. Note that this only works for QObject subclasses which use
2714 the Q_OBJECT macro.
2715
2716 If the QVariant contains a sequential container and \c{T} is QVariantList, the
2717 elements of the container will be converted into \l {QVariant}s and returned as a QVariantList.
2718
2719 \snippet code/src_corelib_kernel_qvariant.cpp 9
2720
2721 \sa setValue(), fromValue(), canConvert(), Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE()
2722*/
2723
2724/*! \fn template<typename T> T QVariant::view()
2725
2726 Returns a mutable view of template type \c{T} on the stored value.
2727 Call canView() to find out whether such a view is supported.
2728 If no such view can be created, returns the stored value converted to the
2729 template type \c{T}. Call canConvert() to find out whether a type can be
2730 converted. If the value can neither be viewed nor converted, a
2731 \l{default-constructed value} will be returned.
2732
2733 \sa canView(), Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE()
2734*/
2735
2736/*! \fn template<typename T> bool QVariant::canConvert() const
2737
2738 Returns \c true if the variant can be converted to the template type \c{T},
2739 otherwise false.
2740
2741 Example:
2742
2743 \snippet code/src_corelib_kernel_qvariant.cpp 6
2744
2745 A QVariant containing a pointer to a type derived from QObject will also return true for this
2746 function if a qobject_cast to the template type \c{T} would succeed. Note that this only works
2747 for QObject subclasses which use the Q_OBJECT macro.
2748
2749 \sa convert()
2750*/
2751
2752/*! \fn template<typename T> bool QVariant::canView() const
2753
2754 Returns \c true if a mutable view of the template type \c{T} can be created on this variant,
2755 otherwise \c false.
2756
2757 \sa value()
2758*/
2759
2760/*! \fn template<typename T> static QVariant QVariant::fromValue(const T &value)
2761
2762 Returns a QVariant containing a copy of \a value. Behaves
2763 exactly like setValue() otherwise.
2764
2765 Example:
2766
2767 \snippet code/src_corelib_kernel_qvariant.cpp 7
2768
2769 \sa setValue(), value()
2770*/
2771
2772/*! \fn template<typename T, QVariant::if_rvalue<T> = true> static QVariant QVariant::fromValue(T &&value)
2773
2774 \since 6.6
2775 \overload
2776*/
2777
2778/*! \fn template<typename... Types> QVariant QVariant::fromStdVariant(const std::variant<Types...> &value)
2779 \since 5.11
2780
2781 Returns a QVariant with the type and value of the active variant of \a value. If
2782 the active type is std::monostate a default QVariant is returned.
2783
2784 \note With this method you do not need to register the variant as a Qt metatype,
2785 since the std::variant is resolved before being stored. The component types
2786 should be registered however.
2787
2788 \sa fromValue()
2789*/
2790
2791/*!
2792 \fn template<typename... Types> QVariant QVariant::fromStdVariant(std::variant<Types...> &&value)
2793 \since 6.6
2794 \overload
2795*/
2796
2797
2798/*!
2799 \since 6.7
2800
2801 Creates a variant of type \a type, and initializes it with
2802 a copy of \c{*copy} if \a copy is not \nullptr (in which case, \a copy
2803 must point to an object of type \a type).
2804
2805 Note that you have to pass the address of the object you want stored.
2806
2807 Usually, you never have to use this constructor, use QVariant::fromValue()
2808 instead to construct variants from the pointer types represented by
2809 \c QMetaType::VoidStar, and \c QMetaType::QObjectStar.
2810
2811 If \a type does not support copy construction and \a copy is not \nullptr,
2812 the variant will be invalid. Similarly, if \a copy is \nullptr and
2813 \a type does not support default construction, the variant will be
2814 invalid.
2815
2816 Returns the QVariant created as described above.
2817
2818 \sa QVariant::fromValue(), QMetaType::Type
2819*/
2820QVariant QVariant::fromMetaType(QMetaType type, const void *copy)
2821{
2822 QVariant result;
2823 type.registerType();
2824 const auto iface = type.iface();
2825 if (isValidMetaTypeForVariant(iface, copy)) {
2826 result.d = Private(iface);
2827 customConstruct(iface, &result.d, copy);
2828 }
2829 return result;
2830}
2831
2832/*!
2833 \fn template<typename T> T qvariant_cast(const QVariant &value)
2834 \relates QVariant
2835
2836 Returns the given \a value converted to the template type \c{T}.
2837
2838 This function is equivalent to QVariant::value().
2839
2840 \sa QVariant::value()
2841*/
2842
2843/*!
2844 \fn template<typename T> T QVariant::qvariant_cast(QVariant &&value)
2845 \overload
2846 \since 6.7
2847
2848 Returns the given \a value converted to the template type \c{T}.
2849*/
2850
2851/*! \fn template<typename T> T qVariantValue(const QVariant &value)
2852 \relates QVariant
2853 \deprecated
2854
2855 Returns the given \a value converted to the template type \c{T}.
2856
2857 This function is equivalent to
2858 \l{QVariant::value()}{QVariant::value}<T>(\a value).
2859
2860 \note This function was provided as a workaround for MSVC 6
2861 which did not support member template functions. It is advised
2862 to use the other form in new code.
2863
2864 \sa QVariant::value(), qvariant_cast()
2865*/
2866
2867/*! \fn bool qVariantCanConvert(const QVariant &value)
2868 \relates QVariant
2869 \deprecated
2870
2871 Returns \c true if the given \a value can be converted to the
2872 template type specified; otherwise returns \c false.
2873
2874 This function is equivalent to QVariant::canConvert(\a value).
2875
2876 \note This function was provided as a workaround for MSVC 6
2877 which did not support member template functions. It is advised
2878 to use the other form in new code.
2879
2880 \sa QVariant::canConvert()
2881*/
2882
2883/*!
2884 \typedef QVariantList
2885 \relates QVariant
2886
2887 Synonym for QList<QVariant>.
2888*/
2889
2890/*!
2891 \typedef QVariantMap
2892 \relates QVariant
2893
2894 Synonym for QMap<QString, QVariant>.
2895*/
2896
2897/*!
2898 \typedef QVariantHash
2899 \relates QVariant
2900 \since 4.5
2901
2902 Synonym for QHash<QString, QVariant>.
2903*/
2904
2905/*!
2906 \typedef QVariant::DataPtr
2907 \internal
2908*/
2909/*! \typedef QVariant::f_construct
2910 \internal
2911*/
2912
2913/*! \typedef QVariant::f_clear
2914 \internal
2915*/
2916
2917/*! \typedef QVariant::f_null
2918 \internal
2919*/
2920
2921/*! \typedef QVariant::f_load
2922 \internal
2923*/
2924
2925/*! \typedef QVariant::f_save
2926 \internal
2927*/
2928
2929/*! \typedef QVariant::f_compare
2930 \internal
2931*/
2932
2933/*! \typedef QVariant::f_convert
2934 \internal
2935*/
2936
2937/*! \typedef QVariant::f_canConvert
2938 \internal
2939*/
2940
2941/*! \typedef QVariant::f_debugStream
2942 \internal
2943*/
2944
2945/*!
2946 \fn DataPtr &QVariant::data_ptr()
2947 \internal
2948*/
2949
2950/*!
2951 \fn const DataPtr &QVariant::data_ptr() const
2952 \internal
2953*/
2954
2955/*!
2956 \internal
2957 */
2958const void *QtPrivate::QVariantTypeCoercer::convert(const QVariant &value, const QMetaType &type)
2959{
2960 if (type == QMetaType::fromType<QVariant>())
2961 return &value;
2962
2963 if (type == value.metaType())
2964 return value.constData();
2965
2966 if (value.canConvert(type)) {
2967 converted = value;
2968 if (converted.convert(type))
2969 return converted.constData();
2970 }
2971
2972 return nullptr;
2973}
2974
2975/*!
2976 \internal
2977 */
2978const void *QtPrivate::QVariantTypeCoercer::coerce(const QVariant &value, const QMetaType &type)
2979{
2980 if (const void *result = convert(value, type))
2981 return result;
2982
2983 converted = QVariant(type);
2984 return converted.constData();
2985}
2986
2987#if QT_DEPRECATED_SINCE(6, 15)
2988QT_WARNING_PUSH
2989QT_WARNING_DISABLE_DEPRECATED
2990
2991/*!
2992 \class QVariantRef
2993 \since 6.0
2994 \deprecated [6.15] Use QVariant::Reference instead.
2995 \inmodule QtCore
2996 \brief The QVariantRef acts as a non-const reference to a QVariant.
2997
2998 As the generic iterators don't actually instantiate a QVariant on each
2999 step, they cannot return a reference to one from operator*(). QVariantRef
3000 provides the same functionality as an actual reference to a QVariant would,
3001 but is backed by a pointer of type \a Pointer. The template is implemented
3002 for pointers of type QSequentialIterator and QAssociativeIterator.
3003*/
3004
3005/*!
3006 \fn template<typename Pointer> QVariantRef<Pointer>::QVariantRef(const Pointer *pointer)
3007
3008 Creates a QVariantRef from an \a pointer.
3009 */
3010
3011/*!
3012 \fn template<typename Pointer> QVariantRef<Pointer> &QVariantRef<Pointer>::operator=(const QVariant &value)
3013
3014 Assigns a new \a value to the value pointed to by the pointer this
3015 QVariantRef refers to.
3016 */
3017
3018/*!
3019 \fn template<typename Pointer> QVariantRef<Pointer> &QVariantRef<Pointer>::operator=(const QVariantRef &value)
3020
3021 Assigns a new \a value to the value pointed to by the pointer this
3022 QVariantRef refers to.
3023 */
3024
3025/*!
3026 \fn template<typename Pointer> QVariantRef<Pointer> &QVariantRef<Pointer>::operator=(QVariantRef &&value)
3027
3028 Assigns a new \a value to the value pointed to by the pointer this
3029 QVariantRef refers to.
3030*/
3031
3032/*!
3033 \fn template<typename Pointer> QVariantRef<Pointer>::operator QVariant() const
3034
3035 Resolves the QVariantRef to an actual QVariant.
3036*/
3037
3038/*!
3039 \fn template<typename Pointer> void swap(QVariantRef<Pointer> a, QVariantRef<Pointer> b)
3040
3041 Swaps the values pointed to by the pointers the QVariantRefs
3042 \a a and \a b refer to.
3043*/
3044
3045/*!
3046 \class QVariantConstPointer
3047 \since 6.0
3048 \deprecated [6.15] Use QVariant::ConstPointer instead.
3049 \inmodule QtCore
3050 \brief Emulated const pointer to QVariant based on a pointer.
3051
3052 QVariantConstPointer wraps a QVariant and returns it from its operator*().
3053 This makes it suitable as replacement for an actual const pointer. We cannot
3054 return an actual const pointer from generic iterators as the iterators don't
3055 hold an actual QVariant.
3056*/
3057
3058/*!
3059 Constructs a QVariantConstPointer from a \a variant.
3060 */
3061QVariantConstPointer::QVariantConstPointer(QVariant variant)
3062 : m_variant(std::move(variant))
3063{
3064}
3065
3066/*!
3067 Dereferences the QVariantConstPointer to retrieve its internal QVariant.
3068 */
3069QVariant QVariantConstPointer::operator*() const
3070{
3071 return m_variant;
3072}
3073
3074/*!
3075 Returns a const pointer to the QVariant, conforming to the
3076 conventions for operator->().
3077 */
3078const QVariant *QVariantConstPointer::operator->() const
3079{
3080 return &m_variant;
3081}
3082
3083/*!
3084 \class QVariantPointer
3085 \since 6.0
3086 \deprecated [6.15] Use QVariant::Pointer instead.
3087 \inmodule QtCore
3088 \brief QVariantPointer is a template class that emulates a pointer to QVariant based on a pointer.
3089
3090 QVariantPointer<Pointer> wraps a pointer of type \a Pointer and returns
3091 QVariantRef to it from its operator*(). This makes it suitable as
3092 replacement for an actual pointer. We cannot return an actual pointer from
3093 generic iterators as the iterators don't hold an actual QVariant.
3094*/
3095
3096/*!
3097 \fn template<typename Pointer> QVariantPointer<Pointer>::QVariantPointer(const Pointer *pointer)
3098
3099 Constructs a QVariantPointer from the given \a pointer.
3100 */
3101
3102/*!
3103 \fn template<typename Pointer> QVariantRef<Pointer> QVariantPointer<Pointer>::operator*() const
3104
3105 Dereferences the QVariantPointer to a QVariantRef.
3106 */
3107
3108/*!
3109 \fn template<typename Pointer> Pointer QVariantPointer<Pointer>::operator->() const
3110
3111 Dereferences and returns the pointer. The pointer is expected to also
3112 implement operator->().
3113 */
3114
3115QT_WARNING_POP
3116#endif // QT_DEPRECATED_SINCE(6, 15)
3117
3118/*!
3119 \class QVariant::ConstReference
3120 \since 6.11
3121 \inmodule QtCore
3122 \brief The QVariant::ConstReference acts as a const reference to a QVariant.
3123
3124 As the generic iterators don't actually instantiate a QVariant on each
3125 step, they cannot return a reference to one from operator*().
3126 QVariant::ConstReference<Indirect> provides the same functionality as an
3127 actual reference to a QVariant would, but is backed by a referred-to value
3128 of type \a Indirect. The template is implemented for
3129 QMetaSequence::ConstIterator, QMetaSequence::Iterator,
3130 QMetaAssociation::ConstIterator, and QMetaAssociation::Iterator.
3131*/
3132
3133/*!
3134 \fn template<typename Indirect> QVariant::ConstReference<Indirect>::ConstReference(const Indirect &referred)
3135
3136 Creates a QVariant::ConstReference from a \a referred.
3137 */
3138
3139/*!
3140 \fn template<typename Indirect> QVariant::ConstReference<Indirect>::ConstReference(Indirect &&referred)
3141
3142 Creates a QVariant::ConstReference from a \a referred.
3143 */
3144
3145/*!
3146 \fn template<typename Indirect> QVariant::ConstReference<Indirect>::ConstReference(const Reference<Indirect> &nonConst)
3147
3148 Creates a QVariant::ConstReference from a \a nonConst Reference.
3149 */
3150
3151/*!
3152 \fn template<typename Indirect> QVariant::ConstReference<Indirect>::ConstReference(Reference<Indirect> &&nonConst)
3153
3154 Creates a QVariant::ConstReference from a \a nonConst Reference.
3155 */
3156
3157
3158/*!
3159 \fn template<typename Indirect> QVariant::ConstReference<Indirect>::operator QVariant() const
3160
3161 Dereferences the reference to a QVariant.
3162 This method needs to be specialized for each Indirect type. It is
3163 pre-defined for QMetaSequence::ConstIterator, QMetaSequence::Iterator,
3164 QMetaAssociation::ConstIterator, and QMetaAssociation::Iterator.
3165 */
3166
3167
3168/*!
3169 \class QVariant::Reference
3170 \since 6.11
3171 \inmodule QtCore
3172 \brief The QVariant::Reference acts as a non-const reference to a QVariant.
3173
3174 As the generic iterators don't actually instantiate a QVariant on each
3175 step, they cannot return a reference to one from operator*().
3176 QVariant::Reference<Indirect> provides the same functionality as an
3177 actual reference to a QVariant would, but is backed by a referred-to value
3178 of type \a Indirect. The template is implemented for
3179 QMetaSequence::Iterator and QMetaAssociation::Iterator.
3180*/
3181
3182/*!
3183 \fn template<typename Indirect> QVariant::Reference<Indirect>::Reference(const Indirect &referred)
3184
3185 Creates a QVariant::Reference from a \a referred.
3186 */
3187
3188/*!
3189 \fn template<typename Indirect> QVariant::Reference<Indirect>::Reference(Indirect &&referred)
3190
3191 Creates a QVariant::Reference from a \a referred.
3192 */
3193
3194/*!
3195 \fn template<typename Indirect> QVariant::Reference<Indirect> &QVariant::Reference<Indirect>::operator=(const Reference<Indirect> &value)
3196
3197 Assigns a new \a value to the value referred to by this QVariant::Reference.
3198 */
3199
3200/*!
3201 \fn template<typename Indirect> QVariant::Reference<Indirect> &QVariant::Reference<Indirect>::operator=(Reference<Indirect> &&value)
3202
3203 Assigns a new \a value to the value referred to by this QVariant::Reference.
3204*/
3205
3206/*!
3207 \fn template<typename Indirect> QVariant::Reference<Indirect> &QVariant::Reference<Indirect>::operator=(const ConstReference<Indirect> &value)
3208
3209 Assigns a new \a value to the value referred to by this QVariant::Reference.
3210 */
3211
3212/*!
3213 \fn template<typename Indirect> QVariant::Reference<Indirect> &QVariant::Reference<Indirect>::operator=(ConstReference<Indirect> &&value)
3214
3215 Assigns a new \a value to the value referred to by this QVariant::Reference.
3216*/
3217
3218/*!
3219 \fn template<typename Indirect> QVariant::Reference<Indirect> &QVariant::Reference<Indirect>::operator=(const QVariant &value)
3220
3221 Assigns a new \a value to the value referred to by this QVariant::Reference.
3222 This method needs to be specialized for each Indirect type. It is
3223 pre-defined for QMetaSequence::Iterator and QMetaAssociation::Iterator.
3224 */
3225
3226/*!
3227 \fn template<typename Indirect> QVariant::Reference<Indirect>::operator QVariant() const
3228
3229 Dereferences the reference to a QVariant. By default this instantiates a
3230 temporary QVariant::ConstReference and calls dereferences that. In cases
3231 where instantiating a temporary ConstReference is expensive, this method
3232 should be specialized.
3233 */
3234
3235/*!
3236 \class QVariant::ConstPointer
3237 \since 6.11
3238 \inmodule QtCore
3239 \brief QVariant::ConstPointer is a template class that emulates a const pointer to QVariant.
3240
3241 QVariant::ConstPointer<Indirect> wraps a pointed-to value of type
3242 \a Indirect and returns a QVariant::ConstReference to it from its
3243 operator*(). This makes it suitable as replacement for an actual pointer.
3244 We cannot return an actual pointer from generic iterators as the iterators
3245 don't hold an actual QVariant.
3246*/
3247
3248/*!
3249 \fn template<typename Indirect> QVariant::ConstPointer<Indirect>::ConstPointer(const Indirect &pointed)
3250
3251 Constructs a QVariant::ConstPointer from the value \a pointed to.
3252 */
3253
3254/*!
3255 \fn template<typename Indirect> QVariant::ConstPointer<Indirect>::ConstPointer(Indirect &&pointed)
3256
3257 Constructs a QVariant::ConstPointer from the value \a pointed to.
3258 */
3259
3260/*!
3261 \fn template<typename Indirect> QVariant::ConstReference<Pointer> QVariant::ConstPointer<Indirect>::operator*() const
3262
3263 Dereferences the QVariant::ConstPointer to a QVariant::ConstReference.
3264 */
3265
3266/*!
3267 \class QVariant::Pointer
3268 \since 6.11
3269 \inmodule QtCore
3270 \brief QVariant::Pointer is a template class that emulates a non-const pointer to QVariant.
3271
3272 QVariant::Pointer<Indirect> wraps a pointed-to value of type \a Indirect
3273 and returns a QVariant::Reference to it from its operator*(). This makes it
3274 suitable as replacement for an actual pointer. We cannot return an actual
3275 pointer from generic iterators as the iterators don't hold an actual
3276 QVariant.
3277*/
3278
3279/*!
3280 \fn template<typename Indirect> QVariant::Pointer<Indirect>::Pointer(const Indirect &pointed)
3281
3282 Constructs a QVariant::Pointer from the value \a pointed to.
3283 */
3284
3285/*!
3286 \fn template<typename Indirect> QVariant::Pointer<Indirect>::Pointer(Indirect &&pointed)
3287
3288 Constructs a QVariant::Pointer from the value \a pointed to.
3289 */
3290
3291/*!
3292 \fn template<typename Indirect> QVariant::Reference<Indirect> QVariant::Pointer<Indirect>::operator*() const
3293
3294 Dereferences the QVariant::Pointer to a QVariant::Reference.
3295 */
3296
3297/*!
3298 \fn template<typename Indirect> QVariant::Pointer<Indirect>::operator QVariant::ConstPointer<Indirect>() const
3299
3300 Converts this QVariant::Pointer into a QVariant::ConstPointer.
3301 */
3302
3303QT_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)