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; }
127 template<
typename T>
const T &get()
const
128 {
return *
static_cast<
const T *>(storage()); }
130 inline const QtPrivate::QMetaTypeInterface *typeInterface()
const
132 return reinterpret_cast<
const QtPrivate::QMetaTypeInterface *>(packedType << 2);
135 inline QMetaType type()
const
137 return QMetaType(typeInterface());
141#if QT_DEPRECATED_SINCE(6
, 0
)
142 enum QT_DEPRECATED_VERSION_X_6_0(
"Use QMetaType::Type instead.") Type
144 Invalid = QMetaType::UnknownType,
145 Bool = QMetaType::Bool,
146 Int = QMetaType::Int,
147 UInt = QMetaType::UInt,
148 LongLong = QMetaType::LongLong,
149 ULongLong = QMetaType::ULongLong,
150 Double = QMetaType::Double,
151 Char = QMetaType::QChar,
152 Map = QMetaType::QVariantMap,
153 List = QMetaType::QVariantList,
154 String = QMetaType::QString,
155 StringList = QMetaType::QStringList,
156 ByteArray = QMetaType::QByteArray,
157 BitArray = QMetaType::QBitArray,
158 Date = QMetaType::QDate,
159 Time = QMetaType::QTime,
160 DateTime = QMetaType::QDateTime,
161 Url = QMetaType::QUrl,
162 Locale = QMetaType::QLocale,
163 Rect = QMetaType::QRect,
164 RectF = QMetaType::QRectF,
165 Size = QMetaType::QSize,
166 SizeF = QMetaType::QSizeF,
167 Line = QMetaType::QLine,
168 LineF = QMetaType::QLineF,
169 Point = QMetaType::QPoint,
170 PointF = QMetaType::QPointF,
171#if QT_CONFIG(regularexpression)
172 RegularExpression = QMetaType::QRegularExpression,
174 Hash = QMetaType::QVariantHash,
175#if QT_CONFIG(easingcurve)
176 EasingCurve = QMetaType::QEasingCurve,
178 Uuid = QMetaType::QUuid,
179#if QT_CONFIG(itemmodel)
180 ModelIndex = QMetaType::QModelIndex,
181 PersistentModelIndex = QMetaType::QPersistentModelIndex,
183 LastCoreType = QMetaType::LastCoreType,
185 Font = QMetaType::QFont,
186 Pixmap = QMetaType::QPixmap,
187 Brush = QMetaType::QBrush,
188 Color = QMetaType::QColor,
189 Palette = QMetaType::QPalette,
190 Image = QMetaType::QImage,
191 Polygon = QMetaType::QPolygon,
192 Region = QMetaType::QRegion,
193 Bitmap = QMetaType::QBitmap,
194 Cursor = QMetaType::QCursor,
195#if QT_CONFIG(shortcut)
196 KeySequence = QMetaType::QKeySequence,
198 Pen = QMetaType::QPen,
199 TextLength = QMetaType::QTextLength,
200 TextFormat = QMetaType::QTextFormat,
201 Transform = QMetaType::QTransform,
202 Matrix4x4 = QMetaType::QMatrix4x4,
203 Vector2D = QMetaType::QVector2D,
204 Vector3D = QMetaType::QVector3D,
205 Vector4D = QMetaType::QVector4D,
206 Quaternion = QMetaType::QQuaternion,
207 PolygonF = QMetaType::QPolygonF,
208 Icon = QMetaType::QIcon,
209 LastGuiType = QMetaType::LastGuiType,
211 SizePolicy = QMetaType::QSizePolicy,
213 UserType = QMetaType::User,
214 LastType = 0xffffffff
217 QVariant()
noexcept : d() {}
219 explicit QVariant(QMetaType type,
const void *copy =
nullptr);
220 QVariant(
const QVariant &other);
223 template <
typename T,
typename ...Args>
224 using is_noexcept_constructible = std::conjunction<
225 std::bool_constant<Private::CanUseInternalSpace<T>>,
226 std::is_nothrow_constructible<T, Args...>
230 template <
typename T,
typename... Args,
231 if_constructible<T, Args...> =
true>
232 explicit QVariant(std::in_place_type_t<T>, Args&&... args)
233 noexcept(is_noexcept_constructible<q20::remove_cvref_t<T>, Args...>::value)
234 : QVariant(std::in_place, QMetaType::fromType<q20::remove_cvref_t<T>>() )
236 void *data =
const_cast<
void *>(constData());
237 new (data) T(std::forward<Args>(args)...);
240 template <
typename T,
typename U,
typename... Args,
241 if_constructible<T, std::initializer_list<U> &, Args...> =
true>
242 explicit QVariant(std::in_place_type_t<T>, std::initializer_list<U> il, Args&&... args)
243 noexcept(is_noexcept_constructible<q20::remove_cvref_t<T>,
244 std::initializer_list<U> &,
247 : QVariant(std::in_place, QMetaType::fromType<q20::remove_cvref_t<T>>())
249 char *data =
static_cast<
char *>(
const_cast<
void *>(constData()));
250 new (data) T(il, std::forward<Args>(args)...);
254 QVariant(
int i)
noexcept;
255 QVariant(uint ui)
noexcept;
256 QVariant(qlonglong ll)
noexcept;
257 QVariant(qulonglong ull)
noexcept;
258 QVariant(
bool b)
noexcept;
259 QVariant(
double d)
noexcept;
260 QVariant(
float f)
noexcept;
263 QVariant(QChar qchar)
noexcept;
264 QVariant(QDate date)
noexcept;
265 QVariant(QTime time)
noexcept;
266 QVariant(
const QBitArray &bitarray)
noexcept;
267 QVariant(
const QByteArray &bytearray)
noexcept;
268 QVariant(
const QDateTime &datetime)
noexcept;
269 QVariant(
const QHash<QString, QVariant> &hash)
noexcept;
270 QVariant(
const QJsonArray &jsonArray)
noexcept;
271 QVariant(
const QJsonObject &jsonObject)
noexcept;
272 QVariant(
const QList<QVariant> &list)
noexcept;
273 QVariant(
const QLocale &locale)
noexcept;
274 QVariant(
const QMap<QString, QVariant> &map)
noexcept;
275 QVariant(
const QRegularExpression &re)
noexcept;
276 QVariant(
const QString &string)
noexcept;
277 QVariant(
const QStringList &stringlist)
noexcept;
278 QVariant(
const QUrl &url)
noexcept;
282 QVariant(
const QJsonValue &jsonValue)
noexcept(Private::FitsInInternalSize<
sizeof(CborValueStandIn)>);
283 QVariant(
const QModelIndex &modelIndex)
noexcept(Private::FitsInInternalSize<8 + 2 *
sizeof(quintptr)>);
284 QVariant(QUuid uuid)
noexcept(Private::FitsInInternalSize<16>);
285 QVariant(QSize size)
noexcept;
286 QVariant(QSizeF size)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 2>);
287 QVariant(QPoint pt)
noexcept;
288 QVariant(QPointF pt)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 2>);
289 QVariant(QLine line)
noexcept(Private::FitsInInternalSize<
sizeof(
int) * 4>);
290 QVariant(QLineF line)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 4>);
291 QVariant(QRect rect)
noexcept(Private::FitsInInternalSize<
sizeof(
int) * 4>);
292 QVariant(QRectF rect)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 4>);
295 QVariant(
const QEasingCurve &easing)
noexcept(
false);
296 QVariant(
const QJsonDocument &jsonDocument)
noexcept(
false);
297 QVariant(
const QPersistentModelIndex &modelIndex)
noexcept(
false);
299#ifndef QT_NO_CAST_FROM_ASCII
300 QT_ASCII_CAST_WARN QVariant(
const char *str)
noexcept(
false)
301 : QVariant(QString::fromUtf8(str))
304 QVariant(QLatin1StringView string)
noexcept(
false);
306#if !defined(Q_CC_GHS)
308 template <
typename T,
309 std::enable_if_t<std::disjunction_v<std::is_pointer<T>, std::is_member_pointer<T>>,
bool> =
false>
310 QVariant(T) =
delete;
312 QVariant(
const volatile void *) =
delete;
315#if QT_CORE_REMOVED_SINCE(6
, 5
)
316 QVariant(
const QSize &size);
317 QVariant(
const QSizeF &size);
318 QVariant(
const QPoint &pt);
319 QVariant(
const QPointF &pt);
320 QVariant(
const QLine &line);
321 QVariant(
const QLineF &line);
322 QVariant(
const QRect &rect);
323 QVariant(
const QRectF &rect);
324 QVariant(
const QUuid &uuid);
327 QVariant& operator=(
const QVariant &other);
328 inline QVariant(QVariant &&other)
noexcept : d(other.d)
329 { other.d = Private(); }
330 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QVariant)
332 inline void swap(QVariant &other)
noexcept { std::swap(d, other.d); }
334 int userType()
const {
return typeId(); }
335 int typeId()
const {
return metaType().id(); }
337 const char *typeName()
const;
338 QMetaType metaType()
const;
340 bool canConvert(QMetaType targetType)
const
341 {
return QMetaType::canConvert(d.type(), targetType); }
342 bool convert(QMetaType type);
344 bool canView(QMetaType targetType)
const
345 {
return QMetaType::canView(d.type(), targetType); }
347#if QT_DEPRECATED_SINCE(6
, 0
)
348 QT_DEPRECATED_VERSION_6_0
349 bool canConvert(
int targetTypeId)
const
350 {
return QMetaType::canConvert(d.type(), QMetaType(targetTypeId)); }
351 QT_DEPRECATED_VERSION_6_0
352 bool convert(
int targetTypeId)
353 {
return convert(QMetaType(targetTypeId)); }
356 inline bool isValid()
const;
362 inline bool isDetached()
const;
364 int toInt(
bool *ok =
nullptr)
const;
365 uint toUInt(
bool *ok =
nullptr)
const;
366 qlonglong toLongLong(
bool *ok =
nullptr)
const;
367 qulonglong toULongLong(
bool *ok =
nullptr)
const;
369 double toDouble(
bool *ok =
nullptr)
const;
370 float toFloat(
bool *ok =
nullptr)
const;
371 qreal toReal(
bool *ok =
nullptr)
const;
372 QByteArray toByteArray()
const;
373 QBitArray toBitArray()
const;
374 QString toString()
const;
375 QStringList toStringList()
const;
376 QChar toChar()
const;
377 QDate toDate()
const;
378 QTime toTime()
const;
379 QDateTime toDateTime()
const;
380 QList<QVariant> toList()
const;
381 QMap<QString, QVariant> toMap()
const;
382 QHash<QString, QVariant> toHash()
const;
384 QPoint toPoint()
const;
385 QPointF toPointF()
const;
386 QRect toRect()
const;
387 QSize toSize()
const;
388 QSizeF toSizeF()
const;
389 QLine toLine()
const;
390 QLineF toLineF()
const;
391 QRectF toRectF()
const;
392 QLocale toLocale()
const;
393#if QT_CONFIG(regularexpression)
394 QRegularExpression toRegularExpression()
const;
396#if QT_CONFIG(easingcurve)
397 QEasingCurve toEasingCurve()
const;
399 QUuid toUuid()
const;
401 QJsonValue toJsonValue()
const;
402 QJsonObject toJsonObject()
const;
403 QJsonArray toJsonArray()
const;
404 QJsonDocument toJsonDocument()
const;
405#if QT_CONFIG(itemmodel)
406 QModelIndex toModelIndex()
const;
407 QPersistentModelIndex toPersistentModelIndex()
const;
410#ifndef QT_NO_DATASTREAM
411 void load(QDataStream &ds);
412 void save(QDataStream &ds)
const;
414#if QT_DEPRECATED_SINCE(6
, 0
)
416 QT_WARNING_DISABLE_DEPRECATED
417 QT_DEPRECATED_VERSION_X_6_0(
"Use the constructor taking a QMetaType instead.")
418 explicit QVariant(Type type)
419 : QVariant(QMetaType(
int(type)))
421 QT_DEPRECATED_VERSION_X_6_0(
"Use typeId() or metaType().")
424 int type = d.type().id();
425 return type >= QMetaType::User ? UserType :
static_cast<Type>(type);
427 QT_DEPRECATED_VERSION_6_0
428 static const char *typeToName(
int typeId)
429 {
return QMetaType(typeId).name(); }
430 QT_DEPRECATED_VERSION_6_0
431 static Type nameToType(
const char *name)
433 int metaType = QMetaType::fromName(name).id();
434 return metaType <=
int(UserType) ? QVariant::Type(metaType) : UserType;
440 const void *constData()
const
441 {
return d.storage(); }
442 inline const void *data()
const {
return constData(); }
445 template <
typename T>
446 void verifySuitableForEmplace()
448 static_assert(!std::is_reference_v<T>,
449 "QVariant does not support reference types");
450 static_assert(!std::is_const_v<T>,
451 "QVariant does not support const types");
452 static_assert(std::is_copy_constructible_v<T>,
453 "QVariant requires that the type is copyable");
454 static_assert(std::is_destructible_v<T>,
455 "QVariant requires that the type is destructible");
458 template <
typename T,
typename... Args>
459 T &emplaceImpl(Args&&... args)
461 verifySuitableForEmplace<T>();
462 auto data =
static_cast<T *>(prepareForEmplace(QMetaType::fromType<T>()));
463 return *q20::construct_at(data, std::forward<Args>(args)...);
467 template <
typename T,
typename... Args,
468 if_constructible<T, Args...> =
true>
469 T &emplace(Args&&... args)
471 return emplaceImpl<T>(std::forward<Args>(args)...);
474 template <
typename T,
typename U,
typename... Args,
475 if_constructible<T, std::initializer_list<U> &, Args...> =
true>
476 T &emplace(std::initializer_list<U> list, Args&&... args)
478 return emplaceImpl<T>(list, std::forward<Args>(args)...);
481 template<
typename T,
typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, QVariant>>>
482 void setValue(T &&avalue)
484 using VT = std::decay_t<T>;
485 QMetaType metaType = QMetaType::fromType<VT>();
487 if (isDetached() && d.type() == metaType) {
488 *
reinterpret_cast<VT *>(
const_cast<
void *>(constData())) = std::forward<T>(avalue);
491 *
this = QVariant::fromValue<VT>(std::forward<T>(avalue));
495 void setValue(
const QVariant &avalue)
500 void setValue(QVariant &&avalue)
502 *
this = std::move(avalue);
506 inline T value()
const &
507 {
return qvariant_cast<T>(*
this); }
513 QMetaType::view(metaType(), data(), QMetaType::fromType<T>(), &t);
519 {
return qvariant_cast<T>(std::move(*
this)); }
521 template<
typename T, if_rvalue<T> =
true>
524
525
526 static inline auto fromValue(T &&value)
527 noexcept(std::is_nothrow_copy_constructible_v<T> && Private::CanUseInternalSpace<T>)
528 -> std::enable_if_t<std::conjunction_v<std::is_copy_constructible<T>,
529 std::is_destructible<T>>, QVariant>
531 static inline QVariant fromValue(T &&value)
535 using Type = std::remove_cv_t<T>;
536 if constexpr (std::is_null_pointer_v<Type>)
537 return QVariant::fromMetaType(QMetaType::fromType<std::nullptr_t>());
538 else if constexpr (std::is_same_v<Type, QVariant>)
539 return std::forward<T>(value);
540 else if constexpr (std::is_same_v<Type, std::monostate>)
542 QMetaType mt = QMetaType::fromType<Type>();
547 if constexpr (std::conjunction_v<std::is_move_constructible<Type>, std::negation<std::is_const<T>>>)
548 return moveConstruct(QMetaType::fromType<Type>(), std::addressof(value));
550 return copyConstruct(mt, std::addressof(value));
555 static inline auto fromValue(
const T &value)
556 noexcept(std::is_nothrow_copy_constructible_v<T> && Private::CanUseInternalSpace<T>)
557 -> std::enable_if_t<std::is_copy_constructible_v<T> && std::is_destructible_v<T>, QVariant>
559 static inline QVariant fromValue(
const T &value)
562 if constexpr (std::is_null_pointer_v<T>)
563 return QVariant(QMetaType::fromType<std::nullptr_t>());
564 else if constexpr (std::is_same_v<T, QVariant>)
566 else if constexpr (std::is_same_v<T, std::monostate>)
568 return QVariant(QMetaType::fromType<T>(), std::addressof(value));
571 template<
typename... Types>
572 static inline QVariant fromStdVariant(
const std::variant<Types...> &value)
574 return fromStdVariantImpl(value);
577 template<
typename... Types>
578 static QVariant fromStdVariant(std::variant<Types...> &&value)
580 return fromStdVariantImpl(std::move(value));
583 static QVariant fromMetaType(QMetaType type,
const void *copy =
nullptr);
586 bool canConvert()
const
587 {
return canConvert(QMetaType::fromType<T>()); }
591 {
return canView(QMetaType::fromType<T>()); }
593 static QPartialOrdering compare(
const QVariant &lhs,
const QVariant &rhs);
596 template <
typename StdVariant>
597 static QVariant fromStdVariantImpl(StdVariant &&v)
599 if (Q_UNLIKELY(v.valueless_by_exception()))
601 auto visitor = [](
auto &&arg) {
602 return QVariant::fromValue(q23::forward_like<StdVariant>(arg));
604 return std::visit(visitor, std::forward<StdVariant>(v));
607 friend bool comparesEqual(
const QVariant &a,
const QVariant &b)
608 {
return a.equals(b); }
609 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QVariant)
611#ifndef QT_NO_DEBUG_STREAM
612 template <
typename T>
613 friend auto operator<<(
const QDebug &debug,
const T &variant) -> std::enable_if_t<std::is_same_v<T, QVariant>, QDebug> {
614 return variant.qdebugHelper(debug);
616 QDebug qdebugHelper(QDebug)
const;
619 template <
typename T>
620 friend T *get_if(QVariant *v)
noexcept
623 if (!v || v->d.type() != QMetaType::fromType<T>())
625 return static_cast<T*>(v->data());
627 template <
typename T>
628 friend const T *get_if(
const QVariant *v)
noexcept
631 if (!v || v->d.is_null || v->d.type() != QMetaType::fromType<T>())
633 return static_cast<
const T*>(v->data());
636#define Q_MK_GET(cvref)
637 template <typename T>
638 friend T cvref get(QVariant cvref v)
640 if constexpr (std::is_const_v<T cvref>)
641 Q_ASSERT(!v.d.is_null);
642 Q_ASSERT(v.d.type() == QMetaType::fromType<q20::remove_cvref_t<T>>());
643 return static_cast<T cvref>(*get_if<T>(&v));
652 static QVariant moveConstruct(QMetaType type,
void *data);
653 static QVariant copyConstruct(QMetaType type,
const void *data);
656 friend inline T qvariant_cast(
const QVariant &);
658 friend inline T qvariant_cast(QVariant &&);
662 void create(
int type,
const void *copy);
663 void create(QMetaType type,
const void *copy);
664 bool equals(
const QVariant &other)
const;
665 bool convert(
int type,
void *ptr)
const;
666 bool view(
int type,
void *ptr);
670 inline QVariant(
void *) =
delete;
677 QVariant(QMetaType::Type) =
delete;
680 QVariant(std::in_place_t, QMetaType type);
682 void *prepareForEmplace(QMetaType type);
689 QVariant(Qt::GlobalColor) =
delete;
690 QVariant(Qt::BrushStyle) =
delete;
691 QVariant(Qt::PenStyle) =
delete;
692 QVariant(Qt::CursorShape) =
delete;
693#ifdef QT_NO_CAST_FROM_ASCII
695 inline QVariant(
const char *) =
delete;
698 typedef Private DataPtr;
699 inline DataPtr &data_ptr() {
return d; }
700 inline const DataPtr &data_ptr()
const {
return d; }