66 template <
typename T,
typename... Args>
67 using if_constructible = std::enable_if_t<
69 std::is_copy_constructible<q20::remove_cvref_t<T>>,
70 std::is_destructible<q20::remove_cvref_t<T>>,
71 std::is_constructible<q20::remove_cvref_t<T>, Args...>
76 using if_rvalue = std::enable_if_t<!std::is_reference_v<T>,
bool>;
78 struct CborValueStandIn { qint64 n;
void *c;
int t; };
83 inline PrivateShared() : ref(1) { }
85 static int computeOffset(PrivateShared *ps, size_t align);
86 static size_t computeAllocationSize(size_t size, size_t align);
87 static PrivateShared *create(size_t size, size_t align);
88 static void free(PrivateShared *p);
90 alignas(8) QAtomicInt ref;
93 const void *data()
const {
return reinterpret_cast<
const uchar *>(
this) + offset; }
94 void *data() {
return reinterpret_cast<uchar *>(
this) + offset; }
99 static constexpr size_t MaxInternalSize = 3 *
sizeof(
void *);
100 template <size_t S>
static constexpr bool FitsInInternalSize = S <= MaxInternalSize;
101 template<
typename T>
static constexpr bool CanUseInternalSpace =
102 (QTypeInfo<T>::isRelocatable && FitsInInternalSize<
sizeof(T)> &&
alignof(T) <=
alignof(
double));
103 static constexpr bool canUseInternalSpace(
const QtPrivate::QMetaTypeInterface *type)
106 return QMetaType::TypeFlags(type->flags) & QMetaType::RelocatableType &&
107 size_t(type->size) <= MaxInternalSize && size_t(type->alignment) <=
alignof(
double);
112 uchar data[MaxInternalSize] = {};
113 PrivateShared *shared;
114 double _forAlignment;
116 quintptr is_shared : 1;
117 quintptr is_null : 1;
118 quintptr packedType :
sizeof(QMetaType) * 8 - 2;
120 constexpr Private()
noexcept : is_shared(
false), is_null(
true), packedType(0) {}
121 explicit Private(
const QtPrivate::QMetaTypeInterface *iface)
noexcept;
122 template <
typename T>
explicit Private(std::piecewise_construct_t,
const T &t);
124 const void *storage()
const
125 {
return is_shared ? data.shared->data() : &data.data; }
128 template<
typename T>
const T &get()
const
129 {
return *
static_cast<
const T *>(CanUseInternalSpace<T> ? &data.data : data.shared->data()); }
131 inline const QtPrivate::QMetaTypeInterface *typeInterface()
const
133 return reinterpret_cast<
const QtPrivate::QMetaTypeInterface *>(packedType << 2);
136 inline QMetaType type()
const
138 return QMetaType(typeInterface());
142#if QT_DEPRECATED_SINCE(6
, 0
)
143 enum QT_DEPRECATED_VERSION_X_6_0(
"Use QMetaType::Type instead.") Type
145 Invalid = QMetaType::UnknownType,
146 Bool = QMetaType::Bool,
147 Int = QMetaType::Int,
148 UInt = QMetaType::UInt,
149 LongLong = QMetaType::LongLong,
150 ULongLong = QMetaType::ULongLong,
151 Double = QMetaType::Double,
152 Char = QMetaType::QChar,
153 Map = QMetaType::QVariantMap,
154 List = QMetaType::QVariantList,
155 String = QMetaType::QString,
156 StringList = QMetaType::QStringList,
157 ByteArray = QMetaType::QByteArray,
158 BitArray = QMetaType::QBitArray,
159 Date = QMetaType::QDate,
160 Time = QMetaType::QTime,
161 DateTime = QMetaType::QDateTime,
162 Url = QMetaType::QUrl,
163 Locale = QMetaType::QLocale,
164 Rect = QMetaType::QRect,
165 RectF = QMetaType::QRectF,
166 Size = QMetaType::QSize,
167 SizeF = QMetaType::QSizeF,
168 Line = QMetaType::QLine,
169 LineF = QMetaType::QLineF,
170 Point = QMetaType::QPoint,
171 PointF = QMetaType::QPointF,
172#if QT_CONFIG(regularexpression)
173 RegularExpression = QMetaType::QRegularExpression,
175 Hash = QMetaType::QVariantHash,
176#if QT_CONFIG(easingcurve)
177 EasingCurve = QMetaType::QEasingCurve,
179 Uuid = QMetaType::QUuid,
180#if QT_CONFIG(itemmodel)
181 ModelIndex = QMetaType::QModelIndex,
182 PersistentModelIndex = QMetaType::QPersistentModelIndex,
184 LastCoreType = QMetaType::LastCoreType,
186 Font = QMetaType::QFont,
187 Pixmap = QMetaType::QPixmap,
188 Brush = QMetaType::QBrush,
189 Color = QMetaType::QColor,
190 Palette = QMetaType::QPalette,
191 Image = QMetaType::QImage,
192 Polygon = QMetaType::QPolygon,
193 Region = QMetaType::QRegion,
194 Bitmap = QMetaType::QBitmap,
195 Cursor = QMetaType::QCursor,
196#if QT_CONFIG(shortcut)
197 KeySequence = QMetaType::QKeySequence,
199 Pen = QMetaType::QPen,
200 TextLength = QMetaType::QTextLength,
201 TextFormat = QMetaType::QTextFormat,
202 Transform = QMetaType::QTransform,
203 Matrix4x4 = QMetaType::QMatrix4x4,
204 Vector2D = QMetaType::QVector2D,
205 Vector3D = QMetaType::QVector3D,
206 Vector4D = QMetaType::QVector4D,
207 Quaternion = QMetaType::QQuaternion,
208 PolygonF = QMetaType::QPolygonF,
209 Icon = QMetaType::QIcon,
210 LastGuiType = QMetaType::LastGuiType,
212 SizePolicy = QMetaType::QSizePolicy,
214 UserType = QMetaType::User,
215 LastType = 0xffffffff
218 QVariant()
noexcept : d() {}
220 explicit QVariant(QMetaType type,
const void *copy =
nullptr);
221 QVariant(
const QVariant &other);
224 template <
typename T,
typename ...Args>
225 using is_noexcept_constructible = std::conjunction<
226 std::bool_constant<Private::CanUseInternalSpace<T>>,
227 std::is_nothrow_constructible<T, Args...>
231 template <
typename T,
typename... Args,
232 if_constructible<T, Args...> =
true>
233 explicit QVariant(std::in_place_type_t<T>, Args&&... args)
234 noexcept(is_noexcept_constructible<q20::remove_cvref_t<T>, Args...>::value)
235 : QVariant(std::in_place, QMetaType::fromType<q20::remove_cvref_t<T>>() )
237 void *data =
const_cast<
void *>(constData());
238 new (data) T(std::forward<Args>(args)...);
241 template <
typename T,
typename U,
typename... Args,
242 if_constructible<T, std::initializer_list<U> &, Args...> =
true>
243 explicit QVariant(std::in_place_type_t<T>, std::initializer_list<U> il, Args&&... args)
244 noexcept(is_noexcept_constructible<q20::remove_cvref_t<T>,
245 std::initializer_list<U> &,
248 : QVariant(std::in_place, QMetaType::fromType<q20::remove_cvref_t<T>>())
250 char *data =
static_cast<
char *>(
const_cast<
void *>(constData()));
251 new (data) T(il, std::forward<Args>(args)...);
255 QVariant(
int i)
noexcept;
256 QVariant(uint ui)
noexcept;
257 QVariant(qlonglong ll)
noexcept;
258 QVariant(qulonglong ull)
noexcept;
259 QVariant(
bool b)
noexcept;
260 QVariant(
double d)
noexcept;
261 QVariant(
float f)
noexcept;
264 QVariant(QChar qchar)
noexcept;
265 QVariant(QDate date)
noexcept;
266 QVariant(QTime time)
noexcept;
267#ifndef QT_BOOTSTRAPPED
268 QVariant(
const QBitArray &bitarray)
noexcept;
270 QVariant(
const QByteArray &bytearray)
noexcept;
271 QVariant(
const QDateTime &datetime)
noexcept;
272 QVariant(
const QHash<QString, QVariant> &hash)
noexcept;
273 QVariant(
const QJsonArray &jsonArray)
noexcept;
274 QVariant(
const QJsonObject &jsonObject)
noexcept;
275 QVariant(
const QList<QVariant> &list)
noexcept;
276 QVariant(
const QLocale &locale)
noexcept;
277 QVariant(
const QMap<QString, QVariant> &map)
noexcept;
278 QVariant(
const QRegularExpression &re)
noexcept;
279 QVariant(
const QString &string)
noexcept;
280 QVariant(
const QStringList &stringlist)
noexcept;
281 QVariant(
const QUrl &url)
noexcept;
285 QVariant(
const QJsonValue &jsonValue)
noexcept(Private::FitsInInternalSize<
sizeof(CborValueStandIn)>);
286 QVariant(
const QModelIndex &modelIndex)
noexcept(Private::FitsInInternalSize<8 + 2 *
sizeof(quintptr)>);
287 QVariant(QUuid uuid)
noexcept(Private::FitsInInternalSize<16>);
288#ifndef QT_NO_GEOM_VARIANT
289 QVariant(QSize size)
noexcept;
290 QVariant(QSizeF size)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 2>);
291 QVariant(QPoint pt)
noexcept;
292 QVariant(QPointF pt)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 2>);
293 QVariant(QLine line)
noexcept(Private::FitsInInternalSize<
sizeof(
int) * 4>);
294 QVariant(QLineF line)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 4>);
295 QVariant(QRect rect)
noexcept(Private::FitsInInternalSize<
sizeof(
int) * 4>);
296 QVariant(QRectF rect)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 4>);
300 QVariant(
const QEasingCurve &easing)
noexcept(
false);
301 QVariant(
const QJsonDocument &jsonDocument)
noexcept(
false);
302 QVariant(
const QPersistentModelIndex &modelIndex)
noexcept(
false);
304#ifndef QT_NO_CAST_FROM_ASCII
305 QT_ASCII_CAST_WARN QVariant(
const char *str)
noexcept(
false)
306 : QVariant(QString::fromUtf8(str))
309 QVariant(QLatin1StringView string)
noexcept(
false);
311#if !defined(Q_CC_GHS)
313 template <
typename T,
314 std::enable_if_t<std::disjunction_v<std::is_pointer<T>, std::is_member_pointer<T>>,
bool> =
false>
315 QVariant(T) =
delete;
317 QVariant(
const volatile void *) =
delete;
320#if QT_CORE_REMOVED_SINCE(6
, 5
)
321 QVariant(
const QSize &size);
322 QVariant(
const QSizeF &size);
323 QVariant(
const QPoint &pt);
324 QVariant(
const QPointF &pt);
325 QVariant(
const QLine &line);
326 QVariant(
const QLineF &line);
327 QVariant(
const QRect &rect);
328 QVariant(
const QRectF &rect);
329 QVariant(
const QUuid &uuid);
332 QVariant& operator=(
const QVariant &other);
333 inline QVariant(QVariant &&other)
noexcept : d(other.d)
334 { other.d = Private(); }
335 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QVariant)
337 inline void swap(QVariant &other)
noexcept { std::swap(d, other.d); }
339 int userType()
const {
return typeId(); }
340 int typeId()
const {
return metaType().id(); }
342 const char *typeName()
const;
343 QMetaType metaType()
const;
345 bool canConvert(QMetaType targetType)
const
346 {
return QMetaType::canConvert(d.type(), targetType); }
347 bool convert(QMetaType type);
349 bool canView(QMetaType targetType)
const
350 {
return QMetaType::canView(d.type(), targetType); }
352#if QT_DEPRECATED_SINCE(6
, 0
)
353 QT_DEPRECATED_VERSION_6_0
354 bool canConvert(
int targetTypeId)
const
355 {
return QMetaType::canConvert(d.type(), QMetaType(targetTypeId)); }
356 QT_DEPRECATED_VERSION_6_0
357 bool convert(
int targetTypeId)
358 {
return convert(QMetaType(targetTypeId)); }
361 inline bool isValid()
const;
367 inline bool isDetached()
const;
369 int toInt(
bool *ok =
nullptr)
const;
370 uint toUInt(
bool *ok =
nullptr)
const;
371 qlonglong toLongLong(
bool *ok =
nullptr)
const;
372 qulonglong toULongLong(
bool *ok =
nullptr)
const;
374 double toDouble(
bool *ok =
nullptr)
const;
375 float toFloat(
bool *ok =
nullptr)
const;
376 qreal toReal(
bool *ok =
nullptr)
const;
377 QByteArray toByteArray()
const;
378#ifndef QT_BOOTSTRAPPED
379 QBitArray toBitArray()
const;
381 QString toString()
const;
382 QStringList toStringList()
const;
383 QChar toChar()
const;
384 QDate toDate()
const;
385 QTime toTime()
const;
386 QDateTime toDateTime()
const;
387 QList<QVariant> toList()
const;
388 QMap<QString, QVariant> toMap()
const;
389 QHash<QString, QVariant> toHash()
const;
391#ifndef QT_NO_GEOM_VARIANT
392 QPoint toPoint()
const;
393 QPointF toPointF()
const;
394 QRect toRect()
const;
395 QSize toSize()
const;
396 QSizeF toSizeF()
const;
397 QLine toLine()
const;
398 QLineF toLineF()
const;
399 QRectF toRectF()
const;
401 QLocale toLocale()
const;
402#if QT_CONFIG(regularexpression)
403 QRegularExpression toRegularExpression()
const;
405#if QT_CONFIG(easingcurve)
406 QEasingCurve toEasingCurve()
const;
408 QUuid toUuid()
const;
409#ifndef QT_BOOTSTRAPPED
411 QJsonValue toJsonValue()
const;
412 QJsonObject toJsonObject()
const;
413 QJsonArray toJsonArray()
const;
414 QJsonDocument toJsonDocument()
const;
416#if QT_CONFIG(itemmodel)
417 QModelIndex toModelIndex()
const;
418 QPersistentModelIndex toPersistentModelIndex()
const;
421#ifndef QT_NO_DATASTREAM
422 void load(QDataStream &ds);
423 void save(QDataStream &ds)
const;
425#if QT_DEPRECATED_SINCE(6
, 0
)
427 QT_WARNING_DISABLE_DEPRECATED
428 QT_DEPRECATED_VERSION_X_6_0(
"Use the constructor taking a QMetaType instead.")
429 explicit QVariant(Type type)
430 : QVariant(QMetaType(
int(type)))
432 QT_DEPRECATED_VERSION_X_6_0(
"Use typeId() or metaType().")
435 int type = d.type().id();
436 return type >= QMetaType::User ? UserType :
static_cast<Type>(type);
438 QT_DEPRECATED_VERSION_6_0
439 static const char *typeToName(
int typeId)
440 {
return QMetaType(typeId).name(); }
441 QT_DEPRECATED_VERSION_6_0
442 static Type nameToType(
const char *name)
444 int metaType = QMetaType::fromName(name).id();
445 return metaType <=
int(UserType) ? QVariant::Type(metaType) : UserType;
451 const void *constData()
const
452 {
return d.storage(); }
453 inline const void *data()
const {
return constData(); }
456 template <
typename T>
457 void verifySuitableForEmplace()
459 static_assert(!std::is_reference_v<T>,
460 "QVariant does not support reference types");
461 static_assert(!std::is_const_v<T>,
462 "QVariant does not support const types");
463 static_assert(std::is_copy_constructible_v<T>,
464 "QVariant requires that the type is copyable");
465 static_assert(std::is_destructible_v<T>,
466 "QVariant requires that the type is destructible");
469 template <
typename T,
typename... Args>
470 T &emplaceImpl(Args&&... args)
472 verifySuitableForEmplace<T>();
473 auto data =
static_cast<T *>(prepareForEmplace(QMetaType::fromType<T>()));
474 return *q20::construct_at(data, std::forward<Args>(args)...);
478 template <
typename T,
typename... Args,
479 if_constructible<T, Args...> =
true>
480 T &emplace(Args&&... args)
482 return emplaceImpl<T>(std::forward<Args>(args)...);
485 template <
typename T,
typename U,
typename... Args,
486 if_constructible<T, std::initializer_list<U> &, Args...> =
true>
487 T &emplace(std::initializer_list<U> list, Args&&... args)
489 return emplaceImpl<T>(list, std::forward<Args>(args)...);
492 template<
typename T,
typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, QVariant>>>
493 void setValue(T &&avalue)
495 using VT = std::decay_t<T>;
496 QMetaType metaType = QMetaType::fromType<VT>();
498 if (isDetached() && d.type() == metaType) {
499 *
reinterpret_cast<VT *>(
const_cast<
void *>(constData())) = std::forward<T>(avalue);
502 *
this = QVariant::fromValue<VT>(std::forward<T>(avalue));
506 void setValue(
const QVariant &avalue)
511 void setValue(QVariant &&avalue)
513 *
this = std::move(avalue);
517 inline T value()
const &
518 {
return qvariant_cast<T>(*
this); }
524 QMetaType::view(metaType(), data(), QMetaType::fromType<T>(), &t);
530 {
return qvariant_cast<T>(std::move(*
this)); }
532 template<
typename T, if_rvalue<T> =
true>
535
536
537 static inline auto fromValue(T &&value)
538 noexcept(std::is_nothrow_copy_constructible_v<T> && Private::CanUseInternalSpace<T>)
539 -> std::enable_if_t<std::conjunction_v<std::is_copy_constructible<T>,
540 std::is_destructible<T>>, QVariant>
542 static inline QVariant fromValue(T &&value)
546 using Type = std::remove_cv_t<T>;
547 if constexpr (std::is_null_pointer_v<Type>)
548 return QVariant::fromMetaType(QMetaType::fromType<std::nullptr_t>());
549 else if constexpr (std::is_same_v<Type, QVariant>)
550 return std::forward<T>(value);
551 else if constexpr (std::is_same_v<Type, std::monostate>)
553 QMetaType mt = QMetaType::fromType<Type>();
558 if constexpr (std::conjunction_v<std::is_move_constructible<Type>, std::negation<std::is_const<T>>>)
559 return moveConstruct(QMetaType::fromType<Type>(), std::addressof(value));
561 return copyConstruct(mt, std::addressof(value));
566 static inline auto fromValue(
const T &value)
567 noexcept(std::is_nothrow_copy_constructible_v<T> && Private::CanUseInternalSpace<T>)
568 -> std::enable_if_t<std::is_copy_constructible_v<T> && std::is_destructible_v<T>, QVariant>
570 static inline QVariant fromValue(
const T &value)
573 if constexpr (std::is_null_pointer_v<T>)
574 return QVariant(QMetaType::fromType<std::nullptr_t>());
575 else if constexpr (std::is_same_v<T, QVariant>)
577 else if constexpr (std::is_same_v<T, std::monostate>)
579 return QVariant(QMetaType::fromType<T>(), std::addressof(value));
582 template<
typename... Types>
583 static inline QVariant fromStdVariant(
const std::variant<Types...> &value)
585 return fromStdVariantImpl(value);
588 template<
typename... Types>
589 static QVariant fromStdVariant(std::variant<Types...> &&value)
591 return fromStdVariantImpl(std::move(value));
594 static QVariant fromMetaType(QMetaType type,
const void *copy =
nullptr);
597 bool canConvert()
const
598 {
return canConvert(QMetaType::fromType<T>()); }
602 {
return canView(QMetaType::fromType<T>()); }
604 static QPartialOrdering compare(
const QVariant &lhs,
const QVariant &rhs);
607 template <
typename StdVariant>
608 static QVariant fromStdVariantImpl(StdVariant &&v)
610 if (Q_UNLIKELY(v.valueless_by_exception()))
612 auto visitor = [](
auto &&arg) {
613 return QVariant::fromValue(q23::forward_like<StdVariant>(arg));
615 return std::visit(visitor, std::forward<StdVariant>(v));
618 friend bool comparesEqual(
const QVariant &a,
const QVariant &b)
619 {
return a.equals(b); }
620 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QVariant)
622#ifndef QT_NO_DEBUG_STREAM
623 template <
typename T>
624 friend auto operator<<(
const QDebug &debug,
const T &variant) -> std::enable_if_t<std::is_same_v<T, QVariant>, QDebug> {
625 return variant.qdebugHelper(debug);
627 QDebug qdebugHelper(QDebug)
const;
630 template <
typename T>
631 friend T *get_if(QVariant *v)
noexcept
634 if (!v || v->d.type() != QMetaType::fromType<T>())
636 return static_cast<T*>(v->data());
638 template <
typename T>
639 friend const T *get_if(
const QVariant *v)
noexcept
642 if (!v || v->d.is_null || v->d.type() != QMetaType::fromType<T>())
644 return static_cast<
const T*>(v->data());
647#define Q_MK_GET(cvref)
648 template <typename T>
649 friend T cvref get(QVariant cvref v)
651 if constexpr (std::is_const_v<T cvref>)
652 Q_ASSERT(!v.d.is_null);
653 Q_ASSERT(v.d.type() == QMetaType::fromType<q20::remove_cvref_t<T>>());
654 return static_cast<T cvref>(*get_if<T>(&v));
663 static QVariant moveConstruct(QMetaType type,
void *data);
664 static QVariant copyConstruct(QMetaType type,
const void *data);
667 friend inline T qvariant_cast(
const QVariant &);
669 friend inline T qvariant_cast(QVariant &&);
673 void create(
int type,
const void *copy);
674 void create(QMetaType type,
const void *copy);
675 bool equals(
const QVariant &other)
const;
676 bool convert(
int type,
void *ptr)
const;
677 bool view(
int type,
void *ptr);
681 inline QVariant(
void *) =
delete;
688 QVariant(QMetaType::Type) =
delete;
691 QVariant(std::in_place_t, QMetaType type);
693 void *prepareForEmplace(QMetaType type);
700 QVariant(Qt::GlobalColor) =
delete;
701 QVariant(Qt::BrushStyle) =
delete;
702 QVariant(Qt::PenStyle) =
delete;
703 QVariant(Qt::CursorShape) =
delete;
704#ifdef QT_NO_CAST_FROM_ASCII
706 inline QVariant(
const char *) =
delete;
709 typedef Private DataPtr;
710 inline DataPtr &data_ptr() {
return d; }
711 inline const DataPtr &data_ptr()
const {
return d; }