Introduce QMetaType::UnknownType.
[profile/ivi/qtbase.git] / src / corelib / kernel / qvariant.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
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 #include <QtCore/qobject.h>
53
54 QT_BEGIN_HEADER
55
56 QT_BEGIN_NAMESPACE
57
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 namespace QtPrivate {
93
94     template <typename Derived, typename Argument, typename ReturnType>
95     struct ObjectInvoker
96     {
97         static ReturnType invoke(Argument a)
98         {
99             return Derived::object(a);
100         }
101     };
102
103     template <typename Derived, typename Argument, typename ReturnType>
104     struct MetaTypeInvoker
105     {
106         static ReturnType invoke(Argument a)
107         {
108             return Derived::metaType(a);
109         }
110     };
111
112     template <typename Derived, typename T, typename Argument, typename ReturnType, bool = IsPointerToTypeDerivedFromQObject<T>::Value>
113     struct TreatAsQObjectBeforeMetaType : ObjectInvoker<Derived, Argument, ReturnType>
114     {
115     };
116
117     template <typename Derived, typename T, typename Argument, typename ReturnType>
118     struct TreatAsQObjectBeforeMetaType<Derived, T, Argument, ReturnType, false> : MetaTypeInvoker<Derived, Argument, ReturnType>
119     {
120     };
121
122     template<typename T> struct QVariantValueHelper;
123 }
124
125 class Q_CORE_EXPORT QVariant
126 {
127  public:
128     enum Type {
129         Invalid = QMetaType::UnknownType,
130         Bool = QMetaType::Bool,
131         Int = QMetaType::Int,
132         UInt = QMetaType::UInt,
133         LongLong = QMetaType::LongLong,
134         ULongLong = QMetaType::ULongLong,
135         Double = QMetaType::Double,
136         Char = QMetaType::QChar,
137         Map = QMetaType::QVariantMap,
138         List = QMetaType::QVariantList,
139         String = QMetaType::QString,
140         StringList = QMetaType::QStringList,
141         ByteArray = QMetaType::QByteArray,
142         BitArray = QMetaType::QBitArray,
143         Date = QMetaType::QDate,
144         Time = QMetaType::QTime,
145         DateTime = QMetaType::QDateTime,
146         Url = QMetaType::QUrl,
147         Locale = QMetaType::QLocale,
148         Rect = QMetaType::QRect,
149         RectF = QMetaType::QRectF,
150         Size = QMetaType::QSize,
151         SizeF = QMetaType::QSizeF,
152         Line = QMetaType::QLine,
153         LineF = QMetaType::QLineF,
154         Point = QMetaType::QPoint,
155         PointF = QMetaType::QPointF,
156         RegExp = QMetaType::QRegExp,
157         Hash = QMetaType::QVariantHash,
158         EasingCurve = QMetaType::QEasingCurve,
159         Uuid = QMetaType::QUuid,
160         ModelIndex = QMetaType::QModelIndex,
161         LastCoreType = QMetaType::LastCoreType,
162
163         Font = QMetaType::QFont,
164         Pixmap = QMetaType::QPixmap,
165         Brush = QMetaType::QBrush,
166         Color = QMetaType::QColor,
167         Palette = QMetaType::QPalette,
168         Image = QMetaType::QImage,
169         Polygon = QMetaType::QPolygon,
170         Region = QMetaType::QRegion,
171         Bitmap = QMetaType::QBitmap,
172         Cursor = QMetaType::QCursor,
173         KeySequence = QMetaType::QKeySequence,
174         Pen = QMetaType::QPen,
175         TextLength = QMetaType::QTextLength,
176         TextFormat = QMetaType::QTextFormat,
177         Matrix = QMetaType::QMatrix,
178         Transform = QMetaType::QTransform,
179         Matrix4x4 = QMetaType::QMatrix4x4,
180         Vector2D = QMetaType::QVector2D,
181         Vector3D = QMetaType::QVector3D,
182         Vector4D = QMetaType::QVector4D,
183         Quaternion = QMetaType::QQuaternion,
184         PolygonF = QMetaType::QPolygonF,
185         LastGuiType = QMetaType::LastGuiType,
186
187         Icon = QMetaType::QIcon,
188         SizePolicy = QMetaType::QSizePolicy,
189
190         UserType = QMetaType::User,
191         LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
192     };
193
194     inline QVariant();
195     ~QVariant();
196     QVariant(Type type);
197     QVariant(int typeId, const void *copy);
198     QVariant(int typeId, const void *copy, uint flags);
199     QVariant(const QVariant &other);
200
201 #ifndef QT_NO_DATASTREAM
202     QVariant(QDataStream &s);
203 #endif
204
205     QVariant(int i);
206     QVariant(uint ui);
207     QVariant(qlonglong ll);
208     QVariant(qulonglong ull);
209     QVariant(bool b);
210     QVariant(double d);
211     QVariant(float f) { d.is_null = false; d.type = QMetaType::Float; d.data.f = f; }
212 #ifndef QT_NO_CAST_FROM_ASCII
213     QT_ASCII_CAST_WARN QVariant(const char *str);
214 #endif
215
216     QVariant(const QByteArray &bytearray);
217     QVariant(const QBitArray &bitarray);
218     QVariant(const QString &string);
219     QVariant(const QLatin1String &string);
220     QVariant(const QStringList &stringlist);
221     QVariant(QChar qchar);
222     QVariant(const QDate &date);
223     QVariant(const QTime &time);
224     QVariant(const QDateTime &datetime);
225     QVariant(const QList<QVariant> &list);
226     QVariant(const QMap<QString,QVariant> &map);
227     QVariant(const QHash<QString,QVariant> &hash);
228 #ifndef QT_NO_GEOM_VARIANT
229     QVariant(const QSize &size);
230     QVariant(const QSizeF &size);
231     QVariant(const QPoint &pt);
232     QVariant(const QPointF &pt);
233     QVariant(const QLine &line);
234     QVariant(const QLineF &line);
235     QVariant(const QRect &rect);
236     QVariant(const QRectF &rect);
237 #endif
238     QVariant(const QUrl &url);
239     QVariant(const QLocale &locale);
240 #ifndef QT_NO_REGEXP
241     QVariant(const QRegExp &regExp);
242 #endif
243 #ifndef QT_BOOTSTRAPPED
244     QVariant(const QEasingCurve &easing);
245 #endif
246     QVariant(Qt::GlobalColor color);
247
248     QVariant& operator=(const QVariant &other);
249 #ifdef Q_COMPILER_RVALUE_REFS
250     inline QVariant &operator=(QVariant &&other)
251     { qSwap(d, other.d); return *this; }
252 #endif
253
254     inline void swap(QVariant &other) { qSwap(d, other.d); }
255
256     Type type() const;
257     int userType() const;
258     const char *typeName() const;
259
260     bool canConvert(int targetTypeId) const;
261     bool convert(int targetTypeId);
262
263     inline bool isValid() const;
264     bool isNull() const;
265
266     void clear();
267
268     void detach();
269     inline bool isDetached() const;
270
271     int toInt(bool *ok = 0) const;
272     uint toUInt(bool *ok = 0) const;
273     qlonglong toLongLong(bool *ok = 0) const;
274     qulonglong toULongLong(bool *ok = 0) const;
275     bool toBool() const;
276     double toDouble(bool *ok = 0) const;
277     float toFloat(bool *ok = 0) const;
278     qreal toReal(bool *ok = 0) const;
279     QByteArray toByteArray() const;
280     QBitArray toBitArray() const;
281     QString toString() const;
282     QStringList toStringList() const;
283     QChar toChar() const;
284     QDate toDate() const;
285     QTime toTime() const;
286     QDateTime toDateTime() const;
287     QList<QVariant> toList() const;
288     QMap<QString, QVariant> toMap() const;
289     QHash<QString, QVariant> toHash() const;
290
291 #ifndef QT_NO_GEOM_VARIANT
292     QPoint toPoint() const;
293     QPointF toPointF() const;
294     QRect toRect() const;
295     QSize toSize() const;
296     QSizeF toSizeF() const;
297     QLine toLine() const;
298     QLineF toLineF() const;
299     QRectF toRectF() const;
300 #endif
301     QUrl toUrl() const;
302     QLocale toLocale() const;
303 #ifndef QT_NO_REGEXP
304     QRegExp toRegExp() const;
305 #endif
306 #ifndef QT_BOOTSTRAPPED
307     QEasingCurve toEasingCurve() const;
308 #endif
309
310 #ifndef QT_NO_DATASTREAM
311     void load(QDataStream &ds);
312     void save(QDataStream &ds) const;
313 #endif
314     static const char *typeToName(int typeId);
315     static Type nameToType(const char *name);
316
317     void *data();
318     const void *constData() const;
319     inline const void *data() const { return constData(); }
320
321     template<typename T>
322     inline void setValue(const T &value);
323
324     template<typename T>
325     inline T value() const
326     { return qvariant_cast<T>(*this); }
327
328     template<typename T>
329     static inline QVariant fromValue(const T &value)
330     { return qVariantFromValue(value); }
331
332     template<typename T>
333     bool canConvert() const
334     { return canConvert(qMetaTypeId<T>()); }
335
336  public:
337 #ifndef qdoc
338     struct PrivateShared
339     {
340         inline PrivateShared(void *v) : ptr(v), ref(1) { }
341         void *ptr;
342         QAtomicInt ref;
343     };
344     struct Private
345     {
346         inline Private(): type(Invalid), is_shared(false), is_null(true) { data.ptr = 0; }
347         inline Private(const Private &other)
348             : data(other.data), type(other.type),
349               is_shared(other.is_shared), is_null(other.is_null)
350         {}
351         union Data
352         {
353             char c;
354             uchar uc;
355             short s;
356             ushort us;
357             int i;
358             uint u;
359             long l;
360             ulong ul;
361             bool b;
362             double d;
363             float f;
364             qreal real;
365             qlonglong ll;
366             qulonglong ull;
367             QObject *o;
368             void *ptr;
369             PrivateShared *shared;
370         } data;
371         uint type : 30;
372         uint is_shared : 1;
373         uint is_null : 1;
374     };
375  public:
376     typedef void (*f_construct)(Private *, const void *);
377     typedef void (*f_clear)(Private *);
378     typedef bool (*f_null)(const Private *);
379 #ifndef QT_NO_DATASTREAM
380     typedef void (*f_load)(Private *, QDataStream &);
381     typedef void (*f_save)(const Private *, QDataStream &);
382 #endif
383     typedef bool (*f_compare)(const Private *, const Private *);
384     typedef bool (*f_convert)(const QVariant::Private *d, int t, void *, bool *);
385     typedef bool (*f_canConvert)(const QVariant::Private *d, int t);
386     typedef void (*f_debugStream)(QDebug, const QVariant &);
387     struct Handler {
388         f_construct construct;
389         f_clear clear;
390         f_null isNull;
391 #ifndef QT_NO_DATASTREAM
392         f_load load;
393         f_save save;
394 #endif
395         f_compare compare;
396         f_convert convert;
397         f_canConvert canConvert;
398         f_debugStream debugStream;
399     };
400 #endif
401
402     inline bool operator==(const QVariant &v) const
403     { return cmp(v); }
404     inline bool operator!=(const QVariant &v) const
405     { return !cmp(v); }
406
407 protected:
408     friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
409 #ifndef QT_NO_DEBUG_STREAM
410     friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
411 #endif
412 #ifndef Q_NO_TEMPLATE_FRIENDS
413     template<typename T>
414     friend inline T qvariant_cast(const QVariant &);
415     template<typename T> friend struct QtPrivate::QVariantValueHelper;
416 protected:
417 #else
418 public:
419 #endif
420     Private d;
421     void create(int type, const void *copy);
422     bool cmp(const QVariant &other) const;
423     bool convert(const int t, void *ptr) const;
424
425 private:
426     // force compile error, prevent QVariant(bool) to be called
427     inline QVariant(void *) Q_DECL_EQ_DELETE;
428 #ifdef QT_NO_CAST_FROM_ASCII
429     // force compile error when implicit conversion is not wanted
430     inline QVariant(const char *) Q_DECL_EQ_DELETE;
431 #endif
432 public:
433     typedef Private DataPtr;
434     inline DataPtr &data_ptr() { return d; }
435     inline const DataPtr &data_ptr() const { return d; }
436 };
437
438 template <typename T>
439 inline QVariant qVariantFromValue(const T &t)
440 {
441     return QVariant(qMetaTypeId<T>(reinterpret_cast<T *>(0)), &t, QTypeInfo<T>::isPointer);
442 }
443
444 template <>
445 inline QVariant qVariantFromValue(const QVariant &t) { return t; }
446
447 template <typename T>
448 inline void qVariantSetValue(QVariant &v, const T &t)
449 {
450     //if possible we reuse the current QVariant private
451     const uint type = qMetaTypeId<T>(reinterpret_cast<T *>(0));
452     QVariant::Private &d = v.data_ptr();
453     if (v.isDetached() && (type == d.type || (type <= uint(QVariant::Char) && d.type <= uint(QVariant::Char)))) {
454         d.type = type;
455         d.is_null = false;
456         T *old = reinterpret_cast<T*>(d.is_shared ? d.data.shared->ptr : &d.data.ptr);
457         if (QTypeInfo<T>::isComplex)
458             old->~T();
459         new (old) T(t); //call the copy constructor
460     } else {
461         v = QVariant(type, &t, QTypeInfo<T>::isPointer);
462     }
463 }
464
465 template <>
466 inline void qVariantSetValue<QVariant>(QVariant &v, const QVariant &t)
467 {
468     v = t;
469 }
470
471
472 inline QVariant::QVariant() {}
473 inline bool QVariant::isValid() const { return d.type != Invalid; }
474
475 template<typename T>
476 inline void QVariant::setValue(const T &avalue)
477 { qVariantSetValue(*this, avalue); }
478
479 #ifndef QT_NO_DATASTREAM
480 Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant& p);
481 Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant& p);
482 Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant::Type& p);
483 Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant::Type p);
484 #endif
485
486 inline bool QVariant::isDetached() const
487 { return !d.is_shared || d.data.shared->ref.load() == 1; }
488
489
490 #ifdef qdoc
491     inline bool operator==(const QVariant &v1, const QVariant &v2);
492     inline bool operator!=(const QVariant &v1, const QVariant &v2);
493 #else
494
495 /* Helper class to add one more level of indirection to prevent
496    implicit casts.
497 */
498 class QVariantComparisonHelper
499 {
500 public:
501     inline QVariantComparisonHelper(const QVariant &var)
502         : v(&var) {}
503 private:
504     friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
505     const QVariant *v;
506 };
507
508 inline bool operator==(const QVariant &v1, const QVariantComparisonHelper &v2)
509 {
510     return v1.cmp(*v2.v);
511 }
512
513 inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
514 {
515     return !operator==(v1, v2);
516 }
517 #endif
518
519 namespace QtPrivate {
520     template<typename T>
521     struct QVariantValueHelper : TreatAsQObjectBeforeMetaType<QVariantValueHelper<T>, T, const QVariant &, T>
522     {
523         static T metaType(const QVariant &v)
524         {
525             const int vid = qMetaTypeId<T>(static_cast<T *>(0));
526             if (vid == v.userType())
527                 return *reinterpret_cast<const T *>(v.constData());
528             if (vid < int(QMetaType::User)) {
529                 T t;
530                 if (v.convert(vid, &t))
531                     return t;
532             }
533             return T();
534         }
535 #ifndef QT_NO_QOBJECT
536         static T object(const QVariant &v)
537         {
538             return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject ? v.d.data.o : 0);
539         }
540 #endif
541     };
542 }
543
544 #ifndef QT_MOC
545 template<typename T> inline T qvariant_cast(const QVariant &v)
546 {
547     return QtPrivate::QVariantValueHelper<T>::invoke(v);
548 }
549
550 template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
551 {
552     if (v.userType() == QMetaType::QVariant)
553         return *reinterpret_cast<const QVariant *>(v.constData());
554     return v;
555 }
556
557 #if QT_DEPRECATED_SINCE(5, 0)
558 template<typename T>
559 inline QT_DEPRECATED T qVariantValue(const QVariant &variant)
560 { return qvariant_cast<T>(variant); }
561
562 template<typename T>
563 inline QT_DEPRECATED bool qVariantCanConvert(const QVariant &variant)
564 { return variant.template canConvert<T>(); }
565 #endif
566
567 #endif
568 Q_DECLARE_SHARED(QVariant)
569 Q_DECLARE_TYPEINFO(QVariant, Q_MOVABLE_TYPE);
570
571 #ifndef QT_NO_DEBUG_STREAM
572 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
573 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant::Type);
574 #endif
575
576 QT_END_NAMESPACE
577
578 QT_END_HEADER
579
580 #endif // QVARIANT_H