1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QVARIANT_H
41#define QVARIANT_H
42
43#include <QtCore/qatomic.h>
44#include <QtCore/qbytearray.h>
45#include <QtCore/qlist.h>
46#include <QtCore/qmetatype.h>
47#include <QtCore/qmap.h>
48#include <QtCore/qhash.h>
49#include <QtCore/qstring.h>
50#include <QtCore/qstringlist.h>
51#include <QtCore/qobject.h>
52#ifndef QT_NO_DEBUG_STREAM
53#include <QtCore/qdebug.h>
54#endif
55#ifndef QT_BOOTSTRAPPED
56#include <QtCore/qbytearraylist.h>
57#endif
58#include <memory>
59#include <type_traits>
60
61#if __has_include(<variant>) && __cplusplus >= 201703L
62#include <variant>
63#elif defined(Q_CLANG_QDOC)
64namespace std { template<typename...> struct variant; }
65#endif
66
67QT_BEGIN_NAMESPACE
68
69
70class QBitArray;
71class QDataStream;
72class QDate;
73class QDateTime;
74#if QT_CONFIG(easingcurve)
75class QEasingCurve;
76#endif
77class QLine;
78class QLineF;
79class QLocale;
80class QTransform;
81class QTime;
82class QPoint;
83class QPointF;
84class QSize;
85class QSizeF;
86class QRect;
87class QRectF;
88#if QT_CONFIG(regularexpression)
89class QRegularExpression;
90#endif // QT_CONFIG(regularexpression)
91class QTextFormat;
92class QTextLength;
93class QUrl;
94class QVariant;
95
96template<typename T>
97inline T qvariant_cast(const QVariant &);
98
99class Q_CORE_EXPORT QVariant
100{
101 public:
102#if QT_DEPRECATED_SINCE(6, 0)
103 enum QT_DEPRECATED_VERSION_X_6_0("Use QMetaType::Type instead.") Type
104 {
105 Invalid = QMetaType::UnknownType,
106 Bool = QMetaType::Bool,
107 Int = QMetaType::Int,
108 UInt = QMetaType::UInt,
109 LongLong = QMetaType::LongLong,
110 ULongLong = QMetaType::ULongLong,
111 Double = QMetaType::Double,
112 Char = QMetaType::QChar,
113 Map = QMetaType::QVariantMap,
114 List = QMetaType::QVariantList,
115 String = QMetaType::QString,
116 StringList = QMetaType::QStringList,
117 ByteArray = QMetaType::QByteArray,
118 BitArray = QMetaType::QBitArray,
119 Date = QMetaType::QDate,
120 Time = QMetaType::QTime,
121 DateTime = QMetaType::QDateTime,
122 Url = QMetaType::QUrl,
123 Locale = QMetaType::QLocale,
124 Rect = QMetaType::QRect,
125 RectF = QMetaType::QRectF,
126 Size = QMetaType::QSize,
127 SizeF = QMetaType::QSizeF,
128 Line = QMetaType::QLine,
129 LineF = QMetaType::QLineF,
130 Point = QMetaType::QPoint,
131 PointF = QMetaType::QPointF,
132#if QT_CONFIG(regularexpression)
133 RegularExpression = QMetaType::QRegularExpression,
134#endif
135 Hash = QMetaType::QVariantHash,
136#if QT_CONFIG(easingcurve)
137 EasingCurve = QMetaType::QEasingCurve,
138#endif
139 Uuid = QMetaType::QUuid,
140#if QT_CONFIG(itemmodel)
141 ModelIndex = QMetaType::QModelIndex,
142 PersistentModelIndex = QMetaType::QPersistentModelIndex,
143#endif
144 LastCoreType = QMetaType::LastCoreType,
145
146 Font = QMetaType::QFont,
147 Pixmap = QMetaType::QPixmap,
148 Brush = QMetaType::QBrush,
149 Color = QMetaType::QColor,
150 Palette = QMetaType::QPalette,
151 Image = QMetaType::QImage,
152 Polygon = QMetaType::QPolygon,
153 Region = QMetaType::QRegion,
154 Bitmap = QMetaType::QBitmap,
155 Cursor = QMetaType::QCursor,
156#if QT_CONFIG(shortcut)
157 KeySequence = QMetaType::QKeySequence,
158#endif
159 Pen = QMetaType::QPen,
160 TextLength = QMetaType::QTextLength,
161 TextFormat = QMetaType::QTextFormat,
162 Transform = QMetaType::QTransform,
163 Matrix4x4 = QMetaType::QMatrix4x4,
164 Vector2D = QMetaType::QVector2D,
165 Vector3D = QMetaType::QVector3D,
166 Vector4D = QMetaType::QVector4D,
167 Quaternion = QMetaType::QQuaternion,
168 PolygonF = QMetaType::QPolygonF,
169 Icon = QMetaType::QIcon,
170 LastGuiType = QMetaType::LastGuiType,
171
172 SizePolicy = QMetaType::QSizePolicy,
173
174 UserType = QMetaType::User,
175 LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
176 };
177#endif
178 QVariant() noexcept : d() {}
179 ~QVariant();
180 explicit QVariant(QMetaType type, const void *copy = nullptr);
181 QVariant(const QVariant &other);
182
183 QVariant(int i);
184 QVariant(uint ui);
185 QVariant(qlonglong ll);
186 QVariant(qulonglong ull);
187 QVariant(bool b);
188 QVariant(double d);
189 QVariant(float f);
190#ifndef QT_NO_CAST_FROM_ASCII
191 QT_ASCII_CAST_WARN QVariant(const char *str)
192 : QVariant(QString::fromUtf8(str))
193 {}
194#endif
195
196 QVariant(const QByteArray &bytearray);
197 QVariant(const QBitArray &bitarray);
198 QVariant(const QString &string);
199 QVariant(QLatin1String string);
200 QVariant(const QStringList &stringlist);
201 QVariant(QChar qchar);
202 QVariant(QDate date);
203 QVariant(QTime time);
204 QVariant(const QDateTime &datetime);
205 QVariant(const QList<QVariant> &list);
206 QVariant(const QMap<QString, QVariant> &map);
207 QVariant(const QHash<QString, QVariant> &hash);
208#ifndef QT_NO_GEOM_VARIANT
209 QVariant(const QSize &size);
210 QVariant(const QSizeF &size);
211 QVariant(const QPoint &pt);
212 QVariant(const QPointF &pt);
213 QVariant(const QLine &line);
214 QVariant(const QLineF &line);
215 QVariant(const QRect &rect);
216 QVariant(const QRectF &rect);
217#endif
218 QVariant(const QLocale &locale);
219#if QT_CONFIG(regularexpression)
220 QVariant(const QRegularExpression &re);
221#endif // QT_CONFIG(regularexpression)
222#if QT_CONFIG(easingcurve)
223 QVariant(const QEasingCurve &easing);
224#endif
225 QVariant(const QUuid &uuid);
226#ifndef QT_BOOTSTRAPPED
227 QVariant(const QUrl &url);
228 QVariant(const QJsonValue &jsonValue);
229 QVariant(const QJsonObject &jsonObject);
230 QVariant(const QJsonArray &jsonArray);
231 QVariant(const QJsonDocument &jsonDocument);
232#endif // QT_BOOTSTRAPPED
233#if QT_CONFIG(itemmodel)
234 QVariant(const QModelIndex &modelIndex);
235 QVariant(const QPersistentModelIndex &modelIndex);
236#endif
237
238 QVariant& operator=(const QVariant &other);
239 inline QVariant(QVariant &&other) noexcept : d(other.d)
240 { other.d = Private(); }
241 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QVariant)
242
243 inline void swap(QVariant &other) noexcept { qSwap(d, other.d); }
244
245 int userType() const { return typeId(); }
246 int typeId() const { return metaType().id(); }
247
248 const char *typeName() const;
249 QMetaType metaType() const;
250
251 bool canConvert(QMetaType targetType) const
252 { return QMetaType::canConvert(d.type(), targetType); }
253 bool convert(QMetaType type);
254
255 bool canView(QMetaType targetType) const
256 { return QMetaType::canView(d.type(), targetType); }
257
258#if QT_DEPRECATED_SINCE(6, 0)
259 QT_DEPRECATED_VERSION_6_0
260 bool canConvert(int targetTypeId) const
261 { return QMetaType::canConvert(d.type(), QMetaType(targetTypeId)); }
262 QT_DEPRECATED_VERSION_6_0
263 bool convert(int targetTypeId)
264 { return convert(QMetaType(targetTypeId)); }
265#endif
266
267 inline bool isValid() const;
268 bool isNull() const;
269
270 void clear();
271
272 void detach();
273 inline bool isDetached() const;
274
275 int toInt(bool *ok = nullptr) const;
276 uint toUInt(bool *ok = nullptr) const;
277 qlonglong toLongLong(bool *ok = nullptr) const;
278 qulonglong toULongLong(bool *ok = nullptr) const;
279 bool toBool() const;
280 double toDouble(bool *ok = nullptr) const;
281 float toFloat(bool *ok = nullptr) const;
282 qreal toReal(bool *ok = nullptr) const;
283 QByteArray toByteArray() const;
284 QBitArray toBitArray() const;
285 QString toString() const;
286 QStringList toStringList() const;
287 QChar toChar() const;
288 QDate toDate() const;
289 QTime toTime() const;
290 QDateTime toDateTime() const;
291 QList<QVariant> toList() const;
292 QMap<QString, QVariant> toMap() const;
293 QHash<QString, QVariant> toHash() const;
294
295#ifndef QT_NO_GEOM_VARIANT
296 QPoint toPoint() const;
297 QPointF toPointF() const;
298 QRect toRect() const;
299 QSize toSize() const;
300 QSizeF toSizeF() const;
301 QLine toLine() const;
302 QLineF toLineF() const;
303 QRectF toRectF() const;
304#endif
305 QLocale toLocale() const;
306#if QT_CONFIG(regularexpression)
307 QRegularExpression toRegularExpression() const;
308#endif // QT_CONFIG(regularexpression)
309#if QT_CONFIG(easingcurve)
310 QEasingCurve toEasingCurve() const;
311#endif
312 QUuid toUuid() const;
313#ifndef QT_BOOTSTRAPPED
314 QUrl toUrl() const;
315 QJsonValue toJsonValue() const;
316 QJsonObject toJsonObject() const;
317 QJsonArray toJsonArray() const;
318 QJsonDocument toJsonDocument() const;
319#endif // QT_BOOTSTRAPPED
320#if QT_CONFIG(itemmodel)
321 QModelIndex toModelIndex() const;
322 QPersistentModelIndex toPersistentModelIndex() const;
323#endif
324
325#ifndef QT_NO_DATASTREAM
326 void load(QDataStream &ds);
327 void save(QDataStream &ds) const;
328#endif
329#if QT_DEPRECATED_SINCE(6, 0)
330 QT_WARNING_PUSH
331 QT_WARNING_DISABLE_DEPRECATED
332 QT_DEPRECATED_VERSION_X_6_0("Use the constructor taking a QMetaType instead.")
333 explicit QVariant(Type type)
334 : QVariant(QMetaType(int(type)))
335 {}
336 QT_DEPRECATED_VERSION_X_6_0("Use typeId() or metaType().")
337 Type type() const
338 {
339 int type = d.typeId();
340 return type >= QMetaType::User ? UserType : static_cast<Type>(type);
341 }
342 QT_DEPRECATED_VERSION_6_0
343 static const char *typeToName(int typeId)
344 { return QMetaType(typeId).name(); }
345 QT_DEPRECATED_VERSION_6_0
346 static Type nameToType(const char *name)
347 {
348 int metaType = QMetaType::fromName(name).id();
349 return metaType <= int(UserType) ? QVariant::Type(metaType) : UserType;
350 }
351 QT_WARNING_POP
352#endif
353
354 void *data();
355 const void *constData() const
356 { return d.storage(); }
357 inline const void *data() const { return constData(); }
358
359 template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, QVariant>>>
360 void setValue(T &&avalue)
361 {
362 using VT = std::decay_t<T>;
363 QMetaType metaType = QMetaType::fromType<VT>();
364 // If possible we reuse the current QVariant private.
365 if (isDetached() && d.type() == metaType) {
366 *reinterpret_cast<VT *>(const_cast<void *>(constData())) = std::forward<T>(avalue);
367 } else {
368 *this = QVariant::fromValue<VT>(std::forward<T>(avalue));
369 }
370 }
371
372 void setValue(const QVariant &avalue)
373 {
374 *this = avalue;
375 }
376
377 void setValue(QVariant &&avalue)
378 {
379 *this = std::move(avalue);
380 }
381
382 template<typename T>
383 inline T value() const
384 { return qvariant_cast<T>(*this); }
385
386 template<typename T>
387 inline T view()
388 {
389 T t{};
390 QMetaType::view(metaType(), data(), QMetaType::fromType<T>(), &t);
391 return t;
392 }
393
394 template<typename T>
395#ifndef Q_CLANG_QDOC
396 static inline auto fromValue(const T &value) ->
397 std::enable_if_t<std::is_copy_constructible_v<T>, QVariant>
398#else
399 static inline QVariant fromValue(const T &value)
400#endif
401 {
402 return QVariant(QMetaType::fromType<T>(), std::addressof(value));
403 }
404
405#if (__has_include(<variant>) && __cplusplus >= 201703L) || defined(Q_CLANG_QDOC)
406 template<typename... Types>
407 static inline QVariant fromStdVariant(const std::variant<Types...> &value)
408 {
409 if (value.valueless_by_exception())
410 return QVariant();
411 return std::visit([](const auto &arg) { return fromValue(arg); }, value);
412 }
413#endif
414
415 template<typename T>
416 bool canConvert() const
417 { return canConvert(QMetaType::fromType<T>()); }
418
419 template<typename T>
420 bool canView() const
421 { return canView(QMetaType::fromType<T>()); }
422
423public:
424 struct PrivateShared
425 {
426 private:
427 inline PrivateShared() : ref(1) { }
428 public:
429 static PrivateShared *create(const QtPrivate::QMetaTypeInterface *type)
430 {
431 Q_ASSERT(type);
432 size_t size = type->size;
433 size_t align = type->alignment;
434
435 size += sizeof(PrivateShared);
436 if (align > sizeof(PrivateShared)) {
437 // The alignment is larger than the alignment we can guarantee for the pointer
438 // directly following PrivateShared, so we need to allocate some additional
439 // memory to be able to fit the object into the available memory with suitable
440 // alignment.
441 size += align - sizeof(PrivateShared);
442 }
443 void *data = operator new(size);
444 auto *ps = new (data) QVariant::PrivateShared();
445 ps->offset = int(((quintptr(ps) + sizeof(PrivateShared) + align - 1) & ~(align - 1)) - quintptr(ps));
446 return ps;
447 }
448 static void free(PrivateShared *p)
449 {
450 p->~PrivateShared();
451 operator delete(p);
452 }
453
454 alignas(8) QAtomicInt ref;
455 int offset;
456
457 const void *data() const
458 { return reinterpret_cast<const unsigned char *>(this) + offset; }
459 void *data()
460 { return reinterpret_cast<unsigned char *>(this) + offset; }
461 };
462 struct Private
463 {
464 static constexpr size_t MaxInternalSize = 3*sizeof(void *);
465 template<typename T>
466 static constexpr bool CanUseInternalSpace = (QTypeInfo<T>::isRelocatable && sizeof(T) <= MaxInternalSize && alignof(T) <= alignof(double));
467 static constexpr bool canUseInternalSpace(QtPrivate::QMetaTypeInterface *type)
468 {
469 Q_ASSERT(type);
470 return QMetaType::TypeFlags(type->flags) & QMetaType::RelocatableType &&
471 size_t(type->size) <= MaxInternalSize && size_t(type->alignment) <= alignof(double);
472 }
473
474 union
475 {
476 uchar data[MaxInternalSize] = {};
477 PrivateShared *shared;
478 double _forAlignment; // we want an 8byte alignment on 32bit systems as well
479 } data;
480 quintptr is_shared : 1;
481 quintptr is_null : 1;
482 quintptr packedType : sizeof(QMetaType) * 8 - 2;
483
484 Private() noexcept : is_shared(false), is_null(true), packedType(0) {}
485 explicit Private(QMetaType type) noexcept : is_shared(false), is_null(false)
486 {
487 quintptr mt = quintptr(type.d_ptr);
488 Q_ASSERT((mt & 0x3) == 0);
489 packedType = mt >> 2;
490 }
491 explicit Private(int type) noexcept : Private(QMetaType(type)) {}
492
493 const void *storage() const
494 { return is_shared ? data.shared->data() : &data.data; }
495
496 const void *internalStorage() const
497 { Q_ASSERT(is_shared); return &data.data; }
498
499 // determine internal storage at compile time
500 template<typename T>
501 const T &get() const
502 { return *static_cast<const T *>(storage()); }
503 template<typename T>
504 void set(const T &t)
505 { *static_cast<T *>(CanUseInternalSpace<T> ? &data.data : data.shared->data()) = t; }
506
507 inline QMetaType type() const
508 {
509 return QMetaType(reinterpret_cast<QtPrivate::QMetaTypeInterface *>(packedType << 2));
510 }
511
512 inline QtPrivate::QMetaTypeInterface * typeInterface() const
513 {
514 return reinterpret_cast<QtPrivate::QMetaTypeInterface *>(packedType << 2);
515 }
516
517 inline int typeId() const
518 {
519 return type().id();
520 }
521 };
522 public:
523 static QPartialOrdering compare(const QVariant &lhs, const QVariant &rhs);
524
525private:
526 friend inline bool operator==(const QVariant &a, const QVariant &b)
527 { return a.equals(b); }
528 friend inline bool operator!=(const QVariant &a, const QVariant &b)
529 { return !a.equals(b); }
530#ifndef QT_NO_DEBUG_STREAM
531 template <typename T>
532 friend auto operator<<(const QDebug &debug, const T &variant) -> std::enable_if_t<std::is_same_v<T, QVariant>, QDebug> {
533 return variant.qdebugHelper(debug);
534 }
535 QDebug qdebugHelper(QDebug) const;
536#endif
537 template<typename T>
538 friend inline T qvariant_cast(const QVariant &);
539protected:
540 Private d;
541 void create(int type, const void *copy);
542 void create(QMetaType type, const void *copy);
543 bool equals(const QVariant &other) const;
544 bool convert(int type, void *ptr) const;
545 bool view(int type, void *ptr);
546
547private:
548 // force compile error, prevent QVariant(bool) to be called
549 inline QVariant(void *) = delete;
550 // QVariant::Type is marked as \obsolete, but we don't want to
551 // provide a constructor from its intended replacement,
552 // QMetaType::Type, instead, because the idea behind these
553 // constructors is flawed in the first place. But we also don't
554 // want QVariant(QMetaType::String) to compile and falsely be an
555 // int variant, so delete this constructor:
556 QVariant(QMetaType::Type) = delete;
557
558 // These constructors don't create QVariants of the type associcated
559 // with the enum, as expected, but they would create a QVariant of
560 // type int with the value of the enum value.
561 // Use QVariant v = QColor(Qt::red) instead of QVariant v = Qt::red for
562 // example.
563 QVariant(Qt::GlobalColor) = delete;
564 QVariant(Qt::BrushStyle) = delete;
565 QVariant(Qt::PenStyle) = delete;
566 QVariant(Qt::CursorShape) = delete;
567#ifdef QT_NO_CAST_FROM_ASCII
568 // force compile error when implicit conversion is not wanted
569 inline QVariant(const char *) = delete;
570#endif
571public:
572 typedef Private DataPtr;
573 inline DataPtr &data_ptr() { return d; }
574 inline const DataPtr &data_ptr() const { return d; }
575};
576
577template<>
578inline QVariant QVariant::fromValue(const QVariant &value)
579{
580 return value;
581}
582
583#if __has_include(<variant>) && __cplusplus >= 201703L
584template<>
585inline QVariant QVariant::fromValue(const std::monostate &)
586{
587 return QVariant();
588}
589#endif
590
591inline bool QVariant::isValid() const
592{
593 return d.type().isValid();
594}
595
596#ifndef QT_NO_DATASTREAM
597Q_CORE_EXPORT QDataStream &operator>>(QDataStream &s, QVariant &p);
598Q_CORE_EXPORT QDataStream &operator<<(QDataStream &s, const QVariant &p);
599
600#if QT_DEPRECATED_SINCE(6, 0)
601QT_WARNING_PUSH
602QT_WARNING_DISABLE_DEPRECATED
603QT_DEPRECATED_VERSION_6_0
604inline QDataStream &operator>>(QDataStream &s, QVariant::Type &p)
605{
606 quint32 u;
607 s >> u;
608 p = static_cast<QVariant::Type>(u);
609 return s;
610}
611QT_DEPRECATED_VERSION_6_0
612inline QDataStream &operator<<(QDataStream &s, const QVariant::Type p)
613{
614 s << static_cast<quint32>(p);
615 return s;
616}
617QT_WARNING_POP
618#endif
619
620#endif
621
622inline bool QVariant::isDetached() const
623{ return !d.is_shared || d.data.shared->ref.loadRelaxed() == 1; }
624
625Q_DECLARE_SHARED(QVariant)
626
627#ifndef QT_MOC
628
629template<typename T> inline T qvariant_cast(const QVariant &v)
630{
631 QMetaType targetType = QMetaType::fromType<T>();
632 if (v.d.type() == targetType)
633 return v.d.get<T>();
634 if constexpr (std::is_same_v<T,std::remove_const_t<std::remove_pointer_t<T>> const *>) {
635 using nonConstT = std::remove_const_t<std::remove_pointer_t<T>> *;
636 QMetaType nonConstTargetType = QMetaType::fromType<nonConstT>();
637 if (v.d.type() == nonConstTargetType)
638 return v.d.get<nonConstT>();
639 }
640
641 T t{};
642 QMetaType::convert(v.metaType(), v.constData(), targetType, &t);
643 return t;
644}
645
646template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
647{
648 if (v.metaType().id() == QMetaType::QVariant)
649 return *reinterpret_cast<const QVariant *>(v.constData());
650 return v;
651}
652
653#endif
654
655#ifndef QT_NO_DEBUG_STREAM
656#if QT_DEPRECATED_SINCE(6, 0)
657QT_WARNING_PUSH
658QT_WARNING_DISABLE_DEPRECATED
659QT_DEPRECATED_VERSION_6_0
660Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant::Type);
661QT_WARNING_POP
662#endif
663#endif
664
665namespace QtPrivate {
666class Q_CORE_EXPORT QVariantTypeCoercer
667{
668public:
669 const void *convert(const QVariant &value, const QMetaType &type);
670 const void *coerce(const QVariant &value, const QMetaType &type);
671
672private:
673 QVariant converted;
674};
675}
676
677template<typename Pointer>
678class QVariantRef
679{
680private:
681 const Pointer *m_pointer = nullptr;
682
683public:
684 explicit QVariantRef(const Pointer *reference) : m_pointer(reference) {}
685 QVariantRef(const QVariantRef &) = default;
686 QVariantRef(QVariantRef &&) = default;
687 ~QVariantRef() = default;
688
689 operator QVariant() const;
690 QVariantRef &operator=(const QVariant &value);
691 QVariantRef &operator=(const QVariantRef &value) { return operator=(QVariant(value)); }
692 QVariantRef &operator=(QVariantRef &&value) { return operator=(QVariant(value)); }
693
694 friend void swap(QVariantRef a, QVariantRef b)
695 {
696 QVariant tmp = a;
697 a = b;
698 b = std::move(tmp);
699 }
700};
701
702class Q_CORE_EXPORT QVariantConstPointer
703{
704private:
705 QVariant m_variant;
706
707public:
708 explicit QVariantConstPointer(QVariant variant);
709
710 QVariant operator*() const;
711 const QVariant *operator->() const;
712};
713
714template<typename Pointer>
715class QVariantPointer
716{
717private:
718 const Pointer *m_pointer = nullptr;
719
720public:
721 explicit QVariantPointer(const Pointer *pointer) : m_pointer(pointer) {}
722 QVariantRef<Pointer> operator*() const { return QVariantRef<Pointer>(m_pointer); }
723 Pointer operator->() const { return *m_pointer; }
724};
725
726QT_END_NAMESPACE
727
728#endif // QVARIANT_H
729