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

source code of qtbase/src/corelib/kernel/qvariant.cpp