source: trunk/src/corelib/kernel/qvariant.h@ 967

Last change on this file since 967 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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