67 template <
typename T,
typename... Args>
68 using if_constructible = std::enable_if_t<
70 std::is_copy_constructible<q20::remove_cvref_t<T>>,
71 std::is_destructible<q20::remove_cvref_t<T>>,
72 std::is_constructible<q20::remove_cvref_t<T>, Args...>
77 using if_rvalue = std::enable_if_t<!std::is_reference_v<T>,
bool>;
79 struct CborValueStandIn { qint64 n;
void *c;
int t; };
84 inline PrivateShared() : ref(1) { }
86 static int computeOffset(PrivateShared *ps, size_t align);
87 static size_t computeAllocationSize(size_t size, size_t align);
88 static PrivateShared *create(size_t size, size_t align);
89 static void free(PrivateShared *p);
91 alignas(8) QAtomicInt ref;
94 const void *data()
const {
return reinterpret_cast<
const uchar *>(
this) + offset; }
95 void *data() {
return reinterpret_cast<uchar *>(
this) + offset; }
100 static constexpr size_t MaxInternalSize = 3 *
sizeof(
void *);
101 template <size_t S>
static constexpr bool FitsInInternalSize = S <= MaxInternalSize;
102 template<
typename T>
static constexpr bool CanUseInternalSpace =
103 (QTypeInfo<T>::isRelocatable && FitsInInternalSize<
sizeof(T)> &&
alignof(T) <=
alignof(
double));
104 static constexpr bool canUseInternalSpace(
const QtPrivate::QMetaTypeInterface *type)
107 return QMetaType::TypeFlags(type->flags) & QMetaType::RelocatableType &&
108 size_t(type->size) <= MaxInternalSize && size_t(type->alignment) <=
alignof(
double);
113 uchar data[MaxInternalSize] = {};
114 PrivateShared *shared;
115 double _forAlignment;
117 quintptr is_shared : 1;
118 quintptr is_null : 1;
119 quintptr packedType :
sizeof(QMetaType) * 8 - 2;
121 constexpr Private()
noexcept : is_shared(
false), is_null(
true), packedType(0) {}
122 explicit Private(
const QtPrivate::QMetaTypeInterface *iface)
noexcept;
123 template <
typename T>
explicit Private(std::piecewise_construct_t,
const T &t);
125 const void *storage()
const
126 {
return is_shared ? data.shared->data() : &data.data; }
128 template<
typename T>
const T &get()
const
129 {
return *
static_cast<
const T *>(storage()); }
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 QVariant(
const QBitArray &bitarray)
noexcept;
268 QVariant(
const QByteArray &bytearray)
noexcept;
269 QVariant(
const QDateTime &datetime)
noexcept;
270 QVariant(
const QHash<QString, QVariant> &hash)
noexcept;
271 QVariant(
const QJsonArray &jsonArray)
noexcept;
272 QVariant(
const QJsonObject &jsonObject)
noexcept;
273 QVariant(
const QList<QVariant> &list)
noexcept;
274 QVariant(
const QLocale &locale)
noexcept;
275 QVariant(
const QMap<QString, QVariant> &map)
noexcept;
276 QVariant(
const QRegularExpression &re)
noexcept;
277 QVariant(
const QString &string)
noexcept;
278 QVariant(
const QStringList &stringlist)
noexcept;
279 QVariant(
const QUrl &url)
noexcept;
283 QVariant(
const QJsonValue &jsonValue)
noexcept(Private::FitsInInternalSize<
sizeof(CborValueStandIn)>);
284 QVariant(
const QModelIndex &modelIndex)
noexcept(Private::FitsInInternalSize<8 + 2 *
sizeof(quintptr)>);
285 QVariant(QUuid uuid)
noexcept(Private::FitsInInternalSize<16>);
286 QVariant(QSize size)
noexcept;
287 QVariant(QSizeF size)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 2>);
288 QVariant(QPoint pt)
noexcept;
289 QVariant(QPointF pt)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 2>);
290 QVariant(QLine line)
noexcept(Private::FitsInInternalSize<
sizeof(
int) * 4>);
291 QVariant(QLineF line)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 4>);
292 QVariant(QRect rect)
noexcept(Private::FitsInInternalSize<
sizeof(
int) * 4>);
293 QVariant(QRectF rect)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 4>);
296 QVariant(
const QEasingCurve &easing)
noexcept(
false);
297 QVariant(
const QJsonDocument &jsonDocument)
noexcept(
false);
298 QVariant(
const QPersistentModelIndex &modelIndex)
noexcept(
false);
300#ifndef QT_NO_CAST_FROM_ASCII
301 QT_ASCII_CAST_WARN QVariant(
const char *str)
noexcept(
false)
302 : QVariant(QString::fromUtf8(str))
305 QVariant(QLatin1StringView string)
noexcept(
false);
307#if !defined(Q_CC_GHS)
309 template <
typename T,
310 std::enable_if_t<std::disjunction_v<std::is_pointer<T>, std::is_member_pointer<T>>,
bool> =
false>
311 QVariant(T) =
delete;
313 QVariant(
const volatile void *) =
delete;
316#if QT_CORE_REMOVED_SINCE(6
, 5
)
317 QVariant(
const QSize &size);
318 QVariant(
const QSizeF &size);
319 QVariant(
const QPoint &pt);
320 QVariant(
const QPointF &pt);
321 QVariant(
const QLine &line);
322 QVariant(
const QLineF &line);
323 QVariant(
const QRect &rect);
324 QVariant(
const QRectF &rect);
325 QVariant(
const QUuid &uuid);
328 QVariant& operator=(
const QVariant &other);
329 inline QVariant(QVariant &&other)
noexcept : d(other.d)
330 { other.d = Private(); }
331 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QVariant)
333 inline void swap(QVariant &other)
noexcept { std::swap(d, other.d); }
335 int userType()
const {
return typeId(); }
339 const QtPrivate::QMetaTypeInterface *mt = metaType().iface();
342 int id = mt->typeId.loadRelaxed();
347 QT_CORE_INLINE_SINCE(6, 10)
348 const char *typeName()
const;
349 QT_CORE_INLINE_SINCE(6, 10)
350 QMetaType metaType()
const;
352 bool canConvert(QMetaType targetType)
const
353 {
return QMetaType::canConvert(d.type(), targetType); }
354 bool convert(QMetaType type);
356 bool canView(QMetaType targetType)
const
357 {
return QMetaType::canView(d.type(), targetType); }
359#if QT_DEPRECATED_SINCE(6
, 0
)
360 QT_DEPRECATED_VERSION_6_0
361 bool canConvert(
int targetTypeId)
const
362 {
return QMetaType::canConvert(d.type(), QMetaType(targetTypeId)); }
363 QT_DEPRECATED_VERSION_6_0
364 bool convert(
int targetTypeId)
365 {
return convert(QMetaType(targetTypeId)); }
368 inline bool isValid()
const;
374 inline bool isDetached()
const;
376 int toInt(
bool *ok =
nullptr)
const;
377 uint toUInt(
bool *ok =
nullptr)
const;
378 qlonglong toLongLong(
bool *ok =
nullptr)
const;
379 qulonglong toULongLong(
bool *ok =
nullptr)
const;
381 double toDouble(
bool *ok =
nullptr)
const;
382 float toFloat(
bool *ok =
nullptr)
const;
383 qreal toReal(
bool *ok =
nullptr)
const;
384 QByteArray toByteArray()
const;
385 QBitArray toBitArray()
const;
386 QString toString()
const;
387 QStringList toStringList()
const;
388 QChar toChar()
const;
389 QDate toDate()
const;
390 QTime toTime()
const;
391 QDateTime toDateTime()
const;
392 QList<QVariant> toList()
const;
393 QMap<QString, QVariant> toMap()
const;
394 QHash<QString, QVariant> toHash()
const;
396 QPoint toPoint()
const;
397 QPointF toPointF()
const;
398 QRect toRect()
const;
399 QSize toSize()
const;
400 QSizeF toSizeF()
const;
401 QLine toLine()
const;
402 QLineF toLineF()
const;
403 QRectF toRectF()
const;
404 QLocale toLocale()
const;
405#if QT_CONFIG(regularexpression)
406 QRegularExpression toRegularExpression()
const;
408#if QT_CONFIG(easingcurve)
409 QEasingCurve toEasingCurve()
const;
411 QUuid toUuid()
const;
413 QJsonValue toJsonValue()
const;
414 QJsonObject toJsonObject()
const;
415 QJsonArray toJsonArray()
const;
416 QJsonDocument toJsonDocument()
const;
417#if QT_CONFIG(itemmodel)
418 QModelIndex toModelIndex()
const;
419 QPersistentModelIndex toPersistentModelIndex()
const;
422#ifndef QT_NO_DATASTREAM
423 void load(QDataStream &ds);
424 void save(QDataStream &ds)
const;
426#if QT_DEPRECATED_SINCE(6
, 0
)
428 QT_WARNING_DISABLE_DEPRECATED
429 QT_DEPRECATED_VERSION_X_6_0(
"Use the constructor taking a QMetaType instead.")
430 explicit QVariant(Type type)
431 : QVariant(QMetaType(
int(type)))
433 QT_DEPRECATED_VERSION_X_6_0(
"Use typeId() or metaType().")
436 int type = d.type().id();
437 return type >= QMetaType::User ? UserType :
static_cast<Type>(type);
439 QT_DEPRECATED_VERSION_6_0
440 static const char *typeToName(
int typeId)
441 {
return QMetaType(typeId).name(); }
442 QT_DEPRECATED_VERSION_6_0
443 static Type nameToType(
const char *name)
445 int metaType = QMetaType::fromName(name).id();
446 return metaType <=
int(UserType) ? QVariant::Type(metaType) : UserType;
452 const void *constData()
const
453 {
return d.storage(); }
454 inline const void *data()
const {
return constData(); }
457 template <
typename T>
458 void verifySuitableForEmplace()
460 static_assert(!std::is_reference_v<T>,
461 "QVariant does not support reference types");
462 static_assert(!std::is_const_v<T>,
463 "QVariant does not support const types");
464 static_assert(std::is_copy_constructible_v<T>,
465 "QVariant requires that the type is copyable");
466 static_assert(std::is_destructible_v<T>,
467 "QVariant requires that the type is destructible");
470 template <
typename T,
typename... Args>
471 T &emplaceImpl(Args&&... args)
473 verifySuitableForEmplace<T>();
474 auto data =
static_cast<T *>(prepareForEmplace(QMetaType::fromType<T>()));
475 return *q20::construct_at(data, std::forward<Args>(args)...);
479 template <
typename T,
typename... Args,
480 if_constructible<T, Args...> =
true>
481 T &emplace(Args&&... args)
483 return emplaceImpl<T>(std::forward<Args>(args)...);
486 template <
typename T,
typename U,
typename... Args,
487 if_constructible<T, std::initializer_list<U> &, Args...> =
true>
488 T &emplace(std::initializer_list<U> list, Args&&... args)
490 return emplaceImpl<T>(list, std::forward<Args>(args)...);
493 template<
typename T,
typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, QVariant>>>
494 void setValue(T &&avalue)
496 using VT = std::decay_t<T>;
497 QMetaType metaType = QMetaType::fromType<VT>();
499 if (isDetached() && d.type() == metaType) {
500 *
reinterpret_cast<VT *>(
const_cast<
void *>(constData())) = std::forward<T>(avalue);
503 *
this = QVariant::fromValue<VT>(std::forward<T>(avalue));
507 void setValue(
const QVariant &avalue)
512 void setValue(QVariant &&avalue)
514 *
this = std::move(avalue);
518 inline T value()
const &
519 {
return qvariant_cast<T>(*
this); }
525 QMetaType::view(metaType(), data(), QMetaType::fromType<T>(), &t);
531 {
return qvariant_cast<T>(std::move(*
this)); }
533 template<
typename T, if_rvalue<T> =
true>
536
537
538 static inline auto fromValue(T &&value)
539 noexcept(std::is_nothrow_copy_constructible_v<T> && Private::CanUseInternalSpace<T>)
540 -> std::enable_if_t<std::conjunction_v<std::is_copy_constructible<T>,
541 std::is_destructible<T>>, QVariant>
543 static inline QVariant fromValue(T &&value)
547 using Type = std::remove_cv_t<T>;
548 if constexpr (std::is_null_pointer_v<Type>)
549 return QVariant::fromMetaType(QMetaType::fromType<std::nullptr_t>());
550 else if constexpr (std::is_same_v<Type, QVariant>)
551 return std::forward<T>(value);
552 else if constexpr (std::is_same_v<Type, std::monostate>)
554 QMetaType mt = QMetaType::fromType<Type>();
559 if constexpr (std::conjunction_v<std::is_move_constructible<Type>, std::negation<std::is_const<T>>>)
560 return moveConstruct(QMetaType::fromType<Type>(), std::addressof(value));
562 return copyConstruct(mt, std::addressof(value));
567 static inline auto fromValue(
const T &value)
568 noexcept(std::is_nothrow_copy_constructible_v<T> && Private::CanUseInternalSpace<T>)
569 -> std::enable_if_t<std::is_copy_constructible_v<T> && std::is_destructible_v<T>, QVariant>
571 static inline QVariant fromValue(
const T &value)
574 if constexpr (std::is_null_pointer_v<T>)
575 return QVariant(QMetaType::fromType<std::nullptr_t>());
576 else if constexpr (std::is_same_v<T, QVariant>)
578 else if constexpr (std::is_same_v<T, std::monostate>)
580 return QVariant(QMetaType::fromType<T>(), std::addressof(value));
583 template<
typename... Types>
584 static inline QVariant fromStdVariant(
const std::variant<Types...> &value)
586 return fromStdVariantImpl(value);
589 template<
typename... Types>
590 static QVariant fromStdVariant(std::variant<Types...> &&value)
592 return fromStdVariantImpl(std::move(value));
595 static QVariant fromMetaType(QMetaType type,
const void *copy =
nullptr);
598 bool canConvert()
const
599 {
return canConvert(QMetaType::fromType<T>()); }
603 {
return canView(QMetaType::fromType<T>()); }
605 static QPartialOrdering compare(
const QVariant &lhs,
const QVariant &rhs);
608 template <
typename StdVariant>
609 static QVariant fromStdVariantImpl(StdVariant &&v)
611 if (Q_UNLIKELY(v.valueless_by_exception()))
613 auto visitor = [](
auto &&arg) {
614 return QVariant::fromValue(q23::forward_like<StdVariant>(arg));
616 return std::visit(visitor, std::forward<StdVariant>(v));
619 friend bool comparesEqual(
const QVariant &a,
const QVariant &b)
620 {
return a.equals(b); }
621 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QVariant)
623#ifndef QT_NO_DEBUG_STREAM
624 template <
typename T>
625 friend auto operator<<(
const QDebug &debug,
const T &variant) -> std::enable_if_t<std::is_same_v<T, QVariant>, QDebug> {
626 return variant.qdebugHelper(debug);
628 QDebug qdebugHelper(QDebug)
const;
631 template <
typename T>
632 friend T *get_if(QVariant *v)
noexcept
635 if (!v || v->d.type() != QMetaType::fromType<T>())
637 return static_cast<T*>(v->data());
639 template <
typename T>
640 friend const T *get_if(
const QVariant *v)
noexcept
643 if (!v || v->d.is_null || v->d.type() != QMetaType::fromType<T>())
645 return static_cast<
const T*>(v->data());
648#define Q_MK_GET(cvref)
649 template <typename T>
650 friend T cvref get(QVariant cvref v)
652 if constexpr (std::is_const_v<T cvref>)
653 Q_ASSERT(!v.d.is_null);
654 Q_ASSERT(v.d.type() == QMetaType::fromType<q20::remove_cvref_t<T>>());
655 return static_cast<T cvref>(*get_if<T>(&v));
664 static QVariant moveConstruct(QMetaType type,
void *data);
665 static QVariant copyConstruct(QMetaType type,
const void *data);
668 friend inline T qvariant_cast(
const QVariant &);
670 friend inline T qvariant_cast(QVariant &&);
674 void create(
int type,
const void *copy);
675 void create(QMetaType type,
const void *copy);
676 bool equals(
const QVariant &other)
const;
677 bool convert(
int type,
void *ptr)
const;
678 bool view(
int type,
void *ptr);
682 inline QVariant(
void *) =
delete;
689 QVariant(QMetaType::Type) =
delete;
692 QVariant(std::in_place_t, QMetaType type);
694 void *prepareForEmplace(QMetaType type);
701 QVariant(Qt::GlobalColor) =
delete;
702 QVariant(Qt::BrushStyle) =
delete;
703 QVariant(Qt::PenStyle) =
delete;
704 QVariant(Qt::CursorShape) =
delete;
705#ifdef QT_NO_CAST_FROM_ASCII
707 inline QVariant(
const char *) =
delete;
710 typedef Private DataPtr;
711 inline DataPtr &data_ptr() {
return d; }
712 inline const DataPtr &data_ptr()
const {
return d; }