1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/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 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
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
53QT_BEGIN_HEADER
54
55QT_BEGIN_NAMESPACE
56
57QT_MODULE(Core)
58
59class QBitArray;
60class QDataStream;
61class QDate;
62class QDateTime;
63class QEasingCurve;
64class QLine;
65class QLineF;
66class QLocale;
67class QMatrix;
68class QTransform;
69class QStringList;
70class QTime;
71class QPoint;
72class QPointF;
73class QSize;
74class QSizeF;
75class QRect;
76class QRectF;
77#ifndef QT_NO_REGEXP
78class QRegExp;
79#endif
80class QTextFormat;
81class QTextLength;
82class QUrl;
83class QVariant;
84class QVariantComparisonHelper;
85
86template <typename T>
87inline QVariant qVariantFromValue(const T &);
88
89template<typename T>
90inline T qvariant_cast(const QVariant &);
91
92class 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);
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
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
237 inline QT3_SUPPORT bool canCast(Type t) const
238 { return canConvert(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
319 inline QT3_SUPPORT_CONSTRUCTOR QVariant(bool val, int) { create(Bool, &val); }
320 inline QT3_SUPPORT const QByteArray toCString() const { return toByteArray(); }
321 inline QT3_SUPPORT QByteArray &asCString() { return *reinterpret_cast<QByteArray *>(castOrDetach(ByteArray)); }
322#endif
323
324 void *data();
325 const void *constData() const;
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>
332 inline T value() const
333 { return qvariant_cast<T>(*this); }
334
335 template<typename T>
336 static inline QVariant fromValue(const T &value)
337 { return qVariantFromValue(value); }
338
339 template<typename T>
340 bool canConvert() const
341 { return canConvert(Type(qMetaTypeId<T>())); }
342
343 public:
344#ifndef qdoc
345 struct PrivateShared
346 {
347 inline PrivateShared(void *v) : ptr(v), ref(1) { }
348 void *ptr;
349 QAtomicInt ref;
350 };
351 struct Private
352 {
353 inline Private(): type(Invalid), is_shared(false), is_null(true) { data.ptr = 0; }
354 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
409protected:
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
427private:
428 // force compile error, prevent QVariant(bool) to be called
429 inline QVariant(void *) { Q_ASSERT(false); }
430#ifdef QT_NO_CAST_FROM_ASCII
431 // force compile error when implicit conversion is not wanted
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
436 inline QVariant(bool, int) { Q_ASSERT(false); }
437#endif
438public:
439 typedef Private DataPtr;
440 inline DataPtr &data_ptr() { return d; }
441};
442
443typedef QList<QVariant> QVariantList;
444typedef QMap<QString, QVariant> QVariantMap;
445typedef QHash<QString, QVariant> QVariantHash;
446
447inline bool qvariant_cast_helper(const QVariant &v, QVariant::Type tp, void *ptr)
448{ return QVariant::handler->convert(&v.d, tp, ptr, 0); }
449
450template <typename T>
451inline QVariant qVariantFromValue(const T &t)
452{
453 return QVariant(qMetaTypeId<T>(reinterpret_cast<T *>(0)), &t, QTypeInfo<T>::isPointer);
454}
455
456template <>
457inline QVariant qVariantFromValue(const QVariant &t) { return t; }
458
459template <typename T>
460inline 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
477template <>
478inline void qVariantSetValue<QVariant>(QVariant &v, const QVariant &t)
479{
480 v = t;
481}
482
483
484inline QVariant::QVariant() {}
485inline bool QVariant::isValid() const { return d.type != Invalid; }
486
487#ifdef QT3_SUPPORT
488inline int &QVariant::asInt()
489{ return *reinterpret_cast<int *>(castOrDetach(Int)); }
490inline uint &QVariant::asUInt()
491{ return *reinterpret_cast<uint *>(castOrDetach(UInt)); }
492inline qlonglong &QVariant::asLongLong()
493{ return *reinterpret_cast<qlonglong *>(castOrDetach(LongLong)); }
494inline qulonglong &QVariant::asULongLong()
495{ return *reinterpret_cast<qulonglong *>(castOrDetach(ULongLong)); }
496inline bool &QVariant::asBool()
497{ return *reinterpret_cast<bool *>(castOrDetach(Bool)); }
498inline double &QVariant::asDouble()
499{ return *reinterpret_cast<double *>(castOrDetach(Double)); }
500inline QByteArray& QVariant::asByteArray()
501{ return *reinterpret_cast<QByteArray *>(castOrDetach(ByteArray)); }
502inline QBitArray& QVariant::asBitArray()
503{ return *reinterpret_cast<QBitArray *>(castOrDetach(BitArray)); }
504inline QString& QVariant::asString()
505{ return *reinterpret_cast<QString *>(castOrDetach(String)); }
506inline QStringList& QVariant::asStringList()
507{ return *reinterpret_cast<QStringList *>(castOrDetach(StringList)); }
508inline QDate& QVariant::asDate()
509{ return *reinterpret_cast<QDate *>(castOrDetach(Date)); }
510inline QTime& QVariant::asTime()
511{ return *reinterpret_cast<QTime *>(castOrDetach(Time)); }
512inline QDateTime& QVariant::asDateTime()
513{ return *reinterpret_cast<QDateTime *>(castOrDetach(DateTime)); }
514inline QList<QVariant>& QVariant::asList()
515{ return *reinterpret_cast<QList<QVariant> *>(castOrDetach(List)); }
516inline QMap<QString, QVariant>& QVariant::asMap()
517{ return *reinterpret_cast<QMap<QString, QVariant> *>(castOrDetach(Map)); }
518inline QPoint &QVariant::asPoint()
519{ return *reinterpret_cast<QPoint *>(castOrDetach(Point)); }
520inline QRect &QVariant::asRect()
521{ return *reinterpret_cast<QRect *>(castOrDetach(Rect)); }
522inline QSize &QVariant::asSize()
523{ return *reinterpret_cast<QSize *>(castOrDetach(Size)); }
524#endif //QT3_SUPPORT
525
526template<typename T>
527inline void QVariant::setValue(const T &avalue)
528{ qVariantSetValue(*this, avalue); }
529
530#ifndef QT_NO_DATASTREAM
531Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant& p);
532Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant& p);
533Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant::Type& p);
534Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant::Type p);
535#endif
536
537inline 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*/
549class QVariantComparisonHelper
550{
551public:
552 inline QVariantComparisonHelper(const QVariant &var)
553 : v(&var) {}
554private:
555 friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
556 const QVariant *v;
557};
558
559inline bool operator==(const QVariant &v1, const QVariantComparisonHelper &v2)
560{
561 return v1.cmp(*v2.v);
562}
563
564inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
565{
566 return !operator==(v1, v2);
567}
568#endif
569
570#ifndef QT_MOC
571template<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
584template<> 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
592template<typename T>
593inline QT_DEPRECATED T qVariantValue(const QVariant &variant)
594{ return qvariant_cast<T>(variant); }
595
596template<typename T>
597inline QT_DEPRECATED bool qVariantCanConvert(const QVariant &variant)
598{ return variant.template canConvert<T>(); }
599#endif
600
601#endif
602Q_DECLARE_SHARED(QVariant)
603Q_DECLARE_TYPEINFO(QVariant, Q_MOVABLE_TYPE);
604
605#ifndef QT_NO_DEBUG_STREAM
606Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
607Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant::Type);
608#endif
609
610QT_END_NAMESPACE
611
612Q_DECLARE_BUILTIN_METATYPE(QVariantList, QVariantList)
613Q_DECLARE_BUILTIN_METATYPE(QVariantMap, QVariantMap)
614Q_DECLARE_BUILTIN_METATYPE(QVariantHash, QVariantHash)
615
616QT_END_HEADER
617
618#endif // QVARIANT_H
619