69 template <
typename T,
typename... Args>
70 using if_constructible = std::enable_if_t<
72 std::is_copy_constructible<q20::remove_cvref_t<T>>,
73 std::is_destructible<q20::remove_cvref_t<T>>,
74 std::is_constructible<q20::remove_cvref_t<T>, Args...>
79 using if_rvalue = std::enable_if_t<!std::is_reference_v<T>,
bool>;
81 struct CborValueStandIn { qint64 n;
void *c;
int t; };
86 inline PrivateShared() : ref(1) { }
88 static int computeOffset(PrivateShared *ps, size_t align);
89 static size_t computeAllocationSize(size_t size, size_t align);
90 static PrivateShared *create(size_t size, size_t align);
91 static void free(PrivateShared *p);
93 alignas(8) QAtomicInt ref;
96 const void *data()
const {
return reinterpret_cast<
const uchar *>(
this) + offset; }
97 void *data() {
return reinterpret_cast<uchar *>(
this) + offset; }
102 static constexpr size_t MaxInternalSize = 3 *
sizeof(
void *);
103 template <size_t S>
static constexpr bool FitsInInternalSize = S <= MaxInternalSize;
104 template<
typename T>
static constexpr bool CanUseInternalSpace =
105 (QTypeInfo<T>::isRelocatable && FitsInInternalSize<
sizeof(T)> &&
alignof(T) <=
alignof(
double));
106 static constexpr bool canUseInternalSpace(
const QtPrivate::QMetaTypeInterface *type)
109 return QMetaType::TypeFlags(type->flags) & QMetaType::RelocatableType &&
110 size_t(type->size) <= MaxInternalSize && size_t(type->alignment) <=
alignof(
double);
113 template <
typename T>
static constexpr bool hasAlwaysBeenAbleToUseInternalSpace()
115 if constexpr (!CanUseInternalSpace<T>)
117#if defined(QT_BOOTSTRAPPED) || defined(QT_STATIC)
124 if constexpr (std::is_scalar_v<T>)
126 if constexpr (QtPrivate::IsQFlags<T>::value)
128 if constexpr (QtPrivate::qIsQtRelocatableContainer<T>)
130 if constexpr (QMetaTypeId2<T>::IsBuiltIn) {
132# if QT_VERSION_MAJOR < 7
133 constexpr int LastCoreType = QMetaType::QVariantPair;
134 constexpr int LastGuiType = QMetaType::QColorSpace;
135 constexpr int LastWidgetType = QMetaType::QSizePolicy;
139 constexpr int Id = QMetaTypeId2<T>::MetaType;
140 if constexpr (Id <= LastCoreType)
142 if constexpr (Id >= QMetaType::FirstGuiType && Id <= LastGuiType)
144 if constexpr (Id >= QMetaType::FirstWidgetsType && Id <= LastWidgetType)
153 uchar data[MaxInternalSize] = {};
154 PrivateShared *shared;
155 double _forAlignment;
157 quintptr is_shared : 1;
158 quintptr is_null : 1;
159 quintptr packedType :
sizeof(QMetaType) * 8 - 2;
161 constexpr Private()
noexcept : is_shared(
false), is_null(
true), packedType(0) {}
162 explicit Private(
const QtPrivate::QMetaTypeInterface *iface)
noexcept;
163 template <
typename T>
164 explicit Private(std::in_place_t, T &&t);
165#if QT_DEPRECATED_SINCE(6
, 12
)
166 template <
typename T>
167 QT_DEPRECATED_VERSION_X_6_12(
"use the std::in_place overload and check whether you can move into it.")
168 explicit Private(std::piecewise_construct_t,
const T &t)
169 : Private{std::in_place, t} {}
172 const void *storage()
const
173 {
return is_shared ? data.shared->data() : &data.data; }
175 template<
typename T>
const T &get()
const
177 if constexpr (!FitsInInternalSize<
sizeof(T)> ||
alignof(T) >
alignof(
double)) {
180 return *
static_cast<
const T *>(data.shared->data());
181 }
else if constexpr (hasAlwaysBeenAbleToUseInternalSpace<T>()) {
182 Q_ASSERT(!is_shared);
183 return *
reinterpret_cast<
const T *>(data.data);
185 return *
static_cast<
const T *>(storage());
189 inline const QtPrivate::QMetaTypeInterface *typeInterface()
const
191 return reinterpret_cast<
const QtPrivate::QMetaTypeInterface *>(packedType << 2);
194 inline QMetaType type()
const
196 return QMetaType(typeInterface());
200#if QT_DEPRECATED_SINCE(6
, 0
)
201 enum QT_DEPRECATED_VERSION_X_6_0(
"Use QMetaType::Type instead.") Type
203 Invalid = QMetaType::UnknownType,
204 Bool = QMetaType::Bool,
205 Int = QMetaType::Int,
206 UInt = QMetaType::UInt,
207 LongLong = QMetaType::LongLong,
208 ULongLong = QMetaType::ULongLong,
209 Double = QMetaType::Double,
210 Char = QMetaType::QChar,
211 Map = QMetaType::QVariantMap,
212 List = QMetaType::QVariantList,
213 String = QMetaType::QString,
214 StringList = QMetaType::QStringList,
215 ByteArray = QMetaType::QByteArray,
216 BitArray = QMetaType::QBitArray,
217 Date = QMetaType::QDate,
218 Time = QMetaType::QTime,
219 DateTime = QMetaType::QDateTime,
220 Url = QMetaType::QUrl,
221 Locale = QMetaType::QLocale,
222 Rect = QMetaType::QRect,
223 RectF = QMetaType::QRectF,
224 Size = QMetaType::QSize,
225 SizeF = QMetaType::QSizeF,
226 Line = QMetaType::QLine,
227 LineF = QMetaType::QLineF,
228 Point = QMetaType::QPoint,
229 PointF = QMetaType::QPointF,
230#if QT_CONFIG(regularexpression)
231 RegularExpression = QMetaType::QRegularExpression,
233 Hash = QMetaType::QVariantHash,
234#if QT_CONFIG(easingcurve)
235 EasingCurve = QMetaType::QEasingCurve,
237 Uuid = QMetaType::QUuid,
238#if QT_CONFIG(itemmodel)
239 ModelIndex = QMetaType::QModelIndex,
240 PersistentModelIndex = QMetaType::QPersistentModelIndex,
242 LastCoreType = QMetaType::LastCoreType,
244 Font = QMetaType::QFont,
245 Pixmap = QMetaType::QPixmap,
246 Brush = QMetaType::QBrush,
247 Color = QMetaType::QColor,
248 Palette = QMetaType::QPalette,
249 Image = QMetaType::QImage,
250 Polygon = QMetaType::QPolygon,
251 Region = QMetaType::QRegion,
252 Bitmap = QMetaType::QBitmap,
253 Cursor = QMetaType::QCursor,
254#if QT_CONFIG(shortcut)
255 KeySequence = QMetaType::QKeySequence,
257 Pen = QMetaType::QPen,
258 TextLength = QMetaType::QTextLength,
259 TextFormat = QMetaType::QTextFormat,
260 Transform = QMetaType::QTransform,
261 Matrix4x4 = QMetaType::QMatrix4x4,
262 Vector2D = QMetaType::QVector2D,
263 Vector3D = QMetaType::QVector3D,
264 Vector4D = QMetaType::QVector4D,
265 Quaternion = QMetaType::QQuaternion,
266 PolygonF = QMetaType::QPolygonF,
267 Icon = QMetaType::QIcon,
268 LastGuiType = QMetaType::LastGuiType,
270 SizePolicy = QMetaType::QSizePolicy,
272 UserType = QMetaType::User,
273 LastType = 0xffffffff
276 QVariant()
noexcept : d() {}
278 explicit QVariant(QMetaType type,
const void *copy =
nullptr);
279 QVariant(
const QVariant &other);
282 template <
typename T,
typename ...Args>
283 using is_noexcept_constructible = std::conjunction<
284 std::bool_constant<Private::CanUseInternalSpace<T>>,
285 std::is_nothrow_constructible<T, Args...>
289 template<
typename Indirect>
292 template<
typename Indirect>
296 friend class Reference<Indirect>;
297 const Indirect m_referred;
302 explicit ConstReference(
const Indirect &referred)
303 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
304 : m_referred(referred) {}
305 explicit ConstReference(Indirect &&referred)
306 noexcept(std::is_nothrow_move_constructible_v<Indirect>)
307 : m_referred(std::move(referred)) {}
308 ConstReference(
const ConstReference &)
309 noexcept(std::is_nothrow_copy_constructible_v<Indirect>) =
default;
315 ConstReference(ConstReference &&) =
delete;
317 ConstReference(
const Reference<Indirect> &)
318 noexcept(std::is_nothrow_copy_constructible_v<Indirect>);
326 ~ConstReference() =
default;
327 ConstReference &operator=(
const ConstReference &value) =
delete;
328 ConstReference &operator=(ConstReference &&value) =
delete;
331 operator QVariant()
const noexcept(Indirect::CanNoexceptConvertToQVariant);
334 template<
typename Indirect>
338 friend class ConstReference<Indirect>;
341 friend void swap(Reference a, Reference b) {
return a.swap(b); }
346 explicit Reference(
const Indirect &referred)
347 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
348 : m_referred(referred) {}
349 explicit Reference(Indirect &&referred)
350 noexcept(std::is_nothrow_move_constructible_v<Indirect>)
351 : m_referred(std::move(referred)) {}
352 Reference(
const Reference &) =
default;
358 Reference(Reference &&) =
delete;
360 ~Reference() =
default;
362 Reference &operator=(
const Reference &value)
363 noexcept(Indirect::CanNoexceptAssignQVariant)
365 return operator=(QVariant(value));
368 Reference &operator=(Reference &&value)
369 noexcept(Indirect::CanNoexceptAssignQVariant)
371 return operator=(QVariant(value));
374 Reference &operator=(
const ConstReference<Indirect> &value)
375 noexcept(Indirect::CanNoexceptAssignQVariant)
377 return operator=(QVariant(value));
380 Reference &operator=(ConstReference<Indirect> &&value)
381 noexcept(Indirect::CanNoexceptAssignQVariant)
383 return operator=(QVariant(value));
386 operator QVariant()
const noexcept(Indirect::CanNoexceptConvertToQVariant)
388 return ConstReference<Indirect>(m_referred);
391 void swap(Reference b)
394 QVariant tmp = *
this;
395 *
this = std::move(b);
400 Reference &operator=(
const QVariant &value)
noexcept(Indirect::CanNoexceptAssignQVariant);
403 template<
typename Indirect>
410 explicit ConstPointer(
const Indirect &pointed)
411 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
412 : m_pointed(pointed) {}
413 explicit ConstPointer(Indirect &&pointed)
414 noexcept(std::is_nothrow_move_constructible_v<Indirect>)
415 : m_pointed(std::move(pointed)) {}
417 ConstReference<Indirect> operator*()
418 const noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
420 return ConstReference<Indirect>(m_pointed);
424 template<
typename Indirect>
431 explicit Pointer(
const Indirect &pointed)
432 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
433 : m_pointed(pointed) {}
434 explicit Pointer(Indirect &&pointed)
435 noexcept(std::is_nothrow_move_constructible_v<Indirect>)
436 : m_pointed(std::move(pointed)) {}
438 Reference<Indirect> operator*()
439 const noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
441 return Reference<Indirect>(m_pointed);
444 operator ConstPointer<Indirect>()
const
445 noexcept(std::is_nothrow_copy_constructible_v<Indirect>)
447 return ConstPointer<Indirect>(m_pointed);
451 template <
typename T,
typename... Args,
452 if_constructible<T, Args...> =
true>
453 explicit QVariant(std::in_place_type_t<T>, Args&&... args)
454 noexcept(is_noexcept_constructible<q20::remove_cvref_t<T>, Args...>::value)
455 : QVariant(std::in_place, QMetaType::fromType<q20::remove_cvref_t<T>>() )
457 void *data =
const_cast<
void *>(constData());
458 new (data) T(std::forward<Args>(args)...);
461 template <
typename T,
typename U,
typename... Args,
462 if_constructible<T, std::initializer_list<U> &, Args...> =
true>
463 explicit QVariant(std::in_place_type_t<T>, std::initializer_list<U> il, Args&&... args)
464 noexcept(is_noexcept_constructible<q20::remove_cvref_t<T>,
465 std::initializer_list<U> &,
468 : QVariant(std::in_place, QMetaType::fromType<q20::remove_cvref_t<T>>())
470 void *data =
const_cast<
void *>(constData());
471 new (data) T(il, std::forward<Args>(args)...);
475 QVariant(
int i)
noexcept;
476 QVariant(uint ui)
noexcept;
477 QVariant(qlonglong ll)
noexcept;
478 QVariant(qulonglong ull)
noexcept;
479 QVariant(
bool b)
noexcept;
480 QVariant(
double d)
noexcept;
481 QVariant(
float f)
noexcept;
484 QVariant(QChar qchar)
noexcept;
485 QVariant(QDate date)
noexcept;
486 QVariant(QTime time)
noexcept;
487 QVariant(
const QBitArray &bitarray)
noexcept;
488 QVariant(QBitArray &&bitarray)
noexcept;
489 QVariant(
const QByteArray &bytearray)
noexcept;
490 QVariant(QByteArray &&bytearray)
noexcept;
491 QVariant(
const QDateTime &datetime)
noexcept;
492 QVariant(QDateTime &&datetime)
noexcept;
493 QVariant(
const QHash<QString, QVariant> &hash)
noexcept;
494 QVariant(QHash<QString, QVariant> &&hash)
noexcept;
495 QVariant(
const QJsonArray &jsonArray)
noexcept;
496 QVariant(QJsonArray &&jsonArray)
noexcept;
497 QVariant(
const QJsonObject &jsonObject)
noexcept;
498 QVariant(QJsonObject &&jsonObject)
noexcept;
499 QVariant(
const QList<QVariant> &list)
noexcept;
500 QVariant(QList<QVariant> &&list)
noexcept;
501 QVariant(
const QLocale &locale)
noexcept;
502 QVariant(QLocale &&locale)
noexcept;
503 QVariant(
const QMap<QString, QVariant> &map)
noexcept;
504 QVariant(QMap<QString, QVariant> &&map)
noexcept;
505 QVariant(
const QRegularExpression &re)
noexcept;
506 QVariant(QRegularExpression &&re)
noexcept;
507 QVariant(
const QString &string)
noexcept;
508 QVariant(QString &&string)
noexcept;
509 QVariant(
const QStringList &stringlist)
noexcept;
510 QVariant(QStringList &&stringlist)
noexcept;
511 QVariant(
const QUrl &url)
noexcept;
512 QVariant(QUrl &&url)
noexcept;
516 QVariant(
const QJsonValue &jsonValue)
noexcept(Private::FitsInInternalSize<
sizeof(CborValueStandIn)>);
517 QVariant(QJsonValue &&jsonValue)
noexcept(Private::FitsInInternalSize<
sizeof(CborValueStandIn)>);
518 QVariant(
const QModelIndex &modelIndex)
noexcept(Private::FitsInInternalSize<8 + 2 *
sizeof(quintptr)>);
519 QVariant(QUuid uuid)
noexcept(Private::FitsInInternalSize<16>);
520 QVariant(QSize size)
noexcept;
521 QVariant(QSizeF size)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 2>);
522 QVariant(QPoint pt)
noexcept;
523 QVariant(QPointF pt)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 2>);
524 QVariant(QLine line)
noexcept(Private::FitsInInternalSize<
sizeof(
int) * 4>);
525 QVariant(QLineF line)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 4>);
526 QVariant(QRect rect)
noexcept(Private::FitsInInternalSize<
sizeof(
int) * 4>);
527 QVariant(QRectF rect)
noexcept(Private::FitsInInternalSize<
sizeof(qreal) * 4>);
530 QVariant(
const QEasingCurve &easing)
noexcept(
false);
531 QVariant(QEasingCurve &&easing)
noexcept;
532 QVariant(
const QJsonDocument &jsonDocument)
noexcept(
false);
533 QVariant(QJsonDocument &&jsonDocument)
noexcept;
534 QVariant(
const QPersistentModelIndex &modelIndex)
noexcept(
false);
535 QVariant(QPersistentModelIndex &&modelIndex)
noexcept;
537#ifndef QT_NO_CAST_FROM_ASCII
538 QT_ASCII_CAST_WARN QVariant(
const char *str)
noexcept(
false)
539 : QVariant(QString::fromUtf8(str))
542 QVariant(QLatin1StringView string)
noexcept(
false);
544#if !defined(Q_CC_GHS)
546 template <
typename T,
547 std::enable_if_t<std::disjunction_v<std::is_pointer<T>, std::is_member_pointer<T>>,
bool> =
false>
548 QVariant(T) =
delete;
550 QVariant(
const volatile void *) =
delete;
553#if QT_CORE_REMOVED_SINCE(6
, 5
)
554 QVariant(
const QSize &size);
555 QVariant(
const QSizeF &size);
556 QVariant(
const QPoint &pt);
557 QVariant(
const QPointF &pt);
558 QVariant(
const QLine &line);
559 QVariant(
const QLineF &line);
560 QVariant(
const QRect &rect);
561 QVariant(
const QRectF &rect);
562 QVariant(
const QUuid &uuid);
565 QVariant& operator=(
const QVariant &other);
566 inline QVariant(QVariant &&other)
noexcept : d(other.d)
567 { other.d = Private(); }
568 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QVariant)
570 inline void swap(QVariant &other)
noexcept { std::swap(d, other.d); }
572 int userType()
const {
return typeId(); }
576 const QtPrivate::QMetaTypeInterface *mt = metaType().iface();
579 int id = mt->typeId.loadRelaxed();
584 QT_CORE_INLINE_SINCE(6, 10)
585 const char *typeName()
const;
586 QT_CORE_INLINE_SINCE(6, 10)
587 QMetaType metaType()
const;
589 bool canConvert(QMetaType targetType)
const
590 {
return QMetaType::canConvert(d.type(), targetType); }
591 bool convert(QMetaType type);
593 bool canView(QMetaType targetType)
const
594 {
return QMetaType::canView(d.type(), targetType); }
596#if QT_DEPRECATED_SINCE(6
, 0
)
597 QT_DEPRECATED_VERSION_6_0
598 bool canConvert(
int targetTypeId)
const
599 {
return QMetaType::canConvert(d.type(), QMetaType(targetTypeId)); }
600 QT_DEPRECATED_VERSION_6_0
601 bool convert(
int targetTypeId)
602 {
return convert(QMetaType(targetTypeId)); }
605 inline bool isValid()
const;
611 inline bool isDetached()
const;
613 int toInt(
bool *ok =
nullptr)
const;
614 uint toUInt(
bool *ok =
nullptr)
const;
615 qlonglong toLongLong(
bool *ok =
nullptr)
const;
616 qulonglong toULongLong(
bool *ok =
nullptr)
const;
618 double toDouble(
bool *ok =
nullptr)
const;
619 float toFloat(
bool *ok =
nullptr)
const;
620 qreal toReal(
bool *ok =
nullptr)
const;
621 QByteArray toByteArray()
const;
622 QBitArray toBitArray()
const;
623 QString toString()
const;
624 QStringList toStringList()
const;
625 QChar toChar()
const;
626 QDate toDate()
const;
627 QTime toTime()
const;
628 QDateTime toDateTime()
const;
629 QList<QVariant> toList()
const;
630 QMap<QString, QVariant> toMap()
const;
631 QHash<QString, QVariant> toHash()
const;
633 QPoint toPoint()
const;
634 QPointF toPointF()
const;
635 QRect toRect()
const;
636 QSize toSize()
const;
637 QSizeF toSizeF()
const;
638 QLine toLine()
const;
639 QLineF toLineF()
const;
640 QRectF toRectF()
const;
641 QLocale toLocale()
const;
642#if QT_CONFIG(regularexpression)
643 QRegularExpression toRegularExpression()
const;
645#if QT_CONFIG(easingcurve)
646 QEasingCurve toEasingCurve()
const;
648 QUuid toUuid()
const;
650 QJsonValue toJsonValue()
const;
651 QJsonObject toJsonObject()
const;
652 QJsonArray toJsonArray()
const;
653 QJsonDocument toJsonDocument()
const;
654#if QT_CONFIG(itemmodel)
655 QModelIndex toModelIndex()
const;
656 QPersistentModelIndex toPersistentModelIndex()
const;
659#ifndef QT_NO_DATASTREAM
660 void load(QDataStream &ds);
661 void save(QDataStream &ds)
const;
663#if QT_DEPRECATED_SINCE(6
, 0
)
665 QT_WARNING_DISABLE_DEPRECATED
666 QT_DEPRECATED_VERSION_X_6_0(
"Use the constructor taking a QMetaType instead.")
667 explicit QVariant(Type type)
668 : QVariant(QMetaType(
int(type)))
670 QT_DEPRECATED_VERSION_X_6_0(
"Use typeId() or metaType().")
673 int type = d.type().rawId();
674 return type >= QMetaType::User ? UserType :
static_cast<Type>(type);
676 QT_DEPRECATED_VERSION_6_0
677 static const char *typeToName(
int typeId)
678 {
return QMetaType(typeId).name(); }
679 QT_DEPRECATED_VERSION_6_0
680 static Type nameToType(
const char *name)
682 int metaType = QMetaType::fromName(name).rawId();
683 return metaType <=
int(UserType) ? QVariant::Type(metaType) : UserType;
689 const void *constData()
const
690 {
return d.storage(); }
691 inline const void *data()
const {
return constData(); }
694 template <
typename T>
695 void verifySuitableForEmplace()
697 static_assert(!std::is_reference_v<T>,
698 "QVariant does not support reference types");
699 static_assert(!std::is_const_v<T>,
700 "QVariant does not support const types");
701 static_assert(std::is_copy_constructible_v<T>,
702 "QVariant requires that the type is copyable");
703 static_assert(std::is_destructible_v<T>,
704 "QVariant requires that the type is destructible");
707 template <
typename T,
typename... Args>
708 T &emplaceImpl(Args&&... args)
710 verifySuitableForEmplace<T>();
711 auto data =
static_cast<T *>(prepareForEmplace(QMetaType::fromType<T>()));
712 return *q20::construct_at(data, std::forward<Args>(args)...);
716 template <
typename T,
typename... Args,
717 if_constructible<T, Args...> =
true>
718 T &emplace(Args&&... args)
720 return emplaceImpl<T>(std::forward<Args>(args)...);
723 template <
typename T,
typename U,
typename... Args,
724 if_constructible<T, std::initializer_list<U> &, Args...> =
true>
725 T &emplace(std::initializer_list<U> list, Args&&... args)
727 return emplaceImpl<T>(list, std::forward<Args>(args)...);
730 template<
typename T,
typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, QVariant>>>
731 void setValue(T &&avalue)
733 using VT = std::decay_t<T>;
734 QMetaType metaType = QMetaType::fromType<VT>();
736 if (isDetached() && d.type() == metaType) {
737 *
reinterpret_cast<VT *>(
const_cast<
void *>(constData())) = std::forward<T>(avalue);
740 *
this = QVariant::fromValue<VT>(std::forward<T>(avalue));
744 void setValue(
const QVariant &avalue)
749 void setValue(QVariant &&avalue)
751 *
this = std::move(avalue);
755 inline T value()
const &
756 {
return qvariant_cast<T>(*
this); }
762 QMetaType::view(metaType(), data(), QMetaType::fromType<T>(), &t);
768 {
return qvariant_cast<T>(std::move(*
this)); }
770 template<
typename T, if_rvalue<T> =
true>
773
774
775 static inline auto fromValue(T &&value)
776 noexcept(std::is_nothrow_copy_constructible_v<T> && Private::CanUseInternalSpace<T>)
777 -> std::enable_if_t<std::conjunction_v<std::is_copy_constructible<T>,
778 std::is_destructible<T>>, QVariant>
780 static inline QVariant fromValue(T &&value)
784 using Type = std::remove_cv_t<T>;
785 if constexpr (std::is_null_pointer_v<Type>)
786 return QVariant::fromMetaType(QMetaType::fromType<std::nullptr_t>());
787 else if constexpr (std::is_same_v<Type, QVariant>)
788 return std::forward<T>(value);
789 else if constexpr (std::is_same_v<Type, std::monostate>)
791 QMetaType mt = QMetaType::fromType<Type>();
796 if constexpr (std::conjunction_v<std::is_move_constructible<Type>, std::negation<std::is_const<T>>>)
797 return moveConstruct(QMetaType::fromType<Type>(), std::addressof(value));
799 return copyConstruct(mt, std::addressof(value));
804 static inline auto fromValue(
const T &value)
805 noexcept(std::is_nothrow_copy_constructible_v<T> && Private::CanUseInternalSpace<T>)
806 -> std::enable_if_t<std::is_copy_constructible_v<T> && std::is_destructible_v<T>, QVariant>
808 static inline QVariant fromValue(
const T &value)
811 if constexpr (std::is_null_pointer_v<T>)
812 return QVariant(QMetaType::fromType<std::nullptr_t>());
813 else if constexpr (std::is_same_v<T, QVariant>)
815 else if constexpr (std::is_same_v<T, std::monostate>)
817 return QVariant(QMetaType::fromType<T>(), std::addressof(value));
820 template<
typename... Types>
821 static inline QVariant fromStdVariant(
const std::variant<Types...> &value)
823 return fromStdVariantImpl(value);
826 template<
typename... Types>
827 static QVariant fromStdVariant(std::variant<Types...> &&value)
829 return fromStdVariantImpl(std::move(value));
832 static QVariant fromMetaType(QMetaType type,
const void *copy =
nullptr);
835 bool canConvert()
const
836 {
return canConvert(QMetaType::fromType<T>()); }
840 {
return canView(QMetaType::fromType<T>()); }
842 static QPartialOrdering compare(
const QVariant &lhs,
const QVariant &rhs);
845 template <
typename StdVariant>
846 static QVariant fromStdVariantImpl(StdVariant &&v)
848 if (Q_UNLIKELY(v.valueless_by_exception()))
850 auto visitor = [](
auto &&arg) {
851 return QVariant::fromValue(q23::forward_like<StdVariant>(arg));
853 return std::visit(visitor, std::forward<StdVariant>(v));
856 friend bool comparesEqual(
const QVariant &a,
const QVariant &b)
857 {
return a.equals(b); }
858 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QVariant)
860#ifndef QT_NO_DEBUG_STREAM
861 template <
typename T>
862 friend auto operator<<(
const QDebug &debug,
const T &variant) -> std::enable_if_t<std::is_same_v<T, QVariant>, QDebug> {
863 return variant.qdebugHelper(debug);
865 QDebug qdebugHelper(QDebug)
const;
868 template <
typename T,
typename Variant>
static constexpr
869 bool canGetTypeFromVariant(Variant *v)
noexcept
873 if (std::is_const_v<Variant> && v->d.is_null)
876 using NonConstT = std::remove_const_t<std::remove_pointer_t<T>>;
877 if constexpr (std::is_pointer_v<T> && !std::is_same_v<T, NonConstT *>) {
878 if (v->d.type() == QMetaType::fromType<NonConstT *>())
881 return v->d.type() == QMetaType::fromType<T>();
884 template <
typename T> T *typedData()
886 Q_PRE(canGetTypeFromVariant<T>(
this));
887 return static_cast<T *>(data());
890 template <
typename T>
const T *typedData()
const
892 Q_PRE(canGetTypeFromVariant<T>(
this));
896 template <
typename T>
897 friend T *get_if(QVariant *v)
noexcept
899 if (!canGetTypeFromVariant<T>(v))
901 return v->typedData<T>();
903 template <
typename T>
904 friend const T *get_if(
const QVariant *v)
noexcept
906 if (!canGetTypeFromVariant<T>(v))
908 return v->typedData<
const T>();
911#define Q_MK_GET(CONST, REF)
912 template <typename T> friend CONST T REF get(CONST QVariant REF v)
913 { return static_cast<CONST T REF>(*v.typedData<T>()); }
921 static QVariant moveConstruct(QMetaType type,
void *data);
922 static QVariant copyConstruct(QMetaType type,
const void *data);
925 friend inline T qvariant_cast(
const QVariant &);
927 friend inline T qvariant_cast(QVariant &&);
932#if QT_REMOVAL_QT7_DEPRECATED_SINCE(6
, 16
)
934 QT_DEPRECATED_VERSION_6_16
935 void create(
int type,
const void *copy);
936 QT_DEPRECATED_VERSION_6_16
937 void create(QMetaType type,
const void *copy);
938 QT_DEPRECATED_VERSION_6_16
939 bool convert(
int type,
void *ptr)
const;
940 QT_DEPRECATED_VERSION_6_16
941 bool view(
int type,
void *ptr);
943 bool equals(
const QVariant &other)
const;
947 inline QVariant(
void *) =
delete;
954 QVariant(QMetaType::Type) =
delete;
957 QVariant(std::in_place_t, QMetaType type);
959 void *prepareForEmplace(QMetaType type);
966 QVariant(Qt::GlobalColor) =
delete;
967 QVariant(Qt::BrushStyle) =
delete;
968 QVariant(Qt::PenStyle) =
delete;
969 QVariant(Qt::CursorShape) =
delete;
970#ifdef QT_NO_CAST_FROM_ASCII
972 inline QVariant(
const char *) =
delete;
975 typedef Private DataPtr;
976 inline DataPtr &data_ptr() {
return d; }
977 inline const DataPtr &data_ptr()
const {
return d; }