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

Last change on this file since 641 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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