1/****************************************************************************
2**
3** Copyright (C) 2016 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_BOOTSTRAPPED
53#include <QtCore/qbytearraylist.h>
54#endif
55
56#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
57#include <variant>
58#elif defined(Q_CLANG_QDOC)
59namespace std { template<typename...> struct variant; }
60#endif
61
62QT_BEGIN_NAMESPACE
63
64
65class QBitArray;
66class QDataStream;
67class QDate;
68class QDateTime;
69class QEasingCurve;
70class QLine;
71class QLineF;
72class QLocale;
73class QMatrix;
74class QTransform;
75class QStringList;
76class QTime;
77class QPoint;
78class QPointF;
79class QSize;
80class QSizeF;
81class QRect;
82class QRectF;
83#ifndef QT_NO_REGEXP
84class QRegExp;
85#endif // QT_NO_REGEXP
86#if QT_CONFIG(regularexpression)
87class QRegularExpression;
88#endif // QT_CONFIG(regularexpression)
89class QTextFormat;
90class QTextLength;
91class QUrl;
92class QVariant;
93class QVariantComparisonHelper;
94
95template<typename T>
96inline T qvariant_cast(const QVariant &);
97
98namespace QtPrivate {
99
100 template <typename Derived, typename Argument, typename ReturnType>
101 struct ObjectInvoker
102 {
103 static ReturnType invoke(Argument a)
104 {
105 return Derived::object(a);
106 }
107 };
108
109 template <typename Derived, typename Argument, typename ReturnType>
110 struct MetaTypeInvoker
111 {
112 static ReturnType invoke(Argument a)
113 {
114 return Derived::metaType(a);
115 }
116 };
117
118 template <typename Derived, typename T, typename Argument, typename ReturnType, bool = IsPointerToTypeDerivedFromQObject<T>::Value>
119 struct TreatAsQObjectBeforeMetaType : ObjectInvoker<Derived, Argument, ReturnType>
120 {
121 };
122
123 template <typename Derived, typename T, typename Argument, typename ReturnType>
124 struct TreatAsQObjectBeforeMetaType<Derived, T, Argument, ReturnType, false> : MetaTypeInvoker<Derived, Argument, ReturnType>
125 {
126 };
127
128 template<typename T> struct QVariantValueHelper;
129}
130
131class Q_CORE_EXPORT QVariant
132{
133 public:
134 enum Type {
135 Invalid = QMetaType::UnknownType,
136 Bool = QMetaType::Bool,
137 Int = QMetaType::Int,
138 UInt = QMetaType::UInt,
139 LongLong = QMetaType::LongLong,
140 ULongLong = QMetaType::ULongLong,
141 Double = QMetaType::Double,
142 Char = QMetaType::QChar,
143 Map = QMetaType::QVariantMap,
144 List = QMetaType::QVariantList,
145 String = QMetaType::QString,
146 StringList = QMetaType::QStringList,
147 ByteArray = QMetaType::QByteArray,
148 BitArray = QMetaType::QBitArray,
149 Date = QMetaType::QDate,
150 Time = QMetaType::QTime,
151 DateTime = QMetaType::QDateTime,
152 Url = QMetaType::QUrl,
153 Locale = QMetaType::QLocale,
154 Rect = QMetaType::QRect,
155 RectF = QMetaType::QRectF,
156 Size = QMetaType::QSize,
157 SizeF = QMetaType::QSizeF,
158 Line = QMetaType::QLine,
159 LineF = QMetaType::QLineF,
160 Point = QMetaType::QPoint,
161 PointF = QMetaType::QPointF,
162 RegExp = QMetaType::QRegExp,
163 RegularExpression = QMetaType::QRegularExpression,
164 Hash = QMetaType::QVariantHash,
165 EasingCurve = QMetaType::QEasingCurve,
166 Uuid = QMetaType::QUuid,
167#if QT_CONFIG(itemmodel)
168 ModelIndex = QMetaType::QModelIndex,
169 PersistentModelIndex = QMetaType::QPersistentModelIndex,
170#endif
171 LastCoreType = QMetaType::LastCoreType,
172
173 Font = QMetaType::QFont,
174 Pixmap = QMetaType::QPixmap,
175 Brush = QMetaType::QBrush,
176 Color = QMetaType::QColor,
177 Palette = QMetaType::QPalette,
178 Image = QMetaType::QImage,
179 Polygon = QMetaType::QPolygon,
180 Region = QMetaType::QRegion,
181 Bitmap = QMetaType::QBitmap,
182 Cursor = QMetaType::QCursor,
183 KeySequence = QMetaType::QKeySequence,
184 Pen = QMetaType::QPen,
185 TextLength = QMetaType::QTextLength,
186 TextFormat = QMetaType::QTextFormat,
187 Matrix = QMetaType::QMatrix,
188 Transform = QMetaType::QTransform,
189 Matrix4x4 = QMetaType::QMatrix4x4,
190 Vector2D = QMetaType::QVector2D,
191 Vector3D = QMetaType::QVector3D,
192 Vector4D = QMetaType::QVector4D,
193 Quaternion = QMetaType::QQuaternion,
194 PolygonF = QMetaType::QPolygonF,
195 Icon = QMetaType::QIcon,
196 LastGuiType = QMetaType::LastGuiType,
197
198 SizePolicy = QMetaType::QSizePolicy,
199
200 UserType = QMetaType::User,
201 LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
202 };
203
204 QVariant() noexcept : d() {}
205 ~QVariant();
206 QVariant(Type type);
207 QVariant(int typeId, const void *copy);
208 QVariant(int typeId, const void *copy, uint flags);
209 QVariant(const QVariant &other);
210
211#ifndef QT_NO_DATASTREAM
212 QVariant(QDataStream &s);
213#endif
214
215 QVariant(int i);
216 QVariant(uint ui);
217 QVariant(qlonglong ll);
218 QVariant(qulonglong ull);
219 QVariant(bool b);
220 QVariant(double d);
221 QVariant(float f);
222#ifndef QT_NO_CAST_FROM_ASCII
223 QT_ASCII_CAST_WARN QVariant(const char *str);
224#endif
225
226 QVariant(const QByteArray &bytearray);
227 QVariant(const QBitArray &bitarray);
228 QVariant(const QString &string);
229 QVariant(QLatin1String string);
230 QVariant(const QStringList &stringlist);
231 QVariant(QChar qchar);
232 QVariant(const QDate &date);
233 QVariant(const QTime &time);
234 QVariant(const QDateTime &datetime);
235 QVariant(const QList<QVariant> &list);
236 QVariant(const QMap<QString,QVariant> &map);
237 QVariant(const QHash<QString,QVariant> &hash);
238#ifndef QT_NO_GEOM_VARIANT
239 QVariant(const QSize &size);
240 QVariant(const QSizeF &size);
241 QVariant(const QPoint &pt);
242 QVariant(const QPointF &pt);
243 QVariant(const QLine &line);
244 QVariant(const QLineF &line);
245 QVariant(const QRect &rect);
246 QVariant(const QRectF &rect);
247#endif
248 QVariant(const QLocale &locale);
249#ifndef QT_NO_REGEXP
250 QVariant(const QRegExp &regExp);
251#endif // QT_NO_REGEXP
252#if QT_CONFIG(regularexpression)
253 QVariant(const QRegularExpression &re);
254#endif // QT_CONFIG(regularexpression)
255#ifndef QT_BOOTSTRAPPED
256 QVariant(const QUrl &url);
257 QVariant(const QEasingCurve &easing);
258 QVariant(const QUuid &uuid);
259 QVariant(const QJsonValue &jsonValue);
260 QVariant(const QJsonObject &jsonObject);
261 QVariant(const QJsonArray &jsonArray);
262 QVariant(const QJsonDocument &jsonDocument);
263#endif // QT_BOOTSTRAPPED
264#if QT_CONFIG(itemmodel)
265 QVariant(const QModelIndex &modelIndex);
266 QVariant(const QPersistentModelIndex &modelIndex);
267#endif
268
269 QVariant& operator=(const QVariant &other);
270 inline QVariant(QVariant &&other) noexcept : d(other.d)
271 { other.d = Private(); }
272 inline QVariant &operator=(QVariant &&other) noexcept
273 { qSwap(d, other.d); return *this; }
274
275 inline void swap(QVariant &other) noexcept { qSwap(d, other.d); }
276
277 Type type() const;
278 int userType() const;
279 const char *typeName() const;
280
281 bool canConvert(int targetTypeId) const;
282 bool convert(int targetTypeId);
283
284 inline bool isValid() const;
285 bool isNull() const;
286
287 void clear();
288
289 void detach();
290 inline bool isDetached() const;
291
292 int toInt(bool *ok = nullptr) const;
293 uint toUInt(bool *ok = nullptr) const;
294 qlonglong toLongLong(bool *ok = nullptr) const;
295 qulonglong toULongLong(bool *ok = nullptr) const;
296 bool toBool() const;
297 double toDouble(bool *ok = nullptr) const;
298 float toFloat(bool *ok = nullptr) const;
299 qreal toReal(bool *ok = nullptr) const;
300 QByteArray toByteArray() const;
301 QBitArray toBitArray() const;
302 QString toString() const;
303 QStringList toStringList() const;
304 QChar toChar() const;
305 QDate toDate() const;
306 QTime toTime() const;
307 QDateTime toDateTime() const;
308 QList<QVariant> toList() const;
309 QMap<QString, QVariant> toMap() const;
310 QHash<QString, QVariant> toHash() const;
311
312#ifndef QT_NO_GEOM_VARIANT
313 QPoint toPoint() const;
314 QPointF toPointF() const;
315 QRect toRect() const;
316 QSize toSize() const;
317 QSizeF toSizeF() const;
318 QLine toLine() const;
319 QLineF toLineF() const;
320 QRectF toRectF() const;
321#endif
322 QLocale toLocale() const;
323#ifndef QT_NO_REGEXP
324 QRegExp toRegExp() const;
325#endif // QT_NO_REGEXP
326#if QT_CONFIG(regularexpression)
327 QRegularExpression toRegularExpression() const;
328#endif // QT_CONFIG(regularexpression)
329#ifndef QT_BOOTSTRAPPED
330 QUrl toUrl() const;
331 QEasingCurve toEasingCurve() const;
332 QUuid toUuid() const;
333 QJsonValue toJsonValue() const;
334 QJsonObject toJsonObject() const;
335 QJsonArray toJsonArray() const;
336 QJsonDocument toJsonDocument() const;
337#endif // QT_BOOTSTRAPPED
338#if QT_CONFIG(itemmodel)
339 QModelIndex toModelIndex() const;
340 QPersistentModelIndex toPersistentModelIndex() const;
341#endif
342
343#ifndef QT_NO_DATASTREAM
344 void load(QDataStream &ds);
345 void save(QDataStream &ds) const;
346#endif
347 static const char *typeToName(int typeId);
348 static Type nameToType(const char *name);
349
350 void *data();
351 const void *constData() const;
352 inline const void *data() const { return constData(); }
353
354 template<typename T>
355 inline void setValue(const T &value);
356
357 template<typename T>
358 inline T value() const
359 { return qvariant_cast<T>(*this); }
360
361 template<typename T>
362 static inline QVariant fromValue(const T &value)
363 { return QVariant(qMetaTypeId<T>(), &value, QTypeInfo<T>::isPointer); }
364
365#if (QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L) || defined(Q_CLANG_QDOC)
366 template<typename... Types>
367 static inline QVariant fromStdVariant(const std::variant<Types...> &value)
368 {
369 if (value.valueless_by_exception())
370 return QVariant();
371 return std::visit([](const auto &arg) { return fromValue(arg); }, value);
372 }
373#endif
374
375 template<typename T>
376 bool canConvert() const
377 { return canConvert(qMetaTypeId<T>()); }
378
379 public:
380 struct PrivateShared
381 {
382 inline PrivateShared(void *v) : ptr(v), ref(1) { }
383 void *ptr;
384 QAtomicInt ref;
385 };
386 struct Private
387 {
388 inline Private() noexcept : type(Invalid), is_shared(false), is_null(true)
389 { data.ptr = nullptr; }
390
391 // Internal constructor for initialized variants.
392 explicit inline Private(uint variantType) noexcept
393 : type(variantType), is_shared(false), is_null(false)
394 {}
395
396#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
397 Private(const Private &other) noexcept
398 : data(other.data), type(other.type),
399 is_shared(other.is_shared), is_null(other.is_null)
400 {}
401 Private &operator=(const Private &other) noexcept = default;
402#endif
403 union Data
404 {
405 char c;
406 uchar uc;
407 short s;
408 signed char sc;
409 ushort us;
410 int i;
411 uint u;
412 long l;
413 ulong ul;
414 bool b;
415 double d;
416 float f;
417 qreal real;
418 qlonglong ll;
419 qulonglong ull;
420 QObject *o;
421 void *ptr;
422 PrivateShared *shared;
423 } data;
424 uint type : 30;
425 uint is_shared : 1;
426 uint is_null : 1;
427 };
428 public:
429 typedef void (*f_construct)(Private *, const void *);
430 typedef void (*f_clear)(Private *);
431 typedef bool (*f_null)(const Private *);
432#ifndef QT_NO_DATASTREAM
433 typedef void (*f_load)(Private *, QDataStream &);
434 typedef void (*f_save)(const Private *, QDataStream &);
435#endif
436 typedef bool (*f_compare)(const Private *, const Private *);
437 typedef bool (*f_convert)(const QVariant::Private *d, int t, void *, bool *);
438 typedef bool (*f_canConvert)(const QVariant::Private *d, int t);
439 typedef void (*f_debugStream)(QDebug, const QVariant &);
440 struct Handler {
441 f_construct construct;
442 f_clear clear;
443 f_null isNull;
444#ifndef QT_NO_DATASTREAM
445 f_load load;
446 f_save save;
447#endif
448 f_compare compare;
449 f_convert convert;
450 f_canConvert canConvert;
451 f_debugStream debugStream;
452 };
453
454 inline bool operator==(const QVariant &v) const
455 { return cmp(v); }
456 inline bool operator!=(const QVariant &v) const
457 { return !cmp(v); }
458 inline bool operator<(const QVariant &v) const
459 { return compare(v) < 0; }
460 inline bool operator<=(const QVariant &v) const
461 { return compare(v) <= 0; }
462 inline bool operator>(const QVariant &v) const
463 { return compare(v) > 0; }
464 inline bool operator>=(const QVariant &v) const
465 { return compare(v) >= 0; }
466
467protected:
468 friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
469#ifndef QT_NO_DEBUG_STREAM
470 friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
471#endif
472// ### Qt6: FIXME: Remove the special Q_CC_MSVC handling, it was introduced to maintain BC for QTBUG-41810 .
473#if !defined(Q_NO_TEMPLATE_FRIENDS) && !defined(Q_CC_MSVC)
474 template<typename T>
475 friend inline T qvariant_cast(const QVariant &);
476 template<typename T> friend struct QtPrivate::QVariantValueHelper;
477protected:
478#else
479public:
480#endif
481 Private d;
482 void create(int type, const void *copy);
483 bool cmp(const QVariant &other) const;
484 int compare(const QVariant &other) const;
485 bool convert(const int t, void *ptr) const; // ### Qt6: drop const
486
487private:
488 // force compile error, prevent QVariant(bool) to be called
489 inline QVariant(void *) = delete;
490 // QVariant::Type is marked as \obsolete, but we don't want to
491 // provide a constructor from its intended replacement,
492 // QMetaType::Type, instead, because the idea behind these
493 // constructors is flawed in the first place. But we also don't
494 // want QVariant(QMetaType::String) to compile and falsely be an
495 // int variant, so delete this constructor:
496 QVariant(QMetaType::Type) = delete;
497
498 // These constructors don't create QVariants of the type associcated
499 // with the enum, as expected, but they would create a QVariant of
500 // type int with the value of the enum value.
501 // Use QVariant v = QColor(Qt::red) instead of QVariant v = Qt::red for
502 // example.
503 QVariant(Qt::GlobalColor) = delete;
504 QVariant(Qt::BrushStyle) = delete;
505 QVariant(Qt::PenStyle) = delete;
506 QVariant(Qt::CursorShape) = delete;
507#ifdef QT_NO_CAST_FROM_ASCII
508 // force compile error when implicit conversion is not wanted
509 inline QVariant(const char *) = delete;
510#endif
511public:
512 typedef Private DataPtr;
513 inline DataPtr &data_ptr() { return d; }
514 inline const DataPtr &data_ptr() const { return d; }
515};
516
517#if QT_DEPRECATED_SINCE(5, 14)
518template <typename T>
519QT_DEPRECATED_X("Use QVariant::fromValue() instead.")
520inline QVariant qVariantFromValue(const T &t)
521{
522 return QVariant::fromValue(t);
523}
524
525template <typename T>
526QT_DEPRECATED_X("Use QVariant::setValue() instead.")
527inline void qVariantSetValue(QVariant &v, const T &t)
528{
529 v.setValue(t);
530}
531#endif
532
533template<>
534inline QVariant QVariant::fromValue(const QVariant &value)
535{
536 return value;
537}
538
539#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
540template<>
541inline QVariant QVariant::fromValue(const std::monostate &)
542{
543 return QVariant();
544}
545#endif
546
547inline bool QVariant::isValid() const { return d.type != Invalid; }
548
549template<typename T>
550inline void QVariant::setValue(const T &avalue)
551{
552 // If possible we reuse the current QVariant private.
553 const uint type = qMetaTypeId<T>();
554 if (isDetached() && (type == d.type || (type <= uint(QVariant::Char) && d.type <= uint(QVariant::Char)))) {
555 d.type = type;
556 d.is_null = false;
557 T *old = reinterpret_cast<T*>(d.is_shared ? d.data.shared->ptr : &d.data.ptr);
558 if (QTypeInfo<T>::isComplex)
559 old->~T();
560 new (old) T(avalue); // call the copy constructor
561 } else {
562 *this = QVariant(type, &avalue, QTypeInfo<T>::isPointer);
563 }
564}
565
566template<>
567inline void QVariant::setValue(const QVariant &avalue)
568{
569 *this = avalue;
570}
571
572#ifndef QT_NO_DATASTREAM
573Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant& p);
574Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant& p);
575Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant::Type& p);
576Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant::Type p);
577#endif
578
579inline bool QVariant::isDetached() const
580{ return !d.is_shared || d.data.shared->ref.loadRelaxed() == 1; }
581
582
583#ifdef Q_QDOC
584 inline bool operator==(const QVariant &v1, const QVariant &v2);
585 inline bool operator!=(const QVariant &v1, const QVariant &v2);
586#else
587
588/* Helper class to add one more level of indirection to prevent
589 implicit casts.
590*/
591class QVariantComparisonHelper
592{
593public:
594 inline QVariantComparisonHelper(const QVariant &var)
595 : v(&var) {}
596private:
597 friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
598 const QVariant *v;
599};
600
601inline bool operator==(const QVariant &v1, const QVariantComparisonHelper &v2)
602{
603 return v1.cmp(*v2.v);
604}
605
606inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
607{
608 return !operator==(v1, v2);
609}
610#endif
611Q_DECLARE_SHARED(QVariant)
612
613class Q_CORE_EXPORT QSequentialIterable
614{
615 QtMetaTypePrivate::QSequentialIterableImpl m_impl;
616public:
617 struct Q_CORE_EXPORT const_iterator
618 {
619 private:
620 QtMetaTypePrivate::QSequentialIterableImpl m_impl;
621 QAtomicInt *ref;
622 friend class QSequentialIterable;
623 explicit const_iterator(const QSequentialIterable &iter, QAtomicInt *ref_);
624
625 explicit const_iterator(const QtMetaTypePrivate::QSequentialIterableImpl &impl, QAtomicInt *ref_);
626
627 void begin();
628 void end();
629 public:
630 ~const_iterator();
631
632 const_iterator(const const_iterator &other);
633
634 const_iterator& operator=(const const_iterator &other);
635
636 const QVariant operator*() const;
637 bool operator==(const const_iterator &o) const;
638 bool operator!=(const const_iterator &o) const;
639 const_iterator &operator++();
640 const_iterator operator++(int);
641 const_iterator &operator--();
642 const_iterator operator--(int);
643 const_iterator &operator+=(int j);
644 const_iterator &operator-=(int j);
645 const_iterator operator+(int j) const;
646 const_iterator operator-(int j) const;
647 friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
648 };
649
650 friend struct const_iterator;
651
652#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
653 explicit QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl);
654#else
655 explicit QSequentialIterable(const QtMetaTypePrivate::QSequentialIterableImpl &impl);
656#endif
657
658 const_iterator begin() const;
659 const_iterator end() const;
660
661 QVariant at(int idx) const;
662 int size() const;
663
664 bool canReverseIterate() const;
665};
666
667class Q_CORE_EXPORT QAssociativeIterable
668{
669 QtMetaTypePrivate::QAssociativeIterableImpl m_impl;
670public:
671 struct Q_CORE_EXPORT const_iterator
672 {
673 private:
674 QtMetaTypePrivate::QAssociativeIterableImpl m_impl;
675 QAtomicInt *ref;
676 friend class QAssociativeIterable;
677 explicit const_iterator(const QAssociativeIterable &iter, QAtomicInt *ref_);
678
679 explicit const_iterator(const QtMetaTypePrivate::QAssociativeIterableImpl &impl, QAtomicInt *ref_);
680
681 void begin();
682 void end();
683 void find(const QVariant &key);
684 public:
685 ~const_iterator();
686 const_iterator(const const_iterator &other);
687
688 const_iterator& operator=(const const_iterator &other);
689
690 const QVariant key() const;
691
692 const QVariant value() const;
693
694 const QVariant operator*() const;
695 bool operator==(const const_iterator &o) const;
696 bool operator!=(const const_iterator &o) const;
697 const_iterator &operator++();
698 const_iterator operator++(int);
699 const_iterator &operator--();
700 const_iterator operator--(int);
701 const_iterator &operator+=(int j);
702 const_iterator &operator-=(int j);
703 const_iterator operator+(int j) const;
704 const_iterator operator-(int j) const;
705 friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
706 };
707
708 friend struct const_iterator;
709
710#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
711 explicit QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl);
712#else
713 explicit QAssociativeIterable(const QtMetaTypePrivate::QAssociativeIterableImpl &impl);
714#endif
715
716 const_iterator begin() const;
717 const_iterator end() const;
718 const_iterator find(const QVariant &key) const;
719
720 QVariant value(const QVariant &key) const;
721
722 int size() const;
723};
724
725#ifndef QT_MOC
726namespace QtPrivate {
727 template<typename T>
728 struct QVariantValueHelper : TreatAsQObjectBeforeMetaType<QVariantValueHelper<T>, T, const QVariant &, T>
729 {
730 static T metaType(const QVariant &v)
731 {
732 const int vid = qMetaTypeId<T>();
733 if (vid == v.userType())
734 return *reinterpret_cast<const T *>(v.constData());
735 T t;
736 if (v.convert(vid, &t))
737 return t;
738 return T();
739 }
740#ifndef QT_NO_QOBJECT
741 static T object(const QVariant &v)
742 {
743 return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject
744 ? v.d.data.o
745 : QVariantValueHelper::metaType(v));
746 }
747#endif
748 };
749
750 template<typename T>
751 struct QVariantValueHelperInterface : QVariantValueHelper<T>
752 {
753 };
754
755 template<>
756 struct QVariantValueHelperInterface<QSequentialIterable>
757 {
758 static QSequentialIterable invoke(const QVariant &v)
759 {
760 const int typeId = v.userType();
761 if (typeId == qMetaTypeId<QVariantList>()) {
762 return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QVariantList*>(v.constData())));
763 }
764 if (typeId == qMetaTypeId<QStringList>()) {
765 return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QStringList*>(v.constData())));
766 }
767#ifndef QT_BOOTSTRAPPED
768 if (typeId == qMetaTypeId<QByteArrayList>()) {
769 return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QByteArrayList*>(v.constData())));
770 }
771#endif
772 return QSequentialIterable(v.value<QtMetaTypePrivate::QSequentialIterableImpl>());
773 }
774 };
775 template<>
776 struct QVariantValueHelperInterface<QAssociativeIterable>
777 {
778 static QAssociativeIterable invoke(const QVariant &v)
779 {
780 const int typeId = v.userType();
781 if (typeId == qMetaTypeId<QVariantMap>()) {
782 return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantMap*>(v.constData())));
783 }
784 if (typeId == qMetaTypeId<QVariantHash>()) {
785 return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantHash*>(v.constData())));
786 }
787 return QAssociativeIterable(v.value<QtMetaTypePrivate::QAssociativeIterableImpl>());
788 }
789 };
790 template<>
791 struct QVariantValueHelperInterface<QVariantList>
792 {
793 static QVariantList invoke(const QVariant &v)
794 {
795 const int typeId = v.userType();
796 if (typeId == qMetaTypeId<QStringList>() || typeId == qMetaTypeId<QByteArrayList>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
797 QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v);
798 QVariantList l;
799 l.reserve(iter.size());
800 for (QSequentialIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
801 l << *it;
802 return l;
803 }
804 return QVariantValueHelper<QVariantList>::invoke(v);
805 }
806 };
807 template<>
808 struct QVariantValueHelperInterface<QVariantHash>
809 {
810 static QVariantHash invoke(const QVariant &v)
811 {
812 const int typeId = v.userType();
813 if (typeId == qMetaTypeId<QVariantMap>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
814 QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
815 QVariantHash l;
816 l.reserve(iter.size());
817 for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
818 l.insertMulti(it.key().toString(), it.value());
819 return l;
820 }
821 return QVariantValueHelper<QVariantHash>::invoke(v);
822 }
823 };
824 template<>
825 struct QVariantValueHelperInterface<QVariantMap>
826 {
827 static QVariantMap invoke(const QVariant &v)
828 {
829 const int typeId = v.userType();
830 if (typeId == qMetaTypeId<QVariantHash>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
831 QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
832 QVariantMap l;
833 for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
834 l.insertMulti(it.key().toString(), it.value());
835 return l;
836 }
837 return QVariantValueHelper<QVariantMap>::invoke(v);
838 }
839 };
840 template<>
841 struct QVariantValueHelperInterface<QPair<QVariant, QVariant> >
842 {
843 static QPair<QVariant, QVariant> invoke(const QVariant &v)
844 {
845 const int typeId = v.userType();
846 if (typeId == qMetaTypeId<QPair<QVariant, QVariant> >())
847 return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
848
849 if (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
850 QtMetaTypePrivate::QPairVariantInterfaceImpl pi = v.value<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
851
852 const QtMetaTypePrivate::VariantData d1 = pi.first();
853 QVariant v1(d1.metaTypeId, d1.data, d1.flags);
854 if (d1.metaTypeId == qMetaTypeId<QVariant>())
855 v1 = *reinterpret_cast<const QVariant*>(d1.data);
856
857 const QtMetaTypePrivate::VariantData d2 = pi.second();
858 QVariant v2(d2.metaTypeId, d2.data, d2.flags);
859 if (d2.metaTypeId == qMetaTypeId<QVariant>())
860 v2 = *reinterpret_cast<const QVariant*>(d2.data);
861
862 return QPair<QVariant, QVariant>(v1, v2);
863 }
864 return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
865 }
866 };
867}
868
869template<typename T> inline T qvariant_cast(const QVariant &v)
870{
871 return QtPrivate::QVariantValueHelperInterface<T>::invoke(v);
872}
873
874template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
875{
876 if (v.userType() == QMetaType::QVariant)
877 return *reinterpret_cast<const QVariant *>(v.constData());
878 return v;
879}
880
881#if QT_DEPRECATED_SINCE(5, 0)
882template<typename T>
883inline QT_DEPRECATED T qVariantValue(const QVariant &variant)
884{ return qvariant_cast<T>(variant); }
885
886template<typename T>
887inline QT_DEPRECATED bool qVariantCanConvert(const QVariant &variant)
888{ return variant.template canConvert<T>(); }
889#endif
890
891#endif
892
893#ifndef QT_NO_DEBUG_STREAM
894Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
895Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant::Type);
896#endif
897
898QT_END_NAMESPACE
899
900#endif // QVARIANT_H
901