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