File indexing completed on 2026-08-05 09:27:44
0001
0002
0003
0004
0005 #ifndef QVARIANT_H
0006 #define QVARIANT_H
0007
0008 #include <QtCore/qatomic.h>
0009 #include <QtCore/qcompare.h>
0010 #include <QtCore/qcontainerfwd.h>
0011 #include <QtCore/qmetatype.h>
0012 #ifndef QT_NO_DEBUG_STREAM
0013 #include <QtCore/qdebug.h>
0014 #endif
0015
0016 #include <memory>
0017 #include <QtCore/q20type_traits.h>
0018 #include <QtCore/q23utility.h>
0019 #include <variant>
0020
0021 #if !defined(QT_LEAN_HEADERS) || QT_LEAN_HEADERS < 1
0022 # include <QtCore/qlist.h>
0023 # include <QtCore/qstringlist.h>
0024 # include <QtCore/qbytearraylist.h>
0025 # include <QtCore/qhash.h>
0026 # include <QtCore/qmap.h>
0027 # include <QtCore/qobject.h>
0028 #endif
0029
0030 QT_BEGIN_NAMESPACE
0031
0032 QT_ENABLE_P0846_SEMANTICS_FOR(get_if)
0033 QT_ENABLE_P0846_SEMANTICS_FOR(get)
0034
0035 class QBitArray;
0036 class QDataStream;
0037 class QDate;
0038 class QDateTime;
0039 class QEasingCurve;
0040 class QLine;
0041 class QLineF;
0042 class QLocale;
0043 class QModelIndex;
0044 class QPersistentModelIndex;
0045 class QPoint;
0046 class QPointF;
0047 class QRect;
0048 class QRectF;
0049 class QRegularExpression;
0050 class QSize;
0051 class QSizeF;
0052 class QTextFormat;
0053 class QTextLength;
0054 class QTime;
0055 class QTransform;
0056 class QUrl;
0057 class QVariant;
0058
0059 template<typename T>
0060 inline T qvariant_cast(const QVariant &);
0061
0062 namespace QtPrivate {
0063 template<> constexpr inline bool qIsRelocatable<QVariant> = true;
0064
0065 }
0066
0067 class Q_CORE_EXPORT QVariant
0068 {
0069 template <typename T, typename... Args>
0070 using if_constructible = std::enable_if_t<
0071 std::conjunction_v<
0072 std::is_copy_constructible<q20::remove_cvref_t<T>>,
0073 std::is_destructible<q20::remove_cvref_t<T>>,
0074 std::is_constructible<q20::remove_cvref_t<T>, Args...>
0075 >,
0076 bool>;
0077
0078 template <typename T>
0079 using if_rvalue = std::enable_if_t<!std::is_reference_v<T>, bool>;
0080
0081 struct CborValueStandIn { qint64 n; void *c; int t; };
0082 public:
0083 struct PrivateShared
0084 {
0085 private:
0086 inline PrivateShared() : ref(1) { }
0087 public:
0088 static int computeOffset(PrivateShared *ps, size_t align);
0089 static size_t computeAllocationSize(size_t size, size_t align);
0090 static PrivateShared *create(size_t size, size_t align);
0091 static void free(PrivateShared *p);
0092
0093 alignas(8) QAtomicInt ref;
0094 int offset;
0095
0096 const void *data() const { return reinterpret_cast<const uchar *>(this) + offset; }
0097 void *data() { return reinterpret_cast<uchar *>(this) + offset; }
0098 };
0099
0100 struct Private
0101 {
0102 static constexpr size_t MaxInternalSize = 3 * sizeof(void *);
0103 template <size_t S> static constexpr bool FitsInInternalSize = S <= MaxInternalSize;
0104 template<typename T> static constexpr bool CanUseInternalSpace =
0105 (QTypeInfo<T>::isRelocatable && FitsInInternalSize<sizeof(T)> && alignof(T) <= alignof(double));
0106 static constexpr bool canUseInternalSpace(const QtPrivate::QMetaTypeInterface *type)
0107 {
0108 Q_ASSERT(type);
0109 return QMetaType::TypeFlags(type->flags) & QMetaType::RelocatableType &&
0110 size_t(type->size) <= MaxInternalSize && size_t(type->alignment) <= alignof(double);
0111 }
0112
0113 union
0114 {
0115 uchar data[MaxInternalSize] = {};
0116 PrivateShared *shared;
0117 double _forAlignment;
0118 } data;
0119 quintptr is_shared : 1;
0120 quintptr is_null : 1;
0121 quintptr packedType : sizeof(QMetaType) * 8 - 2;
0122
0123 constexpr Private() noexcept : is_shared(false), is_null(true), packedType(0) {}
0124 explicit Private(const QtPrivate::QMetaTypeInterface *iface) noexcept;
0125 template <typename T>
0126 explicit Private(std::in_place_t, T &&t);
0127 template <typename T>
0128 explicit Private(std::piecewise_construct_t, const T &t)
0129 : Private{std::in_place, t} {}
0130
0131 const void *storage() const
0132 { return is_shared ? data.shared->data() : &data.data; }
0133
0134 template<typename T> const T &get() const
0135 { return *static_cast<const T *>(storage()); }
0136
0137 inline const QtPrivate::QMetaTypeInterface *typeInterface() const
0138 {
0139 return reinterpret_cast<const QtPrivate::QMetaTypeInterface *>(packedType << 2);
0140 }
0141
0142 inline QMetaType type() const
0143 {
0144 return QMetaType(typeInterface());
0145 }
0146 };
0147
0148 #if QT_DEPRECATED_SINCE(6, 0)
0149 enum QT_DEPRECATED_VERSION_X_6_0("Use QMetaType::Type instead.") Type
0150 {
0151 Invalid = QMetaType::UnknownType,
0152 Bool = QMetaType::Bool,
0153 Int = QMetaType::Int,
0154 UInt = QMetaType::UInt,
0155 LongLong = QMetaType::LongLong,
0156 ULongLong = QMetaType::ULongLong,
0157 Double = QMetaType::Double,
0158 Char = QMetaType::QChar,
0159 Map = QMetaType::QVariantMap,
0160 List = QMetaType::QVariantList,
0161 String = QMetaType::QString,
0162 StringList = QMetaType::QStringList,
0163 ByteArray = QMetaType::QByteArray,
0164 BitArray = QMetaType::QBitArray,
0165 Date = QMetaType::QDate,
0166 Time = QMetaType::QTime,
0167 DateTime = QMetaType::QDateTime,
0168 Url = QMetaType::QUrl,
0169 Locale = QMetaType::QLocale,
0170 Rect = QMetaType::QRect,
0171 RectF = QMetaType::QRectF,
0172 Size = QMetaType::QSize,
0173 SizeF = QMetaType::QSizeF,
0174 Line = QMetaType::QLine,
0175 LineF = QMetaType::QLineF,
0176 Point = QMetaType::QPoint,
0177 PointF = QMetaType::QPointF,
0178 #if QT_CONFIG(regularexpression)
0179 RegularExpression = QMetaType::QRegularExpression,
0180 #endif
0181 Hash = QMetaType::QVariantHash,
0182 #if QT_CONFIG(easingcurve)
0183 EasingCurve = QMetaType::QEasingCurve,
0184 #endif
0185 Uuid = QMetaType::QUuid,
0186 #if QT_CONFIG(itemmodel)
0187 ModelIndex = QMetaType::QModelIndex,
0188 PersistentModelIndex = QMetaType::QPersistentModelIndex,
0189 #endif
0190 LastCoreType = QMetaType::LastCoreType,
0191
0192 Font = QMetaType::QFont,
0193 Pixmap = QMetaType::QPixmap,
0194 Brush = QMetaType::QBrush,
0195 Color = QMetaType::QColor,
0196 Palette = QMetaType::QPalette,
0197 Image = QMetaType::QImage,
0198 Polygon = QMetaType::QPolygon,
0199 Region = QMetaType::QRegion,
0200 Bitmap = QMetaType::QBitmap,
0201 Cursor = QMetaType::QCursor,
0202 #if QT_CONFIG(shortcut)
0203 KeySequence = QMetaType::QKeySequence,
0204 #endif
0205 Pen = QMetaType::QPen,
0206 TextLength = QMetaType::QTextLength,
0207 TextFormat = QMetaType::QTextFormat,
0208 Transform = QMetaType::QTransform,
0209 Matrix4x4 = QMetaType::QMatrix4x4,
0210 Vector2D = QMetaType::QVector2D,
0211 Vector3D = QMetaType::QVector3D,
0212 Vector4D = QMetaType::QVector4D,
0213 Quaternion = QMetaType::QQuaternion,
0214 PolygonF = QMetaType::QPolygonF,
0215 Icon = QMetaType::QIcon,
0216 LastGuiType = QMetaType::LastGuiType,
0217
0218 SizePolicy = QMetaType::QSizePolicy,
0219
0220 UserType = QMetaType::User,
0221 LastType = 0xffffffff
0222 };
0223 #endif
0224 QVariant() noexcept : d() {}
0225 ~QVariant();
0226 explicit QVariant(QMetaType type, const void *copy = nullptr);
0227 QVariant(const QVariant &other);
0228
0229 private:
0230 template <typename T, typename ...Args>
0231 using is_noexcept_constructible = std::conjunction<
0232 std::bool_constant<Private::CanUseInternalSpace<T>>,
0233 std::is_nothrow_constructible<T, Args...>
0234 >;
0235
0236 public:
0237 template<typename Indirect>
0238 class Reference;
0239
0240 template<typename Indirect>
0241 class ConstReference
0242 {
0243 private:
0244 friend class Reference<Indirect>;
0245 const Indirect m_referred;
0246
0247 public:
0248
0249
0250 explicit ConstReference(const Indirect &referred)
0251 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
0252 : m_referred(referred) {}
0253 explicit ConstReference(Indirect &&referred)
0254 noexcept(std::is_nothrow_move_constructible_v<Indirect>)
0255 : m_referred(std::move(referred)) {}
0256 ConstReference(const ConstReference &)
0257 noexcept(std::is_nothrow_copy_constructible_v<Indirect>) = default;
0258
0259
0260
0261
0262
0263 ConstReference(ConstReference &&) = delete;
0264
0265 ConstReference(const Reference<Indirect> &)
0266 noexcept(std::is_nothrow_copy_constructible_v<Indirect>);
0267
0268
0269
0270
0271
0272
0273
0274 ~ConstReference() = default;
0275 ConstReference &operator=(const ConstReference &value) = delete;
0276 ConstReference &operator=(ConstReference &&value) = delete;
0277
0278
0279 operator QVariant() const noexcept(Indirect::CanNoexceptConvertToQVariant);
0280 };
0281
0282 template<typename Indirect>
0283 class Reference
0284 {
0285 private:
0286 friend class ConstReference<Indirect>;
0287 Indirect m_referred;
0288
0289 friend void swap(Reference a, Reference b) { return a.swap(b); }
0290
0291 public:
0292
0293
0294 explicit Reference(const Indirect &referred)
0295 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
0296 : m_referred(referred) {}
0297 explicit Reference(Indirect &&referred)
0298 noexcept(std::is_nothrow_move_constructible_v<Indirect>)
0299 : m_referred(std::move(referred)) {}
0300 Reference(const Reference &) = default;
0301
0302
0303
0304
0305
0306 Reference(Reference &&) = delete;
0307
0308 ~Reference() = default;
0309
0310 Reference &operator=(const Reference &value)
0311 noexcept(Indirect::CanNoexceptAssignQVariant)
0312 {
0313 return operator=(QVariant(value));
0314 }
0315
0316 Reference &operator=(Reference &&value)
0317 noexcept(Indirect::CanNoexceptAssignQVariant)
0318 {
0319 return operator=(QVariant(value));
0320 }
0321
0322 Reference &operator=(const ConstReference<Indirect> &value)
0323 noexcept(Indirect::CanNoexceptAssignQVariant)
0324 {
0325 return operator=(QVariant(value));
0326 }
0327
0328 Reference &operator=(ConstReference<Indirect> &&value)
0329 noexcept(Indirect::CanNoexceptAssignQVariant)
0330 {
0331 return operator=(QVariant(value));
0332 }
0333
0334 operator QVariant() const noexcept(Indirect::CanNoexceptConvertToQVariant)
0335 {
0336 return ConstReference(m_referred);
0337 }
0338
0339 void swap(Reference b)
0340 {
0341
0342 QVariant tmp = *this;
0343 *this = std::move(b);
0344 b = std::move(tmp);
0345 }
0346
0347
0348 Reference &operator=(const QVariant &value) noexcept(Indirect::CanNoexceptAssignQVariant);
0349 };
0350
0351 template<typename Indirect>
0352 class ConstPointer
0353 {
0354 private:
0355 Indirect m_pointed;
0356
0357 public:
0358 explicit ConstPointer(const Indirect &pointed)
0359 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
0360 : m_pointed(pointed) {}
0361 explicit ConstPointer(Indirect &&pointed)
0362 noexcept(std::is_nothrow_move_constructible_v<Indirect>)
0363 : m_pointed(std::move(pointed)) {}
0364
0365 ConstReference<Indirect> operator*()
0366 const noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
0367 {
0368 return ConstReference<Indirect>(m_pointed);
0369 }
0370 };
0371
0372 template<typename Indirect>
0373 class Pointer
0374 {
0375 private:
0376 Indirect m_pointed;
0377
0378 public:
0379 explicit Pointer(const Indirect &pointed)
0380 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
0381 : m_pointed(pointed) {}
0382 explicit Pointer(Indirect &&pointed)
0383 noexcept(std::is_nothrow_move_constructible_v<Indirect>)
0384 : m_pointed(std::move(pointed)) {}
0385
0386 Reference<Indirect> operator*()
0387 const noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
0388 {
0389 return Reference<Indirect>(m_pointed);
0390 }
0391
0392 operator ConstPointer<Indirect>() const
0393 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
0394 {
0395 return ConstPointer(m_pointed);
0396 }
0397 };
0398
0399 template <typename T, typename... Args,
0400 if_constructible<T, Args...> = true>
0401 explicit QVariant(std::in_place_type_t<T>, Args&&... args)
0402 noexcept(is_noexcept_constructible<q20::remove_cvref_t<T>, Args...>::value)
0403 : QVariant(std::in_place, QMetaType::fromType<q20::remove_cvref_t<T>>() )
0404 {
0405 void *data = const_cast<void *>(constData());
0406 new (data) T(std::forward<Args>(args)...);
0407 }
0408
0409 template <typename T, typename U, typename... Args,
0410 if_constructible<T, std::initializer_list<U> &, Args...> = true>
0411 explicit QVariant(std::in_place_type_t<T>, std::initializer_list<U> il, Args&&... args)
0412 noexcept(is_noexcept_constructible<q20::remove_cvref_t<T>,
0413 std::initializer_list<U> &,
0414 Args...
0415 >::value)
0416 : QVariant(std::in_place, QMetaType::fromType<q20::remove_cvref_t<T>>())
0417 {
0418 void *data = const_cast<void *>(constData());
0419 new (data) T(il, std::forward<Args>(args)...);
0420 }
0421
0422
0423 QVariant(int i) noexcept;
0424 QVariant(uint ui) noexcept;
0425 QVariant(qlonglong ll) noexcept;
0426 QVariant(qulonglong ull) noexcept;
0427 QVariant(bool b) noexcept;
0428 QVariant(double d) noexcept;
0429 QVariant(float f) noexcept;
0430
0431
0432 QVariant(QChar qchar) noexcept;
0433 QVariant(QDate date) noexcept;
0434 QVariant(QTime time) noexcept;
0435 QVariant(const QBitArray &bitarray) noexcept;
0436 QVariant(const QByteArray &bytearray) noexcept;
0437 QVariant(const QDateTime &datetime) noexcept;
0438 QVariant(const QHash<QString, QVariant> &hash) noexcept;
0439 QVariant(const QJsonArray &jsonArray) noexcept;
0440 QVariant(const QJsonObject &jsonObject) noexcept;
0441 QVariant(const QList<QVariant> &list) noexcept;
0442 QVariant(const QLocale &locale) noexcept;
0443 QVariant(const QMap<QString, QVariant> &map) noexcept;
0444 QVariant(const QRegularExpression &re) noexcept;
0445 QVariant(const QString &string) noexcept;
0446 QVariant(const QStringList &stringlist) noexcept;
0447 QVariant(const QUrl &url) noexcept;
0448
0449
0450
0451 QVariant(const QJsonValue &jsonValue) noexcept(Private::FitsInInternalSize<sizeof(CborValueStandIn)>);
0452 QVariant(const QModelIndex &modelIndex) noexcept(Private::FitsInInternalSize<8 + 2 * sizeof(quintptr)>);
0453 QVariant(QUuid uuid) noexcept(Private::FitsInInternalSize<16>);
0454 QVariant(QSize size) noexcept;
0455 QVariant(QSizeF size) noexcept(Private::FitsInInternalSize<sizeof(qreal) * 2>);
0456 QVariant(QPoint pt) noexcept;
0457 QVariant(QPointF pt) noexcept(Private::FitsInInternalSize<sizeof(qreal) * 2>);
0458 QVariant(QLine line) noexcept(Private::FitsInInternalSize<sizeof(int) * 4>);
0459 QVariant(QLineF line) noexcept(Private::FitsInInternalSize<sizeof(qreal) * 4>);
0460 QVariant(QRect rect) noexcept(Private::FitsInInternalSize<sizeof(int) * 4>);
0461 QVariant(QRectF rect) noexcept(Private::FitsInInternalSize<sizeof(qreal) * 4>);
0462
0463
0464 QVariant(const QEasingCurve &easing) noexcept(false);
0465 QVariant(const QJsonDocument &jsonDocument) noexcept(false);
0466 QVariant(const QPersistentModelIndex &modelIndex) noexcept(false);
0467
0468 #ifndef QT_NO_CAST_FROM_ASCII
0469 QT_ASCII_CAST_WARN QVariant(const char *str) noexcept(false)
0470 : QVariant(QString::fromUtf8(str))
0471 {}
0472 #endif
0473 QVariant(QLatin1StringView string) noexcept(false);
0474
0475 #if !defined(Q_CC_GHS)
0476
0477 template <typename T,
0478 std::enable_if_t<std::disjunction_v<std::is_pointer<T>, std::is_member_pointer<T>>, bool> = false>
0479 QVariant(T) = delete;
0480 #else
0481 QVariant(const volatile void *) = delete;
0482 #endif
0483
0484 #if QT_CORE_REMOVED_SINCE(6, 5)
0485 QVariant(const QSize &size);
0486 QVariant(const QSizeF &size);
0487 QVariant(const QPoint &pt);
0488 QVariant(const QPointF &pt);
0489 QVariant(const QLine &line);
0490 QVariant(const QLineF &line);
0491 QVariant(const QRect &rect);
0492 QVariant(const QRectF &rect);
0493 QVariant(const QUuid &uuid);
0494 #endif
0495
0496 QVariant& operator=(const QVariant &other);
0497 inline QVariant(QVariant &&other) noexcept : d(other.d)
0498 { other.d = Private(); }
0499 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QVariant)
0500
0501 inline void swap(QVariant &other) noexcept { std::swap(d, other.d); }
0502
0503 int userType() const { return typeId(); }
0504 int typeId() const
0505 {
0506
0507 const QtPrivate::QMetaTypeInterface *mt = metaType().iface();
0508 if (!mt)
0509 return 0;
0510 int id = mt->typeId.loadRelaxed();
0511 Q_PRESUME(id > 0);
0512 return id;
0513 }
0514
0515 QT_CORE_INLINE_SINCE(6, 10)
0516 const char *typeName() const;
0517 QT_CORE_INLINE_SINCE(6, 10)
0518 QMetaType metaType() const;
0519
0520 bool canConvert(QMetaType targetType) const
0521 { return QMetaType::canConvert(d.type(), targetType); }
0522 bool convert(QMetaType type);
0523
0524 bool canView(QMetaType targetType) const
0525 { return QMetaType::canView(d.type(), targetType); }
0526
0527 #if QT_DEPRECATED_SINCE(6, 0)
0528 QT_DEPRECATED_VERSION_6_0
0529 bool canConvert(int targetTypeId) const
0530 { return QMetaType::canConvert(d.type(), QMetaType(targetTypeId)); }
0531 QT_DEPRECATED_VERSION_6_0
0532 bool convert(int targetTypeId)
0533 { return convert(QMetaType(targetTypeId)); }
0534 #endif
0535
0536 inline bool isValid() const;
0537 bool isNull() const;
0538
0539 void clear();
0540
0541 void detach();
0542 inline bool isDetached() const;
0543
0544 int toInt(bool *ok = nullptr) const;
0545 uint toUInt(bool *ok = nullptr) const;
0546 qlonglong toLongLong(bool *ok = nullptr) const;
0547 qulonglong toULongLong(bool *ok = nullptr) const;
0548 bool toBool() const;
0549 double toDouble(bool *ok = nullptr) const;
0550 float toFloat(bool *ok = nullptr) const;
0551 qreal toReal(bool *ok = nullptr) const;
0552 QByteArray toByteArray() const;
0553 QBitArray toBitArray() const;
0554 QString toString() const;
0555 QStringList toStringList() const;
0556 QChar toChar() const;
0557 QDate toDate() const;
0558 QTime toTime() const;
0559 QDateTime toDateTime() const;
0560 QList<QVariant> toList() const;
0561 QMap<QString, QVariant> toMap() const;
0562 QHash<QString, QVariant> toHash() const;
0563
0564 QPoint toPoint() const;
0565 QPointF toPointF() const;
0566 QRect toRect() const;
0567 QSize toSize() const;
0568 QSizeF toSizeF() const;
0569 QLine toLine() const;
0570 QLineF toLineF() const;
0571 QRectF toRectF() const;
0572 QLocale toLocale() const;
0573 #if QT_CONFIG(regularexpression)
0574 QRegularExpression toRegularExpression() const;
0575 #endif
0576 #if QT_CONFIG(easingcurve)
0577 QEasingCurve toEasingCurve() const;
0578 #endif
0579 QUuid toUuid() const;
0580 QUrl toUrl() const;
0581 QJsonValue toJsonValue() const;
0582 QJsonObject toJsonObject() const;
0583 QJsonArray toJsonArray() const;
0584 QJsonDocument toJsonDocument() const;
0585 #if QT_CONFIG(itemmodel)
0586 QModelIndex toModelIndex() const;
0587 QPersistentModelIndex toPersistentModelIndex() const;
0588 #endif
0589
0590 #ifndef QT_NO_DATASTREAM
0591 void load(QDataStream &ds);
0592 void save(QDataStream &ds) const;
0593 #endif
0594 #if QT_DEPRECATED_SINCE(6, 0)
0595 QT_WARNING_PUSH
0596 QT_WARNING_DISABLE_DEPRECATED
0597 QT_DEPRECATED_VERSION_X_6_0("Use the constructor taking a QMetaType instead.")
0598 explicit QVariant(Type type)
0599 : QVariant(QMetaType(int(type)))
0600 {}
0601 QT_DEPRECATED_VERSION_X_6_0("Use typeId() or metaType().")
0602 Type type() const
0603 {
0604 int type = d.type().id();
0605 return type >= QMetaType::User ? UserType : static_cast<Type>(type);
0606 }
0607 QT_DEPRECATED_VERSION_6_0
0608 static const char *typeToName(int typeId)
0609 { return QMetaType(typeId).name(); }
0610 QT_DEPRECATED_VERSION_6_0
0611 static Type nameToType(const char *name)
0612 {
0613 int metaType = QMetaType::fromName(name).id();
0614 return metaType <= int(UserType) ? QVariant::Type(metaType) : UserType;
0615 }
0616 QT_WARNING_POP
0617 #endif
0618
0619 void *data();
0620 const void *constData() const
0621 { return d.storage(); }
0622 inline const void *data() const { return constData(); }
0623
0624 private:
0625 template <typename T>
0626 void verifySuitableForEmplace()
0627 {
0628 static_assert(!std::is_reference_v<T>,
0629 "QVariant does not support reference types");
0630 static_assert(!std::is_const_v<T>,
0631 "QVariant does not support const types");
0632 static_assert(std::is_copy_constructible_v<T>,
0633 "QVariant requires that the type is copyable");
0634 static_assert(std::is_destructible_v<T>,
0635 "QVariant requires that the type is destructible");
0636 }
0637
0638 template <typename T, typename... Args>
0639 T &emplaceImpl(Args&&... args)
0640 {
0641 verifySuitableForEmplace<T>();
0642 auto data = static_cast<T *>(prepareForEmplace(QMetaType::fromType<T>()));
0643 return *q20::construct_at(data, std::forward<Args>(args)...);
0644 }
0645
0646 public:
0647 template <typename T, typename... Args,
0648 if_constructible<T, Args...> = true>
0649 T &emplace(Args&&... args)
0650 {
0651 return emplaceImpl<T>(std::forward<Args>(args)...);
0652 }
0653
0654 template <typename T, typename U, typename... Args,
0655 if_constructible<T, std::initializer_list<U> &, Args...> = true>
0656 T &emplace(std::initializer_list<U> list, Args&&... args)
0657 {
0658 return emplaceImpl<T>(list, std::forward<Args>(args)...);
0659 }
0660
0661 template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, QVariant>>>
0662 void setValue(T &&avalue)
0663 {
0664 using VT = std::decay_t<T>;
0665 QMetaType metaType = QMetaType::fromType<VT>();
0666
0667 if (isDetached() && d.type() == metaType) {
0668 *reinterpret_cast<VT *>(const_cast<void *>(constData())) = std::forward<T>(avalue);
0669 d.is_null = false;
0670 } else {
0671 *this = QVariant::fromValue<VT>(std::forward<T>(avalue));
0672 }
0673 }
0674
0675 void setValue(const QVariant &avalue)
0676 {
0677 *this = avalue;
0678 }
0679
0680 void setValue(QVariant &&avalue)
0681 {
0682 *this = std::move(avalue);
0683 }
0684
0685 template<typename T>
0686 inline T value() const &
0687 { return qvariant_cast<T>(*this); }
0688
0689 template<typename T>
0690 inline T view()
0691 {
0692 T t{};
0693 QMetaType::view(metaType(), data(), QMetaType::fromType<T>(), &t);
0694 return t;
0695 }
0696
0697 template<typename T>
0698 inline T value() &&
0699 { return qvariant_cast<T>(std::move(*this)); }
0700
0701 template<typename T, if_rvalue<T> = true>
0702 #ifndef Q_QDOC
0703
0704
0705
0706 static inline auto fromValue(T &&value)
0707 noexcept(std::is_nothrow_copy_constructible_v<T> && Private::CanUseInternalSpace<T>)
0708 -> std::enable_if_t<std::conjunction_v<std::is_copy_constructible<T>,
0709 std::is_destructible<T>>, QVariant>
0710 #else
0711 static inline QVariant fromValue(T &&value)
0712 #endif
0713 {
0714
0715 using Type = std::remove_cv_t<T>;
0716 if constexpr (std::is_null_pointer_v<Type>)
0717 return QVariant::fromMetaType(QMetaType::fromType<std::nullptr_t>());
0718 else if constexpr (std::is_same_v<Type, QVariant>)
0719 return std::forward<T>(value);
0720 else if constexpr (std::is_same_v<Type, std::monostate>)
0721 return QVariant();
0722 QMetaType mt = QMetaType::fromType<Type>();
0723 mt.registerType();
0724
0725
0726
0727 if constexpr (std::conjunction_v<std::is_move_constructible<Type>, std::negation<std::is_const<T>>>)
0728 return moveConstruct(QMetaType::fromType<Type>(), std::addressof(value));
0729 else
0730 return copyConstruct(mt, std::addressof(value));
0731 }
0732
0733 template<typename T>
0734 #ifndef Q_QDOC
0735 static inline auto fromValue(const T &value)
0736 noexcept(std::is_nothrow_copy_constructible_v<T> && Private::CanUseInternalSpace<T>)
0737 -> std::enable_if_t<std::is_copy_constructible_v<T> && std::is_destructible_v<T>, QVariant>
0738 #else
0739 static inline QVariant fromValue(const T &value)
0740 #endif
0741 {
0742 if constexpr (std::is_null_pointer_v<T>)
0743 return QVariant(QMetaType::fromType<std::nullptr_t>());
0744 else if constexpr (std::is_same_v<T, QVariant>)
0745 return value;
0746 else if constexpr (std::is_same_v<T, std::monostate>)
0747 return QVariant();
0748 return QVariant(QMetaType::fromType<T>(), std::addressof(value));
0749 }
0750
0751 template<typename... Types>
0752 static inline QVariant fromStdVariant(const std::variant<Types...> &value)
0753 {
0754 return fromStdVariantImpl(value);
0755 }
0756
0757 template<typename... Types>
0758 static QVariant fromStdVariant(std::variant<Types...> &&value)
0759 {
0760 return fromStdVariantImpl(std::move(value));
0761 }
0762
0763 static QVariant fromMetaType(QMetaType type, const void *copy = nullptr);
0764
0765 template<typename T>
0766 bool canConvert() const
0767 { return canConvert(QMetaType::fromType<T>()); }
0768
0769 template<typename T>
0770 bool canView() const
0771 { return canView(QMetaType::fromType<T>()); }
0772
0773 static QPartialOrdering compare(const QVariant &lhs, const QVariant &rhs);
0774
0775 private:
0776 template <typename StdVariant>
0777 static QVariant fromStdVariantImpl(StdVariant &&v)
0778 {
0779 if (Q_UNLIKELY(v.valueless_by_exception()))
0780 return QVariant();
0781 auto visitor = [](auto &&arg) {
0782 return QVariant::fromValue(q23::forward_like<StdVariant>(arg));
0783 };
0784 return std::visit(visitor, std::forward<StdVariant>(v));
0785 }
0786
0787 friend bool comparesEqual(const QVariant &a, const QVariant &b)
0788 { return a.equals(b); }
0789 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QVariant)
0790
0791 #ifndef QT_NO_DEBUG_STREAM
0792 template <typename T>
0793 friend auto operator<<(const QDebug &debug, const T &variant) -> std::enable_if_t<std::is_same_v<T, QVariant>, QDebug> {
0794 return variant.qdebugHelper(debug);
0795 }
0796 QDebug qdebugHelper(QDebug) const;
0797 #endif
0798
0799 template <typename T, typename Variant> static constexpr
0800 bool canGetTypeFromVariant(Variant *v) noexcept
0801 {
0802 if (!v)
0803 return false;
0804 if (std::is_const_v<Variant> && v->d.is_null)
0805 return false;
0806 return v->d.type() == QMetaType::fromType<T>();
0807 }
0808
0809 template <typename T> T *typedData()
0810 {
0811 Q_PRE(canGetTypeFromVariant<T>(this));
0812 return static_cast<T *>(data());
0813 }
0814
0815 template <typename T> const T *typedData() const
0816 {
0817 Q_PRE(canGetTypeFromVariant<T>(this));
0818 return &d.get<T>();
0819 }
0820
0821 template <typename T>
0822 friend T *get_if(QVariant *v) noexcept
0823 {
0824 if (!canGetTypeFromVariant<T>(v))
0825 return nullptr;
0826 return v->typedData<T>();
0827 }
0828 template <typename T>
0829 friend const T *get_if(const QVariant *v) noexcept
0830 {
0831 if (!canGetTypeFromVariant<T>(v))
0832 return nullptr;
0833 return v->typedData<const T>();
0834 }
0835
0836 #define Q_MK_GET(CONST, REF) \
0837 template <typename T> friend CONST T REF get(CONST QVariant REF v) \
0838 { return static_cast<CONST T REF>(*v.typedData<T>()); } \
0839
0840 Q_MK_GET(, &)
0841 Q_MK_GET(const, &)
0842 Q_MK_GET(, &&)
0843 Q_MK_GET(const, &&)
0844 #undef Q_MK_GET
0845
0846 static QVariant moveConstruct(QMetaType type, void *data);
0847 static QVariant copyConstruct(QMetaType type, const void *data);
0848
0849 template<typename T>
0850 friend inline T qvariant_cast(const QVariant &);
0851 template<typename T>
0852 friend inline T qvariant_cast(QVariant &&);
0853
0854 protected:
0855 Private d;
0856 void create(int type, const void *copy);
0857 void create(QMetaType type, const void *copy);
0858 bool equals(const QVariant &other) const;
0859 bool convert(int type, void *ptr) const;
0860 bool view(int type, void *ptr);
0861
0862 private:
0863
0864 inline QVariant(void *) = delete;
0865
0866
0867
0868
0869
0870
0871 QVariant(QMetaType::Type) = delete;
0872
0873
0874 QVariant(std::in_place_t, QMetaType type);
0875
0876 void *prepareForEmplace(QMetaType type);
0877
0878
0879
0880
0881
0882
0883 QVariant(Qt::GlobalColor) = delete;
0884 QVariant(Qt::BrushStyle) = delete;
0885 QVariant(Qt::PenStyle) = delete;
0886 QVariant(Qt::CursorShape) = delete;
0887 #ifdef QT_NO_CAST_FROM_ASCII
0888
0889 inline QVariant(const char *) = delete;
0890 #endif
0891 public:
0892 typedef Private DataPtr;
0893 inline DataPtr &data_ptr() { return d; }
0894 inline const DataPtr &data_ptr() const { return d; }
0895 };
0896
0897 inline bool QVariant::isValid() const
0898 {
0899 return d.type().isValid(QT6_CALL_NEW_OVERLOAD);
0900 }
0901
0902 #ifndef QT_NO_DATASTREAM
0903 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &s, QVariant &p);
0904 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &s, const QVariant &p);
0905
0906 #if QT_DEPRECATED_SINCE(6, 0)
0907 QT_WARNING_PUSH
0908 QT_WARNING_DISABLE_DEPRECATED
0909 QT_DEPRECATED_VERSION_6_0
0910 inline QDataStream &operator>>(QDataStream &s, QVariant::Type &p)
0911 {
0912 quint32 u;
0913 s >> u;
0914 p = static_cast<QVariant::Type>(u);
0915 return s;
0916 }
0917 QT_DEPRECATED_VERSION_6_0
0918 inline QDataStream &operator<<(QDataStream &s, const QVariant::Type p)
0919 {
0920 s << static_cast<quint32>(p);
0921 return s;
0922 }
0923 QT_WARNING_POP
0924 #endif
0925
0926 #endif
0927
0928 #if QT_CORE_INLINE_IMPL_SINCE(6, 10)
0929 QMetaType QVariant::metaType() const
0930 {
0931 return d.type();
0932 }
0933
0934 const char *QVariant::typeName() const
0935 {
0936 return d.type().name();
0937 }
0938 #endif
0939
0940 inline bool QVariant::isDetached() const
0941 { return !d.is_shared || d.data.shared->ref.loadRelaxed() == 1; }
0942
0943 inline void swap(QVariant &value1, QVariant &value2) noexcept
0944 { value1.swap(value2); }
0945
0946 template<typename Indirect>
0947 inline QVariant::ConstReference<Indirect>::ConstReference(const Reference<Indirect> &nonConst)
0948 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
0949 : ConstReference(nonConst.m_referred)
0950 {
0951 }
0952
0953 #ifndef QT_MOC
0954
0955 namespace QtPrivate {
0956 template<typename T> inline T qvariant_cast_qmetatype_converted(const QVariant &v, QMetaType targetType)
0957 {
0958 T t{};
0959 QMetaType::convert(v.metaType(), v.constData(), targetType, &t);
0960 return t;
0961 }
0962 }
0963
0964 template<typename T> inline T qvariant_cast(const QVariant &v)
0965 {
0966 QMetaType targetType = QMetaType::fromType<T>();
0967 if (v.d.type() == targetType)
0968 return v.d.get<T>();
0969 if constexpr (std::is_same_v<T,std::remove_const_t<std::remove_pointer_t<T>> const *>) {
0970 using nonConstT = std::remove_const_t<std::remove_pointer_t<T>> *;
0971 QMetaType nonConstTargetType = QMetaType::fromType<nonConstT>();
0972 if (v.d.type() == nonConstTargetType)
0973 return v.d.get<nonConstT>();
0974 }
0975
0976 return QtPrivate::qvariant_cast_qmetatype_converted<T>(v, targetType);
0977 }
0978
0979 template<typename T> inline T qvariant_cast(QVariant &&v)
0980 {
0981 QMetaType targetType = QMetaType::fromType<T>();
0982 if (v.d.type() == targetType) {
0983 if constexpr (QVariant::Private::FitsInInternalSize<sizeof(T)>) {
0984
0985
0986
0987 if (!v.d.is_shared)
0988 return std::move(*reinterpret_cast<T *>(v.d.data.data));
0989 }
0990
0991 Q_ASSERT(v.d.is_shared);
0992 if (v.d.data.shared->ref.loadRelaxed() == 1)
0993 return std::move(*reinterpret_cast<T *>(v.d.data.shared->data()));
0994 else
0995 return v.d.get<T>();
0996 }
0997 if constexpr (std::is_same_v<T, QVariant>) {
0998
0999 return v;
1000 } if constexpr (std::is_same_v<T,std::remove_const_t<std::remove_pointer_t<T>> const *>) {
1001
1002 using nonConstT = std::remove_const_t<std::remove_pointer_t<T>> *;
1003 QMetaType nonConstTargetType = QMetaType::fromType<nonConstT>();
1004 if (v.d.type() == nonConstTargetType)
1005 return v.d.get<nonConstT>();
1006 }
1007
1008 return QtPrivate::qvariant_cast_qmetatype_converted<T>(v, targetType);
1009 }
1010
1011 # ifndef QT_NO_VARIANT
1012 template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
1013 {
1014 if (v.metaType().id() == QMetaType::QVariant)
1015 return *reinterpret_cast<const QVariant *>(v.constData());
1016 return v;
1017 }
1018 # endif
1019
1020 #endif
1021
1022 #ifndef QT_NO_DEBUG_STREAM
1023 #if QT_DEPRECATED_SINCE(6, 0)
1024 QT_WARNING_PUSH
1025 QT_WARNING_DISABLE_DEPRECATED
1026 QT_DEPRECATED_VERSION_6_0
1027 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant::Type);
1028 QT_WARNING_POP
1029 #endif
1030 #endif
1031
1032 namespace QtPrivate {
1033 class Q_CORE_EXPORT QVariantTypeCoercer
1034 {
1035 public:
1036
1037 const void *convert(const QVariant &value, const QMetaType &type);
1038 const void *coerce(const QVariant &value, const QMetaType &type);
1039
1040 private:
1041 QVariant converted;
1042 };
1043 }
1044
1045 #if QT_DEPRECATED_SINCE(6, 15)
1046 QT_WARNING_PUSH
1047 QT_WARNING_DISABLE_DEPRECATED
1048
1049 template<typename Pointer> class
1050 QT_DEPRECATED_VERSION_X_6_15("Use QVariant::Reference instead.")
1051 QVariantRef
1052 {
1053 private:
1054 const Pointer *m_pointer = nullptr;
1055
1056 public:
1057 explicit QVariantRef(const Pointer *reference) : m_pointer(reference) {}
1058 QVariantRef(const QVariantRef &) = default;
1059 QVariantRef(QVariantRef &&) = default;
1060 ~QVariantRef() = default;
1061
1062 operator QVariant() const;
1063 QVariantRef &operator=(const QVariant &value);
1064 QVariantRef &operator=(const QVariantRef &value) { return operator=(QVariant(value)); }
1065 QVariantRef &operator=(QVariantRef &&value) { return operator=(QVariant(value)); }
1066
1067 friend void swap(QVariantRef a, QVariantRef b)
1068 {
1069 QVariant tmp = a;
1070 a = b;
1071 b = std::move(tmp);
1072 }
1073 };
1074
1075
1076 class Q_CORE_EXPORT QT_DEPRECATED_VERSION_X_6_15("Use QVariant::ConstPointer instead.") QVariantConstPointer
1077 {
1078 private:
1079 QVariant m_variant;
1080
1081 public:
1082 explicit QVariantConstPointer(QVariant variant);
1083
1084 QVariant operator*() const;
1085 const QVariant *operator->() const;
1086 };
1087
1088 template<typename Pointer> class
1089 QT_DEPRECATED_VERSION_X_6_15("Use QVariant::Pointer instead.")
1090 QVariantPointer
1091 {
1092 private:
1093 const Pointer *m_pointer = nullptr;
1094
1095 public:
1096 explicit QVariantPointer(const Pointer *pointer) : m_pointer(pointer) {}
1097 QVariantRef<Pointer> operator*() const { return QVariantRef<Pointer>(m_pointer); }
1098 Pointer operator->() const { return *m_pointer; }
1099 };
1100
1101 QT_WARNING_POP
1102 #endif
1103
1104 QT_END_NAMESPACE
1105
1106 #endif