1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://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 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QVARIANT_H
43 #define QVARIANT_H
44 
45 #include <QtCore/qatomic.h>
46 #include <QtCore/qbytearray.h>
47 #include <QtCore/qlist.h>
48 #include <QtCore/qmetatype.h>
49 #include <QtCore/qmap.h>
50 #include <QtCore/qhash.h>
51 #include <QtCore/qstring.h>
52 
53 QT_BEGIN_HEADER
54 
55 QT_BEGIN_NAMESPACE
56 
57 QT_MODULE(Core)
58 
59 class QBitArray;
60 class QDataStream;
61 class QDate;
62 class QDateTime;
63 class QEasingCurve;
64 class QLine;
65 class QLineF;
66 class QLocale;
67 class QMatrix;
68 class QTransform;
69 class QStringList;
70 class QTime;
71 class QPoint;
72 class QPointF;
73 class QSize;
74 class QSizeF;
75 class QRect;
76 class QRectF;
77 #ifndef QT_NO_REGEXP
78 class QRegExp;
79 #endif
80 class QTextFormat;
81 class QTextLength;
82 class QUrl;
83 class QVariant;
84 class QVariantComparisonHelper;
85 
86 template <typename T>
87 inline QVariant qVariantFromValue(const T &);
88 
89 template<typename T>
90 inline T qvariant_cast(const QVariant &);
91 
92 class Q_CORE_EXPORT QVariant
93 {
94  public:
95     enum Type {
96         Invalid = 0,
97 
98         Bool = 1,
99         Int = 2,
100         UInt = 3,
101         LongLong = 4,
102         ULongLong = 5,
103         Double = 6,
104         Char = 7,
105         Map = 8,
106         List = 9,
107         String = 10,
108         StringList = 11,
109         ByteArray = 12,
110         BitArray = 13,
111         Date = 14,
112         Time = 15,
113         DateTime = 16,
114         Url = 17,
115         Locale = 18,
116         Rect = 19,
117         RectF = 20,
118         Size = 21,
119         SizeF = 22,
120         Line = 23,
121         LineF = 24,
122         Point = 25,
123         PointF = 26,
124         RegExp = 27,
125         Hash = 28,
126         EasingCurve = 29,
127         LastCoreType = EasingCurve,
128 
129         // value 62 is internally reserved
130 #ifdef QT3_SUPPORT
131         ColorGroup = 63,
132 #endif
133         Font = 64,
134         Pixmap = 65,
135         Brush = 66,
136         Color = 67,
137         Palette = 68,
138         Icon = 69,
139         Image = 70,
140         Polygon = 71,
141         Region = 72,
142         Bitmap = 73,
143         Cursor = 74,
144         SizePolicy = 75,
145         KeySequence = 76,
146         Pen = 77,
147         TextLength = 78,
148         TextFormat = 79,
149         Matrix = 80,
150         Transform = 81,
151         Matrix4x4 = 82,
152         Vector2D = 83,
153         Vector3D = 84,
154         Vector4D = 85,
155         Quaternion = 86,
156         LastGuiType = Quaternion,
157 
158         UserType = 127,
159 #ifdef QT3_SUPPORT
160         IconSet = Icon,
161         CString = ByteArray,
162         PointArray = Polygon,
163 #endif
164         LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
165     };
166 
167     inline QVariant();
168     ~QVariant();
169     QVariant(Type type);
170     QVariant(int typeOrUserType, const void *copy);
171     QVariant(int typeOrUserType, const void *copy, uint flags);
172     QVariant(const QVariant &other);
173 
174 #ifndef QT_NO_DATASTREAM
175     QVariant(QDataStream &s);
176 #endif
177 
178     QVariant(int i);
179     QVariant(uint ui);
180     QVariant(qlonglong ll);
181     QVariant(qulonglong ull);
182     QVariant(bool b);
183     QVariant(double d);
QVariant(float f)184     QVariant(float f) { d.is_null = false; d.type = QMetaType::Float; d.data.f = f; }
185 #ifndef QT_NO_CAST_FROM_ASCII
186     QT_ASCII_CAST_WARN_CONSTRUCTOR QVariant(const char *str);
187 #endif
188 
189     QVariant(const QByteArray &bytearray);
190     QVariant(const QBitArray &bitarray);
191     QVariant(const QString &string);
192     QVariant(const QLatin1String &string);
193     QVariant(const QStringList &stringlist);
194     QVariant(const QChar &qchar);
195     QVariant(const QDate &date);
196     QVariant(const QTime &time);
197     QVariant(const QDateTime &datetime);
198     QVariant(const QList<QVariant> &list);
199     QVariant(const QMap<QString,QVariant> &map);
200     QVariant(const QHash<QString,QVariant> &hash);
201 #ifndef QT_NO_GEOM_VARIANT
202     QVariant(const QSize &size);
203     QVariant(const QSizeF &size);
204     QVariant(const QPoint &pt);
205     QVariant(const QPointF &pt);
206     QVariant(const QLine &line);
207     QVariant(const QLineF &line);
208     QVariant(const QRect &rect);
209     QVariant(const QRectF &rect);
210 #endif
211     QVariant(const QUrl &url);
212     QVariant(const QLocale &locale);
213 #ifndef QT_NO_REGEXP
214     QVariant(const QRegExp &regExp);
215 #endif
216 #ifndef QT_BOOTSTRAPPED
217     QVariant(const QEasingCurve &easing);
218 #endif
219     QVariant(Qt::GlobalColor color);
220 
221     QVariant& operator=(const QVariant &other);
222 #ifdef Q_COMPILER_RVALUE_REFS
223     inline QVariant &operator=(QVariant &&other)
224     { qSwap(d, other.d); return *this; }
225 #endif
226 
swap(QVariant & other)227     inline void swap(QVariant &other) { qSwap(d, other.d); }
228 
229     Type type() const;
230     int userType() const;
231     const char *typeName() const;
232 
233     bool canConvert(Type t) const;
234     bool convert(Type t);
235 
236 #ifdef QT3_SUPPORT
canCast(Type t)237     inline QT3_SUPPORT bool canCast(Type t) const
238     { return canConvert(t); }
cast(Type t)239     inline QT3_SUPPORT bool cast(Type t)
240     { return convert(t); }
241 #endif
242 
243     inline bool isValid() const;
244     bool isNull() const;
245 
246     void clear();
247 
248     void detach();
249     inline bool isDetached() const;
250 
251     int toInt(bool *ok = 0) const;
252     uint toUInt(bool *ok = 0) const;
253     qlonglong toLongLong(bool *ok = 0) const;
254     qulonglong toULongLong(bool *ok = 0) const;
255     bool toBool() const;
256     double toDouble(bool *ok = 0) const;
257     float toFloat(bool *ok = 0) const;
258     qreal toReal(bool *ok = 0) const;
259     QByteArray toByteArray() const;
260     QBitArray toBitArray() const;
261     QString toString() const;
262     QStringList toStringList() const;
263     QChar toChar() const;
264     QDate toDate() const;
265     QTime toTime() const;
266     QDateTime toDateTime() const;
267     QList<QVariant> toList() const;
268     QMap<QString, QVariant> toMap() const;
269     QHash<QString, QVariant> toHash() const;
270 
271 #ifndef QT_NO_GEOM_VARIANT
272     QPoint toPoint() const;
273     QPointF toPointF() const;
274     QRect toRect() const;
275     QSize toSize() const;
276     QSizeF toSizeF() const;
277     QLine toLine() const;
278     QLineF toLineF() const;
279     QRectF toRectF() const;
280 #endif
281     QUrl toUrl() const;
282     QLocale toLocale() const;
283 #ifndef QT_NO_REGEXP
284     QRegExp toRegExp() const;
285 #endif
286 #ifndef QT_BOOTSTRAPPED
287     QEasingCurve toEasingCurve() const;
288 #endif
289 
290 #ifdef QT3_SUPPORT
291     inline QT3_SUPPORT int &asInt();
292     inline QT3_SUPPORT uint &asUInt();
293     inline QT3_SUPPORT qlonglong &asLongLong();
294     inline QT3_SUPPORT qulonglong &asULongLong();
295     inline QT3_SUPPORT bool &asBool();
296     inline QT3_SUPPORT double &asDouble();
297     inline QT3_SUPPORT QByteArray &asByteArray();
298     inline QT3_SUPPORT QBitArray &asBitArray();
299     inline QT3_SUPPORT QString &asString();
300     inline QT3_SUPPORT QStringList &asStringList();
301     inline QT3_SUPPORT QDate &asDate();
302     inline QT3_SUPPORT QTime &asTime();
303     inline QT3_SUPPORT QDateTime &asDateTime();
304     inline QT3_SUPPORT QList<QVariant> &asList();
305     inline QT3_SUPPORT QMap<QString,QVariant> &asMap();
306     inline QT3_SUPPORT QPoint &asPoint();
307     inline QT3_SUPPORT QRect &asRect();
308     inline QT3_SUPPORT QSize &asSize();
309 #endif //QT3_SUPPORT
310 
311 #ifndef QT_NO_DATASTREAM
312     void load(QDataStream &ds);
313     void save(QDataStream &ds) const;
314 #endif
315     static const char *typeToName(Type type);
316     static Type nameToType(const char *name);
317 
318 #ifdef QT3_SUPPORT
QVariant(bool val,int)319     inline QT3_SUPPORT_CONSTRUCTOR QVariant(bool val, int) { create(Bool, &val); }
toCString()320     inline QT3_SUPPORT const QByteArray toCString() const { return toByteArray(); }
asCString()321     inline QT3_SUPPORT QByteArray &asCString() { return *reinterpret_cast<QByteArray *>(castOrDetach(ByteArray)); }
322 #endif
323 
324     void *data();
325     const void *constData() const;
data()326     inline const void *data() const { return constData(); }
327 
328     template<typename T>
329     inline void setValue(const T &value);
330 
331     template<typename T>
value()332     inline T value() const
333     { return qvariant_cast<T>(*this); }
334 
335     template<typename T>
fromValue(const T & value)336     static inline QVariant fromValue(const T &value)
337     { return qVariantFromValue(value); }
338 
339     template<typename T>
canConvert()340     bool canConvert() const
341     { return canConvert(Type(qMetaTypeId<T>())); }
342 
343  public:
344 #ifndef qdoc
345     struct PrivateShared
346     {
PrivateSharedPrivateShared347         inline PrivateShared(void *v) : ptr(v), ref(1) { }
348         void *ptr;
349         QAtomicInt ref;
350     };
351     struct Private
352     {
PrivatePrivate353         inline Private(): type(Invalid), is_shared(false), is_null(true) { data.ptr = 0; }
PrivatePrivate354         inline Private(const Private &other)
355             : data(other.data), type(other.type),
356               is_shared(other.is_shared), is_null(other.is_null)
357         {}
358         union Data
359         {
360             char c;
361             int i;
362             uint u;
363             bool b;
364             double d;
365             float f;
366             qreal real;
367             qlonglong ll;
368             qulonglong ull;
369             QObject *o;
370             void *ptr;
371             PrivateShared *shared;
372         } data;
373         uint type : 30;
374         uint is_shared : 1;
375         uint is_null : 1;
376     };
377  public:
378     typedef void (*f_construct)(Private *, const void *);
379     typedef void (*f_clear)(Private *);
380     typedef bool (*f_null)(const Private *);
381 #ifndef QT_NO_DATASTREAM
382     typedef void (*f_load)(Private *, QDataStream &);
383     typedef void (*f_save)(const Private *, QDataStream &);
384 #endif
385     typedef bool (*f_compare)(const Private *, const Private *);
386     typedef bool (*f_convert)(const QVariant::Private *d, Type t, void *, bool *);
387     typedef bool (*f_canConvert)(const QVariant::Private *d, Type t);
388     typedef void (*f_debugStream)(QDebug, const QVariant &);
389     struct Handler {
390         f_construct construct;
391         f_clear clear;
392         f_null isNull;
393 #ifndef QT_NO_DATASTREAM
394         f_load load;
395         f_save save;
396 #endif
397         f_compare compare;
398         f_convert convert;
399         f_canConvert canConvert;
400         f_debugStream debugStream;
401     };
402 #endif
403 
404     inline bool operator==(const QVariant &v) const
405     { return cmp(v); }
406     inline bool operator!=(const QVariant &v) const
407     { return !cmp(v); }
408 
409 protected:
410     friend inline bool qvariant_cast_helper(const QVariant &, QVariant::Type, void *);
411     friend int qRegisterGuiVariant();
412     friend int qUnregisterGuiVariant();
413     friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
414 #ifndef QT_NO_DEBUG_STREAM
415     friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
416 #endif
417     Private d;
418 
419     static const Handler *handler;
420 
421     void create(int type, const void *copy);
422 #ifdef QT3_SUPPORT
423     void *castOrDetach(Type t);
424 #endif
425     bool cmp(const QVariant &other) const;
426 
427 private:
428     // force compile error, prevent QVariant(bool) to be called
QVariant(void *)429     inline QVariant(void *) { Q_ASSERT(false); }
430 #ifdef QT_NO_CAST_FROM_ASCII
431     // force compile error when implicit conversion is not wanted
QVariant(const char *)432     inline QVariant(const char *) { Q_ASSERT(false); }
433 #endif
434 #ifndef QT3_SUPPORT
435     // force compile error, prevent QVariant(QVariant::Type, int) to be called
QVariant(bool,int)436     inline QVariant(bool, int) { Q_ASSERT(false); }
437 #endif
438 public:
439     typedef Private DataPtr;
data_ptr()440     inline DataPtr &data_ptr() { return d; }
441 };
442 
443 typedef QList<QVariant> QVariantList;
444 typedef QMap<QString, QVariant> QVariantMap;
445 typedef QHash<QString, QVariant> QVariantHash;
446 
qvariant_cast_helper(const QVariant & v,QVariant::Type tp,void * ptr)447 inline bool qvariant_cast_helper(const QVariant &v, QVariant::Type tp, void *ptr)
448 { return QVariant::handler->convert(&v.d, tp, ptr, 0); }
449 
450 template <typename T>
qVariantFromValue(const T & t)451 inline QVariant qVariantFromValue(const T &t)
452 {
453     return QVariant(qMetaTypeId<T>(reinterpret_cast<T *>(0)), &t, QTypeInfo<T>::isPointer);
454 }
455 
456 template <>
qVariantFromValue(const QVariant & t)457 inline QVariant qVariantFromValue(const QVariant &t) { return t; }
458 
459 template <typename T>
qVariantSetValue(QVariant & v,const T & t)460 inline void qVariantSetValue(QVariant &v, const T &t)
461 {
462     //if possible we reuse the current QVariant private
463     const uint type = qMetaTypeId<T>(reinterpret_cast<T *>(0));
464     QVariant::Private &d = v.data_ptr();
465     if (v.isDetached() && (type == d.type || (type <= uint(QVariant::Char) && d.type <= uint(QVariant::Char)))) {
466         d.type = type;
467         d.is_null = false;
468         T *old = reinterpret_cast<T*>(d.is_shared ? d.data.shared->ptr : &d.data.ptr);
469         if (QTypeInfo<T>::isComplex)
470             old->~T();
471         new (old) T(t); //call the copy constructor
472     } else {
473         v = QVariant(type, &t, QTypeInfo<T>::isPointer);
474     }
475 }
476 
477 template <>
478 inline void qVariantSetValue<QVariant>(QVariant &v, const QVariant &t)
479 {
480     v = t;
481 }
482 
483 
QVariant()484 inline QVariant::QVariant() {}
isValid()485 inline bool QVariant::isValid() const { return d.type != Invalid; }
486 
487 #ifdef QT3_SUPPORT
asInt()488 inline int &QVariant::asInt()
489 { return *reinterpret_cast<int *>(castOrDetach(Int)); }
asUInt()490 inline uint &QVariant::asUInt()
491 { return *reinterpret_cast<uint *>(castOrDetach(UInt)); }
asLongLong()492 inline qlonglong &QVariant::asLongLong()
493 { return *reinterpret_cast<qlonglong *>(castOrDetach(LongLong)); }
asULongLong()494 inline qulonglong &QVariant::asULongLong()
495 { return *reinterpret_cast<qulonglong *>(castOrDetach(ULongLong)); }
asBool()496 inline bool &QVariant::asBool()
497 { return *reinterpret_cast<bool *>(castOrDetach(Bool)); }
asDouble()498 inline double &QVariant::asDouble()
499 { return *reinterpret_cast<double *>(castOrDetach(Double)); }
asByteArray()500 inline QByteArray& QVariant::asByteArray()
501 { return *reinterpret_cast<QByteArray *>(castOrDetach(ByteArray)); }
asBitArray()502 inline QBitArray& QVariant::asBitArray()
503 { return *reinterpret_cast<QBitArray *>(castOrDetach(BitArray)); }
asString()504 inline QString& QVariant::asString()
505 { return *reinterpret_cast<QString *>(castOrDetach(String)); }
asStringList()506 inline QStringList& QVariant::asStringList()
507 { return *reinterpret_cast<QStringList *>(castOrDetach(StringList)); }
asDate()508 inline QDate& QVariant::asDate()
509 { return *reinterpret_cast<QDate *>(castOrDetach(Date)); }
asTime()510 inline QTime& QVariant::asTime()
511 { return *reinterpret_cast<QTime *>(castOrDetach(Time)); }
asDateTime()512 inline QDateTime& QVariant::asDateTime()
513 { return *reinterpret_cast<QDateTime *>(castOrDetach(DateTime)); }
asList()514 inline QList<QVariant>& QVariant::asList()
515 { return *reinterpret_cast<QList<QVariant> *>(castOrDetach(List)); }
asMap()516 inline QMap<QString, QVariant>& QVariant::asMap()
517 { return *reinterpret_cast<QMap<QString, QVariant> *>(castOrDetach(Map)); }
asPoint()518 inline QPoint &QVariant::asPoint()
519 { return *reinterpret_cast<QPoint *>(castOrDetach(Point)); }
asRect()520 inline QRect &QVariant::asRect()
521 { return *reinterpret_cast<QRect *>(castOrDetach(Rect)); }
asSize()522 inline QSize &QVariant::asSize()
523 { return *reinterpret_cast<QSize *>(castOrDetach(Size)); }
524 #endif //QT3_SUPPORT
525 
526 template<typename T>
setValue(const T & avalue)527 inline void QVariant::setValue(const T &avalue)
528 { qVariantSetValue(*this, avalue); }
529 
530 #ifndef QT_NO_DATASTREAM
531 Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant& p);
532 Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant& p);
533 Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant::Type& p);
534 Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant::Type p);
535 #endif
536 
isDetached()537 inline bool QVariant::isDetached() const
538 { return !d.is_shared || d.data.shared->ref == 1; }
539 
540 
541 #ifdef qdoc
542     inline bool operator==(const QVariant &v1, const QVariant &v2);
543     inline bool operator!=(const QVariant &v1, const QVariant &v2);
544 #else
545 
546 /* Helper class to add one more level of indirection to prevent
547    implicit casts.
548 */
549 class QVariantComparisonHelper
550 {
551 public:
QVariantComparisonHelper(const QVariant & var)552     inline QVariantComparisonHelper(const QVariant &var)
553         : v(&var) {}
554 private:
555     friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
556     const QVariant *v;
557 };
558 
559 inline bool operator==(const QVariant &v1, const QVariantComparisonHelper &v2)
560 {
561     return v1.cmp(*v2.v);
562 }
563 
564 inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
565 {
566     return !operator==(v1, v2);
567 }
568 #endif
569 
570 #ifndef QT_MOC
qvariant_cast(const QVariant & v)571 template<typename T> inline T qvariant_cast(const QVariant &v)
572 {
573     const int vid = qMetaTypeId<T>(static_cast<T *>(0));
574     if (vid == v.userType())
575         return *reinterpret_cast<const T *>(v.constData());
576     if (vid < int(QMetaType::User)) {
577         T t;
578         if (qvariant_cast_helper(v, QVariant::Type(vid), &t))
579             return t;
580     }
581     return T();
582 }
583 
584 template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
585 {
586     if (v.userType() == QMetaType::QVariant)
587         return *reinterpret_cast<const QVariant *>(v.constData());
588     return v;
589 }
590 
591 #ifdef QT_DEPRECATED
592 template<typename T>
qVariantValue(const QVariant & variant)593 inline QT_DEPRECATED T qVariantValue(const QVariant &variant)
594 { return qvariant_cast<T>(variant); }
595 
596 template<typename T>
qVariantCanConvert(const QVariant & variant)597 inline QT_DEPRECATED bool qVariantCanConvert(const QVariant &variant)
598 { return variant.template canConvert<T>(); }
599 #endif
600 
601 #endif
602 Q_DECLARE_SHARED(QVariant)
603 Q_DECLARE_TYPEINFO(QVariant, Q_MOVABLE_TYPE);
604 
605 #ifndef QT_NO_DEBUG_STREAM
606 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
607 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant::Type);
608 #endif
609 
610 QT_END_NAMESPACE
611 
612 Q_DECLARE_BUILTIN_METATYPE(QVariantList, QVariantList)
613 Q_DECLARE_BUILTIN_METATYPE(QVariantMap, QVariantMap)
614 Q_DECLARE_BUILTIN_METATYPE(QVariantHash, QVariantHash)
615 
616 QT_END_HEADER
617 
618 #endif // QVARIANT_H
619