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