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