Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qvariant.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2021 Intel Corporation.
3// Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#include "qvariant_p.h"
7#include "qbitarray.h"
8#include "qbytearray.h"
9#include "qdatastream.h"
10#include "qdebug.h"
11#include "qmap.h"
12#include "qhash.h"
13#include "qdatetime.h"
14#if QT_CONFIG(easingcurve)
15#include "qeasingcurve.h"
16#endif
17#include "qlist.h"
18#if QT_CONFIG(regularexpression)
19#include "qregularexpression.h"
20#endif
21#include "qstring.h"
22#include "qstringlist.h"
23#include "qurl.h"
24#include "qlocale.h"
25#include "quuid.h"
26#if QT_CONFIG(itemmodel)
27#include "qabstractitemmodel.h"
28#endif
29#ifndef QT_BOOTSTRAPPED
30#include "qcborarray.h"
31#include "qcborcommon.h"
32#include "qcbormap.h"
33#include "qjsonvalue.h"
34#include "qjsonobject.h"
35#include "qjsonarray.h"
36#include "qjsondocument.h"
37#include "qbytearraylist.h"
38#endif
39#include "private/qlocale_p.h"
40#include "qmetatype_p.h"
41#include <qmetaobject.h>
42
43#ifndef QT_NO_GEOM_VARIANT
44#include "qsize.h"
45#include "qpoint.h"
46#include "qrect.h"
47#include "qline.h"
48#endif
49
50#include <memory>
51
52#include <cmath>
53#include <float.h>
54#include <cstring>
55
57
58using namespace Qt::StringLiterals;
59
60namespace { // anonymous used to hide QVariant handlers
61
62static qlonglong qMetaTypeNumberBySize(const QVariant::Private *d)
63{
64 switch (d->typeInterface()->size) {
65 case 1:
66 return d->get<signed char>();
67 case 2:
68 return d->get<short>();
69 case 4:
70 return d->get<int>();
71 case 8:
72 return d->get<qlonglong>();
73 }
74 Q_UNREACHABLE_RETURN(0);
75}
76
77static qlonglong qMetaTypeNumber(const QVariant::Private *d)
78{
79 switch (d->typeInterface()->typeId) {
80 case QMetaType::Int:
81 case QMetaType::LongLong:
82 case QMetaType::Char:
83 case QMetaType::SChar:
84 case QMetaType::Short:
85 case QMetaType::Long:
86 return qMetaTypeNumberBySize(d);
87 case QMetaType::Float:
88 return qRound64(d->get<float>());
89 case QMetaType::Double:
90 return qRound64(d->get<double>());
91#ifndef QT_BOOTSTRAPPED
92 case QMetaType::QJsonValue:
93 return d->get<QJsonValue>().toDouble();
94 case QMetaType::QCborValue:
95 return d->get<QCborValue>().toInteger();
96#endif
97 }
98 Q_UNREACHABLE_RETURN(0);
99}
100
101static qulonglong qMetaTypeUNumber(const QVariant::Private *d)
102{
103 switch (d->typeInterface()->size) {
104 case 1:
105 return d->get<unsigned char>();
106 case 2:
107 return d->get<unsigned short>();
108 case 4:
109 return d->get<unsigned int>();
110 case 8:
111 return d->get<qulonglong>();
112 }
113 Q_UNREACHABLE_RETURN(0);
114}
115
116static std::optional<qlonglong> qConvertToNumber(const QVariant::Private *d, bool allowStringToBool = false)
117{
118 bool ok;
119 switch (d->typeInterface()->typeId) {
120 case QMetaType::QString: {
121 const QString &s = d->get<QString>();
122 if (qlonglong l = s.toLongLong(&ok); ok)
123 return l;
124 if (allowStringToBool) {
125 if (s == "false"_L1 || s == "0"_L1)
126 return 0;
127 if (s == "true"_L1 || s == "1"_L1)
128 return 1;
129 }
130 return std::nullopt;
131 }
132 case QMetaType::QChar:
133 return d->get<QChar>().unicode();
134 case QMetaType::QByteArray:
135 if (qlonglong l = d->get<QByteArray>().toLongLong(&ok); ok)
136 return l;
137 return std::nullopt;
138 case QMetaType::Bool:
139 return qlonglong(d->get<bool>());
140#ifndef QT_BOOTSTRAPPED
141 case QMetaType::QCborValue:
142 if (!d->get<QCborValue>().isInteger() && !d->get<QCborValue>().isDouble())
143 break;
144 return qMetaTypeNumber(d);
145 case QMetaType::QJsonValue:
146 if (!d->get<QJsonValue>().isDouble())
147 break;
149#endif
150 case QMetaType::Double:
151 case QMetaType::Int:
152 case QMetaType::Char:
153 case QMetaType::SChar:
154 case QMetaType::Short:
155 case QMetaType::Long:
156 case QMetaType::Float:
157 case QMetaType::LongLong:
158 return qMetaTypeNumber(d);
159 case QMetaType::ULongLong:
160 case QMetaType::UInt:
161 case QMetaType::UChar:
162 case QMetaType::Char16:
163 case QMetaType::Char32:
164 case QMetaType::UShort:
165 case QMetaType::ULong:
166 return qlonglong(qMetaTypeUNumber(d));
167 }
168
169 if (d->typeInterface()->flags & QMetaType::IsEnumeration
170 || d->typeInterface()->typeId == QMetaType::QCborSimpleType)
171 return qMetaTypeNumberBySize(d);
172
173 return std::nullopt;
174}
175
176static std::optional<double> qConvertToRealNumber(const QVariant::Private *d)
177{
178 bool ok;
179 switch (d->typeInterface()->typeId) {
180 case QMetaType::QString:
181 if (double r = d->get<QString>().toDouble(&ok); ok)
182 return r;
183 return std::nullopt;
184 case QMetaType::Double:
185 return d->get<double>();
186 case QMetaType::Float:
187 return double(d->get<float>());
188 case QMetaType::Float16:
189 return double(d->get<qfloat16>());
190 case QMetaType::ULongLong:
191 case QMetaType::UInt:
192 case QMetaType::UChar:
193 case QMetaType::Char16:
194 case QMetaType::Char32:
195 case QMetaType::UShort:
196 case QMetaType::ULong:
197 return double(qMetaTypeUNumber(d));
198#ifndef QT_BOOTSTRAPPED
199 case QMetaType::QCborValue:
200 return d->get<QCborValue>().toDouble();
201 case QMetaType::QJsonValue:
202 return d->get<QJsonValue>().toDouble();
203#endif
204 default:
205 // includes enum conversion as well as invalid types
206 if (std::optional<qlonglong> l = qConvertToNumber(d))
207 return double(*l);
208 return std::nullopt;
209 }
210}
211
212static bool isValidMetaTypeForVariant(const QtPrivate::QMetaTypeInterface *iface, const void *copy)
213{
214 using namespace QtMetaTypePrivate;
215 if (!iface || iface->size == 0)
216 return false;
217
218 Q_ASSERT(!isInterfaceFor<void>(iface)); // only void should have size 0
219 if (!isCopyConstructible(iface) || !isDestructible(iface)) {
220 // all meta types must be copyable (because QVariant is) and
221 // destructible (because QVariant owns it)
222 qWarning("QVariant: Provided metatype for '%s' does not support destruction and "
223 "copy construction", iface->name);
224 return false;
225 }
226 if (!copy && !isDefaultConstructible(iface)) {
227 // non-default-constructible types are acceptable, but not if you're
228 // asking us to construct from nothing
229 qWarning("QVariant: Cannot create type '%s' without a default constructor", iface->name);
230 return false;
231 }
232
233 return true;
234}
235
236enum CustomConstructMoveOptions {
237 UseCopy, // custom construct uses the copy ctor unconditionally
238 // future option: TryMove: uses move ctor if available, else copy ctor
239 ForceMove, // custom construct use the move ctor (which must exist)
240};
241
242enum CustomConstructNullabilityOption {
243 MaybeNull, // copy might be null, might be non-null
244 NonNull, // copy is guarantueed to be non-null
245 // future option: AlwaysNull?
246};
247
248// the type of d has already been set, but other field are not set
249template <CustomConstructMoveOptions moveOption = UseCopy, CustomConstructNullabilityOption nullability = MaybeNull>
250static void customConstruct(const QtPrivate::QMetaTypeInterface *iface, QVariant::Private *d,
251 std::conditional_t<moveOption == ForceMove, void *, const void *> copy)
252{
253 using namespace QtMetaTypePrivate;
254 Q_ASSERT(iface);
255 Q_ASSERT(iface->size);
256 Q_ASSERT(!isInterfaceFor<void>(iface));
258 Q_ASSERT(isDestructible(iface));
260 if constexpr (moveOption == ForceMove)
262 if constexpr (nullability == NonNull)
263 Q_ASSERT(copy != nullptr);
264
265 // need to check for nullptr_t here, as this can get called by fromValue(nullptr). fromValue() uses
266 // std::addressof(value) which in this case returns the address of the nullptr object.
267 // ### Qt 7: remove nullptr_t special casing
268 d->is_null = !copy QT6_ONLY(|| isInterfaceFor<std::nullptr_t>(iface));
269
271 d->is_shared = false;
272 if (!copy && !iface->defaultCtr)
273 return; // trivial default constructor and it's OK to build in 0-filled storage, which we've already done
274 if constexpr (moveOption == ForceMove && nullability == NonNull)
275 moveConstruct(iface, d->data.data, copy);
276 else
277 construct(iface, d->data.data, copy);
278 } else {
279 d->data.shared = customConstructShared(iface->size, iface->alignment, [=](void *where) {
280 if constexpr (moveOption == ForceMove && nullability == NonNull)
281 moveConstruct(iface, where, copy);
282 else
283 construct(iface, where, copy);
284 });
285 d->is_shared = true;
286 }
287}
288
289static void customClear(QVariant::Private *d)
290{
291 const QtPrivate::QMetaTypeInterface *iface = d->typeInterface();
292 if (!iface)
293 return;
294 if (!d->is_shared) {
295 QtMetaTypePrivate::destruct(iface, d->data.data);
296 } else {
297 QtMetaTypePrivate::destruct(iface, d->data.shared->data());
298 QVariant::PrivateShared::free(d->data.shared);
299 }
300}
301
302static QVariant::Private clonePrivate(const QVariant::Private &other)
303{
305 if (d.is_shared) {
306 d.data.shared->ref.ref();
307 } else if (const QtPrivate::QMetaTypeInterface *iface = d.typeInterface()) {
308 Q_ASSERT(d.canUseInternalSpace(iface));
309
310 // if not trivially copyable, ask to copy
311 if (iface->copyCtr)
312 QtMetaTypePrivate::copyConstruct(iface, d.data.data, other.data.data);
313 }
314 return d;
315}
316
317} // anonymous used to hide QVariant handlers
318
506//### Qt 7: Remove in favor of QMetaType overload
507void QVariant::create(int type, const void *copy)
508{
510}
511
519{
521}
522
530{
531 if (!d.is_shared || !d.data.shared->ref.deref())
532 customClear(&d);
533}
534
543 : d(clonePrivate(p.d))
544{
545}
546
596QVariant::QVariant(std::in_place_t, QMetaType type) : d(type.iface())
597{
598 // we query the metatype instead of detecting it at compile time
599 // so that we can change relocatability of internal types
600 if (!Private::canUseInternalSpace(type.iface())) {
601 d.data.shared = PrivateShared::create(type.sizeOf(), type.alignOf());
602 d.is_shared = true;
603 }
604}
605
612void *QVariant::prepareForEmplace(QMetaType type)
613{
614 /* There are two cases where we can reuse the existing storage
615 (1) The new type fits in QVariant's SBO storage
616 (2) We are using the externally allocated storage, the variant is
617 detached, and the new type fits into the existing storage.
618 In all other cases (3), we cannot reuse the storage.
619 */
620 auto typeFits = [&] {
621 auto newIface = type.iface();
622 auto oldIface = d.typeInterface();
623 auto newSize = PrivateShared::computeAllocationSize(newIface->size, newIface->alignment);
624 auto oldSize = PrivateShared::computeAllocationSize(oldIface->size, oldIface->alignment);
625 return newSize <= oldSize;
626 };
627 if (Private::canUseInternalSpace(type.iface())) { // (1)
628 clear();
629 d.packedType = quintptr(type.iface()) >> 2;
630 return d.data.data;
631 } else if (d.is_shared && isDetached() && typeFits()) { // (2)
633 // compare QVariant::PrivateShared::create
634 const auto ps = d.data.shared;
635 const auto align = type.alignOf();
636 ps->offset = PrivateShared::computeOffset(ps, align);
637 d.packedType = quintptr(type.iface()) >> 2;
638 return ps->data();
639 }
640 // (3)
641 QVariant newVariant(std::in_place, type);
642 swap(newVariant);
643 // const cast is safe, we're in a non-const method
644 return const_cast<void *>(d.storage());
645}
646
932 : d()
933{
934 *this = fromMetaType(type, copy);
935}
936
937QVariant::QVariant(int val) noexcept : d(std::piecewise_construct_t{}, val) {}
938QVariant::QVariant(uint val) noexcept : d(std::piecewise_construct_t{}, val) {}
939QVariant::QVariant(qlonglong val) noexcept : d(std::piecewise_construct_t{}, val) {}
940QVariant::QVariant(qulonglong val) noexcept : d(std::piecewise_construct_t{}, val) {}
941QVariant::QVariant(bool val) noexcept : d(std::piecewise_construct_t{}, val) {}
942QVariant::QVariant(double val) noexcept : d(std::piecewise_construct_t{}, val) {}
943QVariant::QVariant(float val) noexcept : d(std::piecewise_construct_t{}, val) {}
944
945QVariant::QVariant(const QByteArray &val) noexcept : d(std::piecewise_construct_t{}, val) {}
946#ifndef QT_BOOTSTRAPPED
947QVariant::QVariant(const QBitArray &val) noexcept : d(std::piecewise_construct_t{}, val) {}
948#endif
949QVariant::QVariant(const QString &val) noexcept : d(std::piecewise_construct_t{}, val) {}
950QVariant::QVariant(QChar val) noexcept : d(std::piecewise_construct_t{}, val) {}
951QVariant::QVariant(const QStringList &val) noexcept : d(std::piecewise_construct_t{}, val) {}
952
953QVariant::QVariant(QDate val) noexcept : d(std::piecewise_construct_t{}, val) {}
954QVariant::QVariant(QTime val) noexcept : d(std::piecewise_construct_t{}, val) {}
955QVariant::QVariant(const QDateTime &val) noexcept : d(std::piecewise_construct_t{}, val) {}
956
957QVariant::QVariant(const QList<QVariant> &list) noexcept : d(std::piecewise_construct_t{}, list) {}
958QVariant::QVariant(const QMap<QString, QVariant> &map) noexcept : d(std::piecewise_construct_t{}, map) {}
959QVariant::QVariant(const QHash<QString, QVariant> &hash) noexcept : d(std::piecewise_construct_t{}, hash) {}
960
962
963#if QT_CONFIG(easingcurve)
964QVariant::QVariant(const QEasingCurve &val) : d(std::piecewise_construct_t{}, val) {}
965#endif
966#ifndef QT_NO_GEOM_VARIANT
968 : d(std::piecewise_construct_t{}, pt) {}
969QVariant::QVariant(QPointF pt) noexcept(Private::FitsInInternalSize<sizeof(qreal) * 2>)
970 : d(std::piecewise_construct_t{}, pt) {}
971QVariant::QVariant(QRect r) noexcept(Private::FitsInInternalSize<sizeof(int) * 4>)
972 : d(std::piecewise_construct_t{}, r) {}
973QVariant::QVariant(QRectF r) noexcept(Private::FitsInInternalSize<sizeof(qreal) * 4>)
974 : d(std::piecewise_construct_t{}, r) {}
975QVariant::QVariant(QLine l) noexcept(Private::FitsInInternalSize<sizeof(int) * 4>)
976 : d(std::piecewise_construct_t{}, l) {}
977QVariant::QVariant(QLineF l) noexcept(Private::FitsInInternalSize<sizeof(qreal) * 4>)
978 : d(std::piecewise_construct_t{}, l) {}
980 : d(std::piecewise_construct_t{}, s) {}
981QVariant::QVariant(QSizeF s) noexcept(Private::FitsInInternalSize<sizeof(qreal) * 2>)
982 : d(std::piecewise_construct_t{}, s) {}
983#endif
984#ifndef QT_BOOTSTRAPPED
985QVariant::QVariant(const QUrl &u) noexcept : d(std::piecewise_construct_t{}, u) {}
986#endif
987QVariant::QVariant(const QLocale &l) noexcept : d(std::piecewise_construct_t{}, l) {}
988#if QT_CONFIG(regularexpression)
989QVariant::QVariant(const QRegularExpression &re) noexcept : d(std::piecewise_construct_t{}, re) {}
990#endif // QT_CONFIG(regularexpression)
991QVariant::QVariant(QUuid uuid) noexcept(Private::FitsInInternalSize<16>) : d(std::piecewise_construct_t{}, uuid) {}
992#ifndef QT_BOOTSTRAPPED
993QVariant::QVariant(const QJsonValue &jsonValue) noexcept(Private::FitsInInternalSize<sizeof(CborValueStandIn)>)
994 : d(std::piecewise_construct_t{}, jsonValue)
995{ static_assert(sizeof(CborValueStandIn) == sizeof(QJsonValue)); }
996QVariant::QVariant(const QJsonObject &jsonObject) noexcept : d(std::piecewise_construct_t{}, jsonObject) {}
997QVariant::QVariant(const QJsonArray &jsonArray) noexcept : d(std::piecewise_construct_t{}, jsonArray) {}
998QVariant::QVariant(const QJsonDocument &jsonDocument) : d(std::piecewise_construct_t{}, jsonDocument) {}
999#endif // QT_BOOTSTRAPPED
1000#if QT_CONFIG(itemmodel)
1001QVariant::QVariant(const QModelIndex &modelIndex) noexcept(Private::FitsInInternalSize<8 + 2 * sizeof(quintptr)>)
1002 : d(std::piecewise_construct_t{}, modelIndex) {}
1003QVariant::QVariant(const QPersistentModelIndex &modelIndex) : d(std::piecewise_construct_t{}, modelIndex) {}
1004#endif
1005
1057{
1058 return d.type();
1059}
1060
1065{
1066 if (this == &variant)
1067 return *this;
1068
1069 clear();
1070 d = clonePrivate(variant.d);
1071 return *this;
1072}
1073
1089{
1090 if (!d.is_shared || d.data.shared->ref.loadRelaxed() == 1)
1091 return;
1092
1093 Q_ASSERT(isValidMetaTypeForVariant(d.typeInterface(), constData()));
1094 Private dd(d.typeInterface());
1095 // null variant is never shared; anything else is NonNull
1096 customConstruct<UseCopy, NonNull>(d.typeInterface(), &dd, constData());
1097 if (!d.data.shared->ref.deref())
1098 customClear(&d);
1099 d.data.shared = dd.data.shared;
1100}
1101
1114const char *QVariant::typeName() const
1115{
1116 return d.type().name();
1117}
1118
1124{
1125 if (!d.is_shared || !d.data.shared->ref.deref())
1126 customClear(&d);
1127 d = {};
1128}
1129
1151#ifndef QT_NO_DATASTREAM
1152enum { MapFromThreeCount = 36 };
1154{
1156 QMetaType::QVariantMap,
1157 QMetaType::QVariantList,
1158 QMetaType::QString,
1159 QMetaType::QStringList,
1160 QMetaType::QFont,
1161 QMetaType::QPixmap,
1162 QMetaType::QBrush,
1163 QMetaType::QRect,
1164 QMetaType::QSize,
1165 QMetaType::QColor,
1166 QMetaType::QPalette,
1167 0, // ColorGroup
1168 QMetaType::QIcon,
1169 QMetaType::QPoint,
1170 QMetaType::QImage,
1171 QMetaType::Int,
1172 QMetaType::UInt,
1173 QMetaType::Bool,
1174 QMetaType::Double,
1175 0, // Buggy ByteArray, QByteArray never had id == 20
1176 QMetaType::QPolygon,
1177 QMetaType::QRegion,
1178 QMetaType::QBitmap,
1179 QMetaType::QCursor,
1180 QMetaType::QSizePolicy,
1181 QMetaType::QDate,
1182 QMetaType::QTime,
1183 QMetaType::QDateTime,
1184 QMetaType::QByteArray,
1185 QMetaType::QBitArray,
1186#if QT_CONFIG(shortcut)
1187 QMetaType::QKeySequence,
1188#else
1189 0, // QKeySequence
1190#endif
1191 QMetaType::QPen,
1192 QMetaType::LongLong,
1193 QMetaType::ULongLong,
1194#if QT_CONFIG(easingcurve)
1195 QMetaType::QEasingCurve
1196#endif
1197};
1198
1199// values needed to map Qt5 based type id's to Qt6 based ones
1200constexpr int Qt5UserType = 1024;
1201constexpr int Qt5LastCoreType = QMetaType::QCborMap;
1202constexpr int Qt5FirstGuiType = 64;
1203constexpr int Qt5LastGuiType = 87;
1204constexpr int Qt5SizePolicy = 121;
1205constexpr int Qt5RegExp = 27;
1206constexpr int Qt5KeySequence = 75;
1207constexpr int Qt5QQuaternion = 85;
1208
1210
1218{
1219 clear();
1220
1222 s >> typeId;
1223 if (s.version() < QDataStream::Qt_4_0) {
1224 // map to Qt 5 ids
1226 return;
1228 } else if (s.version() < QDataStream::Qt_5_0) {
1229 // map to Qt 5 type ids
1230 if (typeId == 127 /* QVariant::UserType */) {
1232 } else if (typeId >= 128 && typeId != Qt5UserType) {
1233 // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
1234 // by moving all ids down by 97.
1235 typeId -= 97;
1236 } else if (typeId == 75 /* QSizePolicy */) {
1238 } else if (typeId > 75 && typeId <= 86) {
1239 // and as a result these types received lower ids too
1240 // QKeySequence QPen QTextLength QTextFormat QTransform QMatrix4x4 QVector2D QVector3D QVector4D QQuaternion
1241 typeId -=1;
1242 }
1243 }
1244 if (s.version() < QDataStream::Qt_6_0) {
1245 // map from Qt 5 to Qt 6 values
1246 if (typeId == Qt5UserType) {
1248 } else if (typeId >= Qt5FirstGuiType && typeId <= Qt5LastGuiType) {
1250 } else if (typeId == Qt5SizePolicy) {
1251 typeId = QMetaType::QSizePolicy;
1252 } else if (typeId == Qt5RegExp) {
1253 typeId = QMetaType::fromName("QRegExp").id();
1254 }
1255 }
1256
1257 qint8 is_null = false;
1258 if (s.version() >= QDataStream::Qt_4_2)
1259 s >> is_null;
1260 if (typeId == QMetaType::User) {
1262 s >> name;
1265 s.setStatus(QDataStream::ReadCorruptData);
1266 qWarning("QVariant::load: unknown user type with name %s.", name.constData());
1267 return;
1268 }
1269 }
1270 create(typeId, nullptr);
1271 d.is_null = is_null;
1272
1273 if (!isValid()) {
1274 if (s.version() < QDataStream::Qt_5_0) {
1275 // Since we wrote something, we should read something
1276 QString x;
1277 s >> x;
1278 }
1279 d.is_null = true;
1280 return;
1281 }
1282
1283 // const cast is safe since we operate on a newly constructed variant
1284 void *data = const_cast<void *>(constData());
1285 if (!d.type().load(s, data)) {
1286 s.setStatus(QDataStream::ReadCorruptData);
1287 qWarning("QVariant::load: unable to load type %d.", d.type().id());
1288 }
1289}
1290
1298{
1299 quint32 typeId = d.type().id();
1300 bool saveAsUserType = false;
1301 if (typeId >= QMetaType::User) {
1303 saveAsUserType = true;
1304 }
1305 if (s.version() < QDataStream::Qt_6_0) {
1306 // map to Qt 5 values
1307 if (typeId == QMetaType::User) {
1309 if (!strcmp(d.type().name(), "QRegExp")) {
1310 typeId = 27; // QRegExp in Qt 4/5
1311 }
1313 // the type didn't exist in Qt 5
1315 saveAsUserType = true;
1318 if (typeId > Qt5LastGuiType) {
1320 saveAsUserType = true;
1321 }
1322 } else if (typeId == QMetaType::QSizePolicy) {
1324 }
1325 }
1326 if (s.version() < QDataStream::Qt_4_0) {
1327 int i;
1328 for (i = 0; i <= MapFromThreeCount - 1; ++i) {
1329 if (mapIdFromQt3ToCurrent[i] == typeId) {
1330 typeId = i;
1331 break;
1332 }
1333 }
1334 if (i >= MapFromThreeCount) {
1335 s << QVariant();
1336 return;
1337 }
1338 } else if (s.version() < QDataStream::Qt_5_0) {
1339 if (typeId == Qt5UserType) {
1340 typeId = 127; // QVariant::UserType had this value in Qt4
1341 saveAsUserType = true;
1342 } else if (typeId >= 128 - 97 && typeId <= Qt5LastCoreType) {
1343 // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
1344 // by moving all ids down by 97.
1345 typeId += 97;
1346 } else if (typeId == Qt5SizePolicy) {
1347 typeId = 75;
1348 } else if (typeId >= Qt5KeySequence && typeId <= Qt5QQuaternion) {
1349 // and as a result these types received lower ids too
1350 typeId += 1;
1351 } else if (typeId > Qt5QQuaternion || typeId == QMetaType::QUuid) {
1352 // These existed in Qt 4 only as a custom type
1353 typeId = 127;
1354 saveAsUserType = true;
1355 }
1356 }
1357 const char *typeName = nullptr;
1358 if (saveAsUserType) {
1359 if (s.version() < QDataStream::Qt_6_0)
1361 if (!typeName)
1362 typeName = d.type().name();
1363 }
1364 s << typeId;
1365 if (s.version() >= QDataStream::Qt_4_2)
1366 s << qint8(d.is_null);
1367 if (typeName)
1368 s << typeName;
1369
1370 if (!isValid()) {
1371 if (s.version() < QDataStream::Qt_5_0)
1372 s << QString();
1373 return;
1374 }
1375
1376 if (!d.type().save(s, constData())) {
1377 qWarning("QVariant::save: unable to save type '%s' (type id: %d).\n",
1378 d.type().name(), d.type().id());
1379 Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
1380 }
1381}
1382
1403{
1404 p.load(s);
1405 return s;
1406}
1407
1415{
1416 p.save(s);
1417 return s;
1418}
1419
1433#endif //QT_NO_DATASTREAM
1434
1453{
1454 return qvariant_cast<QStringList>(*this);
1455}
1456
1473{
1474 return qvariant_cast<QString>(*this);
1475}
1476
1489{
1490 return qvariant_cast<QVariantMap>(*this);
1491}
1492
1500{
1501 return qvariant_cast<QVariantHash>(*this);
1502}
1503
1517{
1518 return qvariant_cast<QDate>(*this);
1519}
1520
1534{
1535 return qvariant_cast<QTime>(*this);
1536}
1537
1551{
1552 return qvariant_cast<QDateTime>(*this);
1553}
1554
1564#if QT_CONFIG(easingcurve)
1565QEasingCurve QVariant::toEasingCurve() const
1566{
1567 return qvariant_cast<QEasingCurve>(*this);
1568}
1569#endif
1570
1581{
1582 return qvariant_cast<QByteArray>(*this);
1583}
1584
1585#ifndef QT_NO_GEOM_VARIANT
1596{
1597 return qvariant_cast<QPoint>(*this);
1598}
1599
1609{
1610 return qvariant_cast<QRect>(*this);
1611}
1612
1622{
1623 return qvariant_cast<QSize>(*this);
1624}
1625
1635{
1636 return qvariant_cast<QSizeF>(*this);
1637}
1638
1649{
1650 return qvariant_cast<QRectF>(*this);
1651}
1652
1662{
1663 return qvariant_cast<QLineF>(*this);
1664}
1665
1675{
1676 return qvariant_cast<QLine>(*this);
1677}
1678
1689{
1690 return qvariant_cast<QPointF>(*this);
1691}
1692
1693#endif // QT_NO_GEOM_VARIANT
1694
1695#ifndef QT_BOOTSTRAPPED
1705{
1706 return qvariant_cast<QUrl>(*this);
1707}
1708#endif
1709
1719{
1720 return qvariant_cast<QLocale>(*this);
1721}
1722
1723#if QT_CONFIG(regularexpression)
1733QRegularExpression QVariant::toRegularExpression() const
1734{
1735 return qvariant_cast<QRegularExpression>(*this);
1736}
1737#endif // QT_CONFIG(regularexpression)
1738
1739#if QT_CONFIG(itemmodel)
1748QModelIndex QVariant::toModelIndex() const
1749{
1750 return qvariant_cast<QModelIndex>(*this);
1751}
1752
1761QPersistentModelIndex QVariant::toPersistentModelIndex() const
1762{
1763 return qvariant_cast<QPersistentModelIndex>(*this);
1764}
1765#endif // QT_CONFIG(itemmodel)
1766
1777{
1778 return qvariant_cast<QUuid>(*this);
1779}
1780
1781#ifndef QT_BOOTSTRAPPED
1791{
1792 return qvariant_cast<QJsonValue>(*this);
1793}
1794
1804{
1805 return qvariant_cast<QJsonObject>(*this);
1806}
1807
1817{
1818 return qvariant_cast<QJsonArray>(*this);
1819}
1820
1830{
1831 return qvariant_cast<QJsonDocument>(*this);
1832}
1833#endif // QT_BOOTSTRAPPED
1834
1845{
1846 return qvariant_cast<QChar>(*this);
1847}
1848
1849#ifndef QT_BOOTSTRAPPED
1857{
1858 return qvariant_cast<QBitArray>(*this);
1859}
1860#endif // QT_BOOTSTRAPPED
1861
1862template <typename T>
1864{
1865 QMetaType t = QMetaType::fromType<T>();
1866 if (ok)
1867 *ok = true;
1868
1869 if (d.type() == t)
1870 return d.get<T>();
1871
1872 T ret = 0;
1873 bool success = QMetaType::convert(d.type(), d.storage(), t, &ret);
1874 if (ok)
1875 *ok = success;
1876 return ret;
1877}
1878
1896int QVariant::toInt(bool *ok) const
1897{
1898 return qNumVariantToHelper<int>(d, ok);
1899}
1900
1919{
1920 return qNumVariantToHelper<uint>(d, ok);
1921}
1922
1936{
1937 return qNumVariantToHelper<qlonglong>(d, ok);
1938}
1939
1953{
1954 return qNumVariantToHelper<qulonglong>(d, ok);
1955}
1956
1970{
1971 auto boolType = QMetaType::fromType<bool>();
1972 if (d.type() == boolType)
1973 return d.get<bool>();
1974
1975 bool res = false;
1976 QMetaType::convert(d.type(), constData(), boolType, &res);
1977 return res;
1978}
1979
1992double QVariant::toDouble(bool *ok) const
1993{
1994 return qNumVariantToHelper<double>(d, ok);
1995}
1996
2011float QVariant::toFloat(bool *ok) const
2012{
2013 return qNumVariantToHelper<float>(d, ok);
2014}
2015
2031{
2032 return qNumVariantToHelper<qreal>(d, ok);
2033}
2034
2047{
2048 return qvariant_cast<QVariantList>(*this);
2049}
2050
2117{
2118 if (d.type() == targetType)
2119 return targetType.isValid();
2120
2121 QVariant oldValue = *this;
2122
2123 clear();
2124 create(targetType, nullptr);
2125 if (!oldValue.canConvert(targetType))
2126 return false;
2127
2128 // Fail if the value is not initialized or was forced null by a previous failed convert.
2129 if (oldValue.d.is_null && oldValue.d.type().id() != QMetaType::Nullptr)
2130 return false;
2131
2132 bool ok = QMetaType::convert(oldValue.d.type(), oldValue.constData(), targetType, data());
2133 d.is_null = !ok;
2134 return ok;
2135}
2136
2142bool QVariant::convert(int type, void *ptr) const
2143{
2145}
2146
2150bool QVariant::view(int type, void *ptr)
2151{
2152 return QMetaType::view(d.type(), data(), QMetaType(type), ptr);
2153}
2154
2203static bool qIsNumericType(uint tp)
2204{
2205 static const qulonglong numericTypeBits =
2206 Q_UINT64_C(1) << QMetaType::QString |
2207 Q_UINT64_C(1) << QMetaType::Bool |
2208 Q_UINT64_C(1) << QMetaType::Double |
2209 Q_UINT64_C(1) << QMetaType::Float |
2210 Q_UINT64_C(1) << QMetaType::Char |
2211 Q_UINT64_C(1) << QMetaType::Char16 |
2212 Q_UINT64_C(1) << QMetaType::Char32 |
2213 Q_UINT64_C(1) << QMetaType::SChar |
2214 Q_UINT64_C(1) << QMetaType::UChar |
2215 Q_UINT64_C(1) << QMetaType::Short |
2216 Q_UINT64_C(1) << QMetaType::UShort |
2217 Q_UINT64_C(1) << QMetaType::Int |
2218 Q_UINT64_C(1) << QMetaType::UInt |
2219 Q_UINT64_C(1) << QMetaType::Long |
2220 Q_UINT64_C(1) << QMetaType::ULong |
2221 Q_UINT64_C(1) << QMetaType::LongLong |
2222 Q_UINT64_C(1) << QMetaType::ULongLong;
2223 return tp < (CHAR_BIT * sizeof numericTypeBits) ? numericTypeBits & (Q_UINT64_C(1) << tp) : false;
2224}
2225
2226static bool qIsFloatingPoint(uint tp)
2227{
2228 return tp == QMetaType::Double || tp == QMetaType::Float || tp == QMetaType::Float16;
2229}
2230
2232 const QtPrivate::QMetaTypeInterface *iface2)
2233{
2234 if (!iface1 || !iface2)
2235 return false;
2236
2237 // We don't need QMetaType::id() here because the type Id is always stored
2238 // directly for all built-in types.
2239 bool isNumeric1 = qIsNumericType(iface1->typeId);
2240 bool isNumeric2 = qIsNumericType(iface2->typeId);
2241
2242 // if they're both numeric (or QString), then they can be compared
2243 if (isNumeric1 && isNumeric2)
2244 return true;
2245
2246 bool isEnum1 = iface1->flags & QMetaType::IsEnumeration;
2247 bool isEnum2 = iface2->flags & QMetaType::IsEnumeration;
2248
2249 // if both are enums, we can only compare if they are the same enum
2250 // (the language does allow comparing two different enum types, but that's
2251 // usually considered poor coding and produces a warning)
2252 if (isEnum1 && isEnum2)
2253 return QMetaType(iface1) == QMetaType(iface2);
2254
2255 // if one is an enum and the other is a numeric, we can compare too
2256 if (isEnum1 && isNumeric2)
2257 return true;
2258 if (isNumeric1 && isEnum2)
2259 return true;
2260
2261 // we need at least one enum and one numeric...
2262 return false;
2263}
2264
2266 const QtPrivate::QMetaTypeInterface *iface2)
2267{
2268 Q_ASSERT(canBeNumericallyCompared(iface1, iface2));
2269
2270 // We don't need QMetaType::id() here because the type Id is always stored
2271 // directly for the types we're comparing against below.
2272 uint t1 = iface1->typeId;
2273 uint t2 = iface2->typeId;
2274
2275 if ((t1 == QMetaType::Bool && t2 == QMetaType::QString) ||
2276 (t2 == QMetaType::Bool && t1 == QMetaType::QString))
2277 return QMetaType::Bool;
2278
2279 // C++ integral ranks: (4.13 Integer conversion rank [conv.rank])
2280 // bool < signed char < short < int < long < long long
2281 // unsigneds have the same rank as their signed counterparts
2282 // C++ integral promotion rules (4.5 Integral Promotions [conv.prom])
2283 // - any type with rank less than int can be converted to int or unsigned int
2284 // 5 Expressions [expr] paragraph 9:
2285 // - if either operand is double, the other shall be converted to double
2286 // - " " float, " " " float
2287 // - if both operands have the same type, no further conversion is needed.
2288 // - if both are signed or if both are unsigned, convert to the one with highest rank
2289 // - if the unsigned has higher or same rank, convert the signed to the unsigned one
2290 // - if the signed can represent all values of the unsigned, convert to the signed
2291 // - otherwise, convert to the unsigned corresponding to the rank of the signed
2292
2293 // floating point: we deviate from the C++ standard by always using qreal
2295 return QMetaType::QReal;
2296
2297 auto isUnsigned = [](uint tp) {
2298 // only types for which sizeof(T) >= sizeof(int); lesser ones promote to int
2299 return tp == QMetaType::ULongLong || tp == QMetaType::ULong ||
2300 tp == QMetaType::UInt || tp == QMetaType::Char32;
2301 };
2302 bool isUnsigned1 = isUnsigned(t1);
2303 bool isUnsigned2 = isUnsigned(t2);
2304
2305 // integral rules:
2306 // 1) if either type is a 64-bit unsigned, compare as 64-bit unsigned
2307 if (isUnsigned1 && iface1->size > sizeof(int))
2308 return QMetaType::ULongLong;
2309 if (isUnsigned2 && iface2->size > sizeof(int))
2310 return QMetaType::ULongLong;
2311
2312 // 2) if either type is 64-bit, compare as 64-bit signed
2313 if (iface1->size > sizeof(int) || iface2->size > sizeof(int))
2314 return QMetaType::LongLong;
2315
2316 // 3) if either type is 32-bit unsigned, compare as 32-bit unsigned
2317 if (isUnsigned1 || isUnsigned2)
2318 return QMetaType::UInt;
2319
2320 // 4) otherwise, just do int promotion
2321 return QMetaType::Int;
2322}
2323
2324template <typename Numeric> static QPartialOrdering spaceShip(Numeric lhs, Numeric rhs)
2325{
2326 if (lhs == rhs)
2328 if constexpr (std::numeric_limits<Numeric>::has_quiet_NaN) {
2329 if (std::isnan(lhs) || std::isnan(rhs))
2331 }
2332
2333 bool smaller;
2334 if constexpr (std::is_same_v<Numeric, QObject *>)
2335 smaller = std::less<QObject *>()(lhs, rhs); // can't use less all the time because of bool
2336 else
2337 smaller = lhs < rhs;
2339}
2340
2342{
2343 // use toLongLong to retrieve the data, it gets us all the bits
2344 std::optional<qlonglong> l1 = qConvertToNumber(d1, promotedType == QMetaType::Bool);
2345 std::optional<qlonglong> l2 = qConvertToNumber(d2, promotedType == QMetaType::Bool);
2346 if (!l1 || !l2)
2348 if (promotedType == QMetaType::UInt)
2349 return spaceShip<uint>(*l1, *l2);
2350 if (promotedType == QMetaType::LongLong)
2351 return spaceShip<qlonglong>(*l1, *l2);
2352 if (promotedType == QMetaType::ULongLong)
2353 return spaceShip<qulonglong>(*l1, *l2);
2354
2355 return spaceShip<int>(*l1, *l2);
2356}
2357
2359{
2360 uint promotedType = numericTypePromotion(d1->typeInterface(), d2->typeInterface());
2361 if (promotedType != QMetaType::QReal)
2362 return integralCompare(promotedType, d1, d2);
2363
2364 // floating point comparison
2365 const auto r1 = qConvertToRealNumber(d1);
2366 const auto r2 = qConvertToRealNumber(d2);
2367 if (!r1 || !r2)
2369 if (*r1 == *r2)
2371
2372 return spaceShip(*r1, *r2);
2373}
2374
2375#ifndef QT_BOOTSTRAPPED
2376static bool qvCanConvertMetaObject(QMetaType fromType, QMetaType toType)
2377{
2378 if ((fromType.flags() & QMetaType::PointerToQObject)
2379 && (toType.flags() & QMetaType::PointerToQObject)) {
2380 const QMetaObject *f = fromType.metaObject();
2381 const QMetaObject *t = toType.metaObject();
2382 return f && t && (f->inherits(t) || t->inherits(f));
2383 }
2384 return false;
2385}
2386
2388{
2389 return spaceShip<QObject *>(d1->get<QObject *>(), d2->get<QObject *>());
2390}
2391#endif
2392
2396bool QVariant::equals(const QVariant &v) const
2397{
2398 auto metatype = d.type();
2399
2400 if (metatype != v.metaType()) {
2401 // try numeric comparisons, with C++ type promotion rules (no conversion)
2402 if (canBeNumericallyCompared(metatype.iface(), v.d.type().iface()))
2404#ifndef QT_BOOTSTRAPPED
2405 // if both types are related pointers to QObjects, check if they point to the same object
2406 if (qvCanConvertMetaObject(metatype, v.metaType()))
2408#endif
2409 return false;
2410 }
2411
2412 // For historical reasons: QVariant() == QVariant()
2413 if (!metatype.isValid())
2414 return true;
2415
2416 return metatype.equals(d.storage(), v.d.storage());
2417}
2418
2442{
2443 QMetaType t = lhs.d.type();
2444 if (t != rhs.d.type()) {
2445 // try numeric comparisons, with C++ type promotion rules (no conversion)
2446 if (canBeNumericallyCompared(lhs.d.type().iface(), rhs.d.type().iface()))
2447 return numericCompare(&lhs.d, &rhs.d);
2448#ifndef QT_BOOTSTRAPPED
2449 if (qvCanConvertMetaObject(lhs.metaType(), rhs.metaType()))
2450 return pointerCompare(&lhs.d, &rhs.d);
2451#endif
2453 }
2454 return t.compare(lhs.constData(), rhs.constData());
2455}
2456
2477{
2478 detach();
2479 // set is_null to false, as the caller is likely to write some data into this variant
2480 d.is_null = false;
2481 return const_cast<void *>(constData());
2482}
2483
2532{
2533 if (d.is_null || !metaType().isValid())
2534 return true;
2536 return d.get<void *>() == nullptr;
2537 return false;
2538}
2539
2540#ifndef QT_NO_DEBUG_STREAM
2541QDebug QVariant::qdebugHelper(QDebug dbg) const
2542{
2543 QDebugStateSaver saver(dbg);
2544 const uint typeId = d.type().id();
2545 dbg.nospace() << "QVariant(";
2547 dbg << d.type().name() << ", ";
2548 bool streamed = d.type().debugStream(dbg, d.storage());
2549 if (!streamed && canConvert<QString>())
2550 dbg << toString();
2551 } else {
2552 dbg << "Invalid";
2553 }
2554 dbg << ')';
2555 return dbg;
2556}
2557
2558QVariant QVariant::moveConstruct(QMetaType type, void *data)
2559{
2560 QVariant var;
2561 var.d = QVariant::Private(type.d_ptr);
2562 customConstruct<ForceMove, NonNull>(type.d_ptr, &var.d, data);
2563 return var;
2564}
2565
2566QVariant QVariant::copyConstruct(QMetaType type, const void *data)
2567{
2568 QVariant var;
2569 var.d = QVariant::Private(type.d_ptr);
2570 customConstruct<UseCopy, NonNull>(type.d_ptr, &var.d, data);
2571 return var;
2572}
2573
2574#if QT_DEPRECATED_SINCE(6, 0)
2577
2578QDebug operator<<(QDebug dbg, const QVariant::Type p)
2579{
2580 QDebugStateSaver saver(dbg);
2581 dbg.nospace() << "QVariant::"
2582 << (int(p) != int(QMetaType::UnknownType)
2583 ? QMetaType(p).name()
2584 : "Invalid");
2585 return dbg;
2586}
2587
2589#endif
2590
2591#endif
2592
2743{
2745 type.registerType();
2746 const auto iface = type.iface();
2747 if (isValidMetaTypeForVariant(iface, copy)) {
2748 result.d = Private(iface);
2749 customConstruct(iface, &result.d, copy);
2750 }
2751 return result;
2752}
2753
2881{
2882 if (type == QMetaType::fromType<QVariant>())
2883 return &value;
2884
2885 if (type == value.metaType())
2886 return value.constData();
2887
2888 if (value.canConvert(type)) {
2889 converted = value;
2890 if (converted.convert(type))
2891 return converted.constData();
2892 }
2893
2894 return nullptr;
2895}
2896
2901{
2902 if (const void *result = convert(value, type))
2903 return result;
2904
2905 converted = QVariant(type);
2906 return converted.constData();
2907}
2908
2982
2987{
2988 return m_variant;
2989}
2990
2996{
2997 return &m_variant;
2998}
2999
\inmodule QtCore
Definition qbitarray.h:13
\inmodule QtCore
Definition qbytearray.h:57
qlonglong toLongLong(bool *ok=nullptr, int base=10) const
Returns the byte array converted to a {long long} using base base, which is ten by default.
\inmodule QtCore\reentrant
Definition qcborvalue.h:47
bool isDouble() const
Returns true if this QCborValue is of the floating-point type.
Definition qcborvalue.h:166
bool isInteger() const
Returns true if this QCborValue is of the integer type.
Definition qcborvalue.h:155
\inmodule QtCore
\inmodule QtCore\reentrant
Definition qdatastream.h:46
\inmodule QtCore\reentrant
Definition qdatetime.h:283
\inmodule QtCore \reentrant
Definition qdatetime.h:29
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore\reentrant
Definition qjsonarray.h:18
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
Definition qjsonobject.h:20
\inmodule QtCore\reentrant
Definition qjsonvalue.h:25
bool isDouble() const
Returns true if the value contains a double.
Definition qjsonvalue.h:74
\inmodule QtCore\compares equality \compareswith equality QLine \endcompareswith
Definition qline.h:192
\inmodule QtCore\compares equality \compareswith equality QLineF \endcompareswith
Definition qline.h:18
\inmodule QtCore
Definition qmetatype.h:341
constexpr TypeFlags flags() const
Definition qmetatype.h:2658
const QtPrivate::QMetaTypeInterface * iface() const
Definition qmetatype.h:771
static bool view(QMetaType fromType, void *from, QMetaType toType, void *to)
Creates a mutable view on the object at from of fromType in the preallocated space at to typed toType...
bool debugStream(QDebug &dbg, const void *rhs)
Streams the object at rhs to the debug stream dbg.
static QMetaType fromName(QByteArrayView name)
Returns a QMetaType matching typeName.
bool isValid() const
int id(int=0) const
Definition qmetatype.h:475
@ PointerToQObject
Definition qmetatype.h:406
@ IsEnumeration
Definition qmetatype.h:407
constexpr const QMetaObject * metaObject() const
Definition qmetatype.h:2663
constexpr const char * name() const
Definition qmetatype.h:2680
bool load(QDataStream &stream, void *data) const
Reads the object of this type from the given stream into data.
bool save(QDataStream &stream, const void *data) const
Writes the object pointed to by data to the given stream.
static bool convert(QMetaType fromType, const void *from, QMetaType toType, void *to)
Converts the object at from from fromType to the preallocated space at to typed toType.
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:103
\variable Qt::partial_ordering::less
Definition qcompare.h:679
static const QPartialOrdering Less
Definition qcompare.h:681
static const QPartialOrdering Greater
Definition qcompare.h:683
static const QPartialOrdering Equivalent
Definition qcompare.h:682
static const QPartialOrdering Unordered
Definition qcompare.h:684
\inmodule QtCore\reentrant
Definition qpoint.h:217
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore \reentrant
\inmodule QtCore
Definition qsize.h:208
\inmodule QtCore
Definition qsize.h:25
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
double toDouble(bool *ok=nullptr) const
Returns the string converted to a double value.
Definition qstring.cpp:7904
\inmodule QtCore \reentrant
Definition qdatetime.h:215
\inmodule QtCore
Definition qurl.h:94
\inmodule QtCore
Definition quuid.h:31
QVariantConstPointer(QVariant variant)
Constructs a QVariantConstPointer from a variant.
const QVariant * operator->() const
Returns a const pointer to the QVariant, conforming to the conventions for operator->().
QVariant operator*() const
Dereferences the QVariantConstPointer to retrieve its internal QVariant.
\inmodule QtCore
Definition qvariant.h:65
QChar toChar() const
Returns the variant as a QChar if the variant has userType() \l QMetaType::QChar, \l QMetaType::Int,...
static QVariant fromMetaType(QMetaType type, const void *copy=nullptr)
void * data()
Returns a pointer to the contained object as a generic void* that can be written to.
bool convert(QMetaType type)
Casts the variant to the requested type, targetType.
QVariant() noexcept
Constructs an invalid variant.
Definition qvariant.h:218
QDataStream & operator<<(QDataStream &s, const QVariant &p)
Writes a variant p to the stream s.
void clear()
Convert this variant to type QMetaType::UnknownType and free up any resources used.
QPointF toPointF() const
Returns the variant as a QPointF if the variant has userType() \l QMetaType::QPoint or \l QMetaType::...
T view()
Returns a mutable view of template type {T} on the stored value.
Definition qvariant.h:520
static QPartialOrdering compare(const QVariant &lhs, const QVariant &rhs)
Compares the objects at lhs and rhs for ordering.
bool isDetached() const
Definition qvariant.h:745
qreal toReal(bool *ok=nullptr) const
Returns the variant as a qreal if the variant has userType() \l QMetaType::Double,...
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has userType() \l QMetaType::QDateTime,...
void swap(QVariant &other) noexcept
Definition qvariant.h:337
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:714
QJsonValue toJsonValue() const
double toDouble(bool *ok=nullptr) const
Returns the variant as a double if the variant has userType() \l QMetaType::Double,...
QList< QVariant > toList() const
Returns the variant as a QVariantList if the variant has userType() \l QMetaType::QVariantList.
QMap< QString, QVariant > toMap() const
Returns the variant as a QVariantMap if the variant has type() \l QMetaType::QVariantMap.
qlonglong toLongLong(bool *ok=nullptr) const
Returns the variant as a long long int if the variant has userType() \l QMetaType::LongLong,...
QPoint toPoint() const
Returns the variant as a QPoint if the variant has userType() \l QMetaType::QPoint or \l QMetaType::Q...
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QLocale toLocale() const
Returns the variant as a QLocale if the variant has userType() \l QMetaType::QLocale; otherwise retur...
QSize toSize() const
Returns the variant as a QSize if the variant has userType() \l QMetaType::QSize; otherwise returns a...
void save(QDataStream &ds) const
Internal function for saving a variant to the stream s.
QTime toTime() const
Returns the variant as a QTime if the variant has userType() \l QMetaType::QTime, \l QMetaType::QDate...
float toFloat(bool *ok=nullptr) const
Returns the variant as a float if the variant has userType() \l QMetaType::Double,...
uint toUInt(bool *ok=nullptr) const
Returns the variant as an unsigned int if the variant has userType() \l QMetaType::UInt,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
void load(QDataStream &ds)
Internal function for loading a variant from stream s.
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
QBitArray toBitArray() const
Returns the variant as a QBitArray if the variant has userType() \l QMetaType::QBitArray; otherwise r...
QJsonArray toJsonArray() const
QHash< QString, QVariant > toHash() const
Returns the variant as a QHash<QString, QVariant> if the variant has type() \l QMetaType::QVariantHas...
int typeId() const
Returns the storage type of the value stored in the variant.
Definition qvariant.h:340
bool isNull() const
Returns true if this is a null variant, false otherwise.
const char * typeName() const
Returns the name of the type stored in the variant.
QJsonDocument toJsonDocument() const
QRectF toRectF() const
Returns the variant as a QRectF if the variant has userType() \l QMetaType::QRect or \l QMetaType::QR...
QLineF toLineF() const
Returns the variant as a QLineF if the variant has userType() \l QMetaType::QLineF; otherwise returns...
void detach()
QVariant & operator=(const QVariant &other)
Move-assigns other to this QVariant instance.
QJsonObject toJsonObject() const
bool canConvert(QMetaType targetType) const
Definition qvariant.h:345
QRect toRect() const
Returns the variant as a QRect if the variant has userType() \l QMetaType::QRect; otherwise returns a...
QSizeF toSizeF() const
Returns the variant as a QSizeF if the variant has userType() \l QMetaType::QSizeF; otherwise returns...
QUuid toUuid() const
QDate toDate() const
Returns the variant as a QDate if the variant has userType() \l QMetaType::QDate, \l QMetaType::QDate...
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has userType() \l QMetaType::QByteArray or \l QMet...
QLine toLine() const
Returns the variant as a QLine if the variant has userType() \l QMetaType::QLine; otherwise returns a...
Private d
Definition qvariant.h:672
~QVariant()
Destroys the QVariant and the contained object.
Definition qvariant.cpp:529
QDataStream & operator>>(QDataStream &s, QVariant &p)
void create(int type, const void *copy)
Definition qvariant.cpp:507
QMetaType metaType() const
qulonglong toULongLong(bool *ok=nullptr) const
Returns the variant as an unsigned long long int if the variant has type() \l QMetaType::ULongLong,...
const void * constData() const
Definition qvariant.h:451
QStringList toStringList() const
Returns the variant as a QStringList if the variant has userType() \l QMetaType::QStringList,...
QUrl toUrl() const
Returns the variant as a QUrl if the variant has userType() \l QMetaType::QUrl; otherwise returns an ...
bool equals(const QVariant &other) const
const void * coerce(const QVariant &value, const QMetaType &type)
const void * convert(const QVariant &value, const QMetaType &type)
\keyword 16-bit Floating Point Support\inmodule QtCore \inheaderfile QFloat16
Definition qfloat16.h:47
QHash< int, QWidget * > hash
[35multi]
QMap< QString, QString > map
[6]
Combined button and popup list for selecting options.
bool isDestructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
bool isDefaultConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
bool isCopyConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
void copyConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy)
void destruct(const QtPrivate::QMetaTypeInterface *iface, void *where)
void construct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy)
void moveConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where, void *copy)
const char * typedefNameForType(const QtPrivate::QMetaTypeInterface *type_d)
constexpr QBindableInterface iface
Definition qproperty.h:666
static jboolean copy(JNIEnv *, jobject)
class QT6_ONLY(Q_CORE_EXPORT) QChar
Definition qchar.h:44
#define Q_FALLTHROUGH()
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_DEPRECATED
#define QT_WARNING_PUSH
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
qint64 qRound64(qfloat16 d) noexcept
Definition qfloat16.h:330
#define qWarning
Definition qlogging.h:166
return ret
static ControlElement< T > * ptr(QWidget *widget)
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLboolean r
[2]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
[4]
GLenum type
GLbitfield flags
GLuint name
GLdouble s
[6]
Definition qopenglext.h:235
GLuint res
GLuint GLfloat * val
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
static constexpr To convert(const std::array< Mapping, N > &mapping, From Mapping::*from, To Mapping::*to, From value, To defaultValue)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
#define t2
QT_BEGIN_NAMESPACE constexpr std::underlying_type_t< Enum > qToUnderlying(Enum e) noexcept
#define Q_UINT64_C(c)
Definition qtypes.h:58
unsigned int quint32
Definition qtypes.h:50
size_t quintptr
Definition qtypes.h:167
quint64 qulonglong
Definition qtypes.h:64
unsigned int uint
Definition qtypes.h:34
unsigned short ushort
Definition qtypes.h:33
QT_BEGIN_NAMESPACE typedef signed char qint8
Definition qtypes.h:45
double qreal
Definition qtypes.h:187
qint64 qlonglong
Definition qtypes.h:63
static double toDouble(Value v)
constexpr int Qt6ToQt5GuiTypeDelta
@ MapFromThreeCount
static QPartialOrdering spaceShip(Numeric lhs, Numeric rhs)
static bool qIsFloatingPoint(uint tp)
static QPartialOrdering numericCompare(const QVariant::Private *d1, const QVariant::Private *d2)
constexpr int Qt5QQuaternion
static bool qIsNumericType(uint tp)
static bool canBeNumericallyCompared(const QtPrivate::QMetaTypeInterface *iface1, const QtPrivate::QMetaTypeInterface *iface2)
constexpr int Qt5KeySequence
static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount]
static QPartialOrdering integralCompare(uint promotedType, const QVariant::Private *d1, const QVariant::Private *d2)
constexpr int Qt5LastCoreType
T qNumVariantToHelper(const QVariant::Private &d, bool *ok)
constexpr int Qt5FirstGuiType
static bool qvCanConvertMetaObject(QMetaType fromType, QMetaType toType)
constexpr int Qt5RegExp
constexpr int Qt5LastGuiType
static int numericTypePromotion(const QtPrivate::QMetaTypeInterface *iface1, const QtPrivate::QMetaTypeInterface *iface2)
constexpr int Qt5SizePolicy
constexpr int Qt5UserType
static QPartialOrdering pointerCompare(const QVariant::Private *d1, const QVariant::Private *d2)
static QVariant::PrivateShared * customConstructShared(size_t size, size_t align, F &&construct)
Definition qvariant_p.h:36
QList< int > list
[14]
QDataStream & operator<<(QDataStream &out, const MyClass &myObj)
[4]
QVariant variant
[1]
QDate d1(1995, 5, 17)
[0]
QDate d2(1995, 5, 20)
QRect r1(100, 200, 11, 16)
[0]
QRect r2(QPoint(100, 200), QSize(11, 16))
QSharedPointer< T > other(t)
[5]
view create()
\inmodule QtCore
static void free(PrivateShared *p)
Definition qvariant_p.h:70
static PrivateShared * create(size_t size, size_t align)
Definition qvariant_p.h:61
static size_t computeAllocationSize(size_t size, size_t align)
Definition qvariant_p.h:48
static int computeOffset(PrivateShared *ps, size_t align)
Definition qvariant_p.h:43
static constexpr bool canUseInternalSpace(const QtPrivate::QMetaTypeInterface *type)
Definition qvariant.h:103
const void * storage() const
Definition qvariant.h:124
quintptr is_shared
Definition qvariant.h:116
const T & get() const
Definition qvariant.h:128
quintptr packedType
Definition qvariant.h:118
const QtPrivate::QMetaTypeInterface * typeInterface() const
Definition qvariant.h:131
quintptr is_null
Definition qvariant.h:117
uchar data[MaxInternalSize]
Definition qvariant.h:112
QMetaType type() const
Definition qvariant.h:136