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