qvariant.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
00004 ** All rights reserved.
00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
00006 **
00007 ** This file is part of the QtCore module of the Qt Toolkit.
00008 **
00009 ** $QT_BEGIN_LICENSE:LGPL$
00010 ** Commercial Usage
00011 ** Licensees holding valid Qt Commercial licenses may use this file in
00012 ** accordance with the Qt Commercial License Agreement provided with the
00013 ** Software or, alternatively, in accordance with the terms contained in
00014 ** a written agreement between you and Nokia.
00015 **
00016 ** GNU Lesser General Public License Usage
00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
00018 ** General Public License version 2.1 as published by the Free Software
00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
00020 ** packaging of this file.  Please review the following information to
00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
00023 **
00024 ** In addition, as a special exception, Nokia gives you certain additional
00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
00027 **
00028 ** GNU General Public License Usage
00029 ** Alternatively, this file may be used under the terms of the GNU
00030 ** General Public License version 3.0 as published by the Free Software
00031 ** Foundation and appearing in the file LICENSE.GPL included in the
00032 ** packaging of this file.  Please review the following information to
00033 ** ensure the GNU General Public License version 3.0 requirements will be
00034 ** met: http://www.gnu.org/copyleft/gpl.html.
00035 **
00036 ** If you have questions regarding the use of this file, please contact
00037 ** Nokia at qt-info@nokia.com.
00038 ** $QT_END_LICENSE$
00039 **
00040 ****************************************************************************/
00041 
00042 #ifndef QVARIANT_H
00043 #define QVARIANT_H
00044 
00045 #include <QtCore/qatomic.h>
00046 #include <QtCore/qbytearray.h>
00047 #include <QtCore/qlist.h>
00048 #include <QtCore/qmetatype.h>
00049 #include <QtCore/qmap.h>
00050 #include <QtCore/qhash.h>
00051 #include <QtCore/qstring.h>
00052 
00053 QT_BEGIN_HEADER
00054 
00055 QT_BEGIN_NAMESPACE
00056 
00057 QT_MODULE(Core)
00058 
00059 class QBitArray;
00060 class QDataStream;
00061 class QDate;
00062 class QDateTime;
00063 class QEasingCurve;
00064 class QLine;
00065 class QLineF;
00066 class QLocale;
00067 class QMatrix;
00068 class QTransform;
00069 class QStringList;
00070 class QTime;
00071 class QPoint;
00072 class QPointF;
00073 class QSize;
00074 class QSizeF;
00075 class QRect;
00076 class QRectF;
00077 #ifndef QT_NO_REGEXP
00078 class QRegExp;
00079 #endif
00080 class QTextFormat;
00081 class QTextLength;
00082 class QUrl;
00083 class QVariant;
00084 class QVariantComparisonHelper;
00085 
00086 #ifndef QT_NO_MEMBER_TEMPLATES
00087 template <typename T>
00088 inline QVariant qVariantFromValue(const T &);
00089 
00090 template <typename T>
00091 inline void qVariantSetValue(QVariant &, const T &);
00092 
00093 template<typename T>
00094 inline T qVariantValue(const QVariant &);
00095 
00096 template<typename T>
00097 inline bool qVariantCanConvert(const QVariant &);
00098 #endif
00099 
00100 class Q_CORE_EXPORT QVariant
00101 {
00102  public:
00103     enum Type {
00104         Invalid = 0,
00105 
00106         Bool = 1,
00107         Int = 2,
00108         UInt = 3,
00109         LongLong = 4,
00110         ULongLong = 5,
00111         Double = 6,
00112         Char = 7,
00113         Map = 8,
00114         List = 9,
00115         String = 10,
00116         StringList = 11,
00117         ByteArray = 12,
00118         BitArray = 13,
00119         Date = 14,
00120         Time = 15,
00121         DateTime = 16,
00122         Url = 17,
00123         Locale = 18,
00124         Rect = 19,
00125         RectF = 20,
00126         Size = 21,
00127         SizeF = 22,
00128         Line = 23,
00129         LineF = 24,
00130         Point = 25,
00131         PointF = 26,
00132         RegExp = 27,
00133         Hash = 28,
00134         EasingCurve = 29,
00135         LastCoreType = EasingCurve,
00136 
00137         // value 62 is internally reserved
00138 #ifdef QT3_SUPPORT
00139         ColorGroup = 63,
00140 #endif
00141         Font = 64,
00142         Pixmap = 65,
00143         Brush = 66,
00144         Color = 67,
00145         Palette = 68,
00146         Icon = 69,
00147         Image = 70,
00148         Polygon = 71,
00149         Region = 72,
00150         Bitmap = 73,
00151         Cursor = 74,
00152         SizePolicy = 75,
00153         KeySequence = 76,
00154         Pen = 77,
00155         TextLength = 78,
00156         TextFormat = 79,
00157         Matrix = 80,
00158         Transform = 81,
00159         Matrix4x4 = 82,
00160         Vector2D = 83,
00161         Vector3D = 84,
00162         Vector4D = 85,
00163         Quaternion = 86,
00164         LastGuiType = Quaternion,
00165 
00166         UserType = 127,
00167 #ifdef QT3_SUPPORT
00168         IconSet = Icon,
00169         CString = ByteArray,
00170         PointArray = Polygon,
00171 #endif
00172         LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
00173     };
00174 
00175     inline QVariant();
00176     ~QVariant();
00177     QVariant(Type type);
00178     QVariant(int typeOrUserType, const void *copy);
00179     QVariant(int typeOrUserType, const void *copy, uint flags);
00180     QVariant(const QVariant &other);
00181 
00182 #ifndef QT_NO_DATASTREAM
00183     QVariant(QDataStream &s);
00184 #endif
00185 
00186     QVariant(int i);
00187     QVariant(uint ui);
00188     QVariant(qlonglong ll);
00189     QVariant(qulonglong ull);
00190     QVariant(bool b);
00191     QVariant(double d);
00192     QVariant(float f) { d.is_null = false; d.type = QMetaType::Float; d.data.f = f; }
00193 #ifndef QT_NO_CAST_FROM_ASCII
00194     QT_ASCII_CAST_WARN_CONSTRUCTOR QVariant(const char *str);
00195 #endif
00196 
00197     QVariant(const QByteArray &bytearray);
00198     QVariant(const QBitArray &bitarray);
00199     QVariant(const QString &string);
00200     QVariant(const QLatin1String &string);
00201     QVariant(const QStringList &stringlist);
00202     QVariant(const QChar &qchar);
00203     QVariant(const QDate &date);
00204     QVariant(const QTime &time);
00205     QVariant(const QDateTime &datetime);
00206     QVariant(const QList<QVariant> &list);
00207     QVariant(const QMap<QString,QVariant> &map);
00208     QVariant(const QHash<QString,QVariant> &hash);
00209 #ifndef QT_NO_GEOM_VARIANT
00210     QVariant(const QSize &size);
00211     QVariant(const QSizeF &size);
00212     QVariant(const QPoint &pt);
00213     QVariant(const QPointF &pt);
00214     QVariant(const QLine &line);
00215     QVariant(const QLineF &line);
00216     QVariant(const QRect &rect);
00217     QVariant(const QRectF &rect);
00218 #endif
00219     QVariant(const QUrl &url);
00220     QVariant(const QLocale &locale);
00221 #ifndef QT_NO_REGEXP
00222     QVariant(const QRegExp &regExp);
00223 #endif
00224 #ifndef QT_BOOTSTRAPPED
00225     QVariant(const QEasingCurve &easing);
00226 #endif
00227     QVariant(Qt::GlobalColor color);
00228 
00229     QVariant& operator=(const QVariant &other);
00230 
00231     Type type() const;
00232     int userType() const;
00233     const char *typeName() const;
00234 
00235     bool canConvert(Type t) const;
00236     bool convert(Type t);
00237 
00238 #ifdef QT3_SUPPORT
00239     inline QT3_SUPPORT bool canCast(Type t) const
00240     { return canConvert(t); }
00241     inline QT3_SUPPORT bool cast(Type t)
00242     { return convert(t); }
00243 #endif
00244 
00245     inline bool isValid() const;
00246     bool isNull() const;
00247 
00248     void clear();
00249 
00250     void detach();
00251     inline bool isDetached() const;
00252 
00253     int toInt(bool *ok = 0) const;
00254     uint toUInt(bool *ok = 0) const;
00255     qlonglong toLongLong(bool *ok = 0) const;
00256     qulonglong toULongLong(bool *ok = 0) const;
00257     bool toBool() const;
00258     double toDouble(bool *ok = 0) const;
00259     float toFloat(bool *ok = 0) const;
00260     qreal toReal(bool *ok = 0) const;
00261     QByteArray toByteArray() const;
00262     QBitArray toBitArray() const;
00263     QString toString() const;
00264     QStringList toStringList() const;
00265     QChar toChar() const;
00266     QDate toDate() const;
00267     QTime toTime() const;
00268     QDateTime toDateTime() const;
00269     QList<QVariant> toList() const;
00270     QMap<QString, QVariant> toMap() const;
00271     QHash<QString, QVariant> toHash() const;
00272 
00273 #ifndef QT_NO_GEOM_VARIANT
00274     QPoint toPoint() const;
00275     QPointF toPointF() const;
00276     QRect toRect() const;
00277     QSize toSize() const;
00278     QSizeF toSizeF() const;
00279     QLine toLine() const;
00280     QLineF toLineF() const;
00281     QRectF toRectF() const;
00282 #endif
00283     QUrl toUrl() const;
00284     QLocale toLocale() const;
00285 #ifndef QT_NO_REGEXP
00286     QRegExp toRegExp() const;
00287 #endif
00288 #ifndef QT_BOOTSTRAPPED
00289     QEasingCurve toEasingCurve() const;
00290 #endif
00291 
00292 #ifdef QT3_SUPPORT
00293     inline QT3_SUPPORT int &asInt();
00294     inline QT3_SUPPORT uint &asUInt();
00295     inline QT3_SUPPORT qlonglong &asLongLong();
00296     inline QT3_SUPPORT qulonglong &asULongLong();
00297     inline QT3_SUPPORT bool &asBool();
00298     inline QT3_SUPPORT double &asDouble();
00299     inline QT3_SUPPORT QByteArray &asByteArray();
00300     inline QT3_SUPPORT QBitArray &asBitArray();
00301     inline QT3_SUPPORT QString &asString();
00302     inline QT3_SUPPORT QStringList &asStringList();
00303     inline QT3_SUPPORT QDate &asDate();
00304     inline QT3_SUPPORT QTime &asTime();
00305     inline QT3_SUPPORT QDateTime &asDateTime();
00306     inline QT3_SUPPORT QList<QVariant> &asList();
00307     inline QT3_SUPPORT QMap<QString,QVariant> &asMap();
00308     inline QT3_SUPPORT QPoint &asPoint();
00309     inline QT3_SUPPORT QRect &asRect();
00310     inline QT3_SUPPORT QSize &asSize();
00311 #endif //QT3_SUPPORT
00312 
00313 #ifndef QT_NO_DATASTREAM
00314     void load(QDataStream &ds);
00315     void save(QDataStream &ds) const;
00316 #endif
00317     static const char *typeToName(Type type);
00318     static Type nameToType(const char *name);
00319 
00320 #ifdef QT3_SUPPORT
00321     inline QT3_SUPPORT_CONSTRUCTOR QVariant(bool val, int) { create(Bool, &val); }
00322     inline QT3_SUPPORT const QByteArray toCString() const { return toByteArray(); }
00323     inline QT3_SUPPORT QByteArray &asCString() { return *reinterpret_cast<QByteArray *>(castOrDetach(ByteArray)); }
00324 #endif
00325 
00326     void *data();
00327     const void *constData() const;
00328     inline const void *data() const { return constData(); }
00329 
00330 #ifndef QT_NO_MEMBER_TEMPLATES
00331     template<typename T>
00332     inline void setValue(const T &value);
00333 
00334     template<typename T>
00335     inline T value() const
00336     { return qVariantValue<T>(*this); }
00337 
00338     template<typename T>
00339     static inline QVariant fromValue(const T &value)
00340     { return qVariantFromValue(value); }
00341 
00342     template<typename T>
00343     bool canConvert() const
00344     { return qVariantCanConvert<T>(*this); }
00345 #endif
00346 
00347  public:
00348 #ifndef qdoc
00349     struct PrivateShared
00350     {
00351         inline PrivateShared(void *v) : ptr(v), ref(1) { }
00352         void *ptr;
00353         QAtomicInt ref;
00354     };
00355     struct Private
00356     {
00357         inline Private(): type(Invalid), is_shared(false), is_null(true) { data.ptr = 0; }
00358         inline Private(const Private &other)
00359             : data(other.data), type(other.type),
00360               is_shared(other.is_shared), is_null(other.is_null)
00361         {}
00362         union Data
00363         {
00364             char c;
00365             int i;
00366             uint u;
00367             bool b;
00368             double d;
00369             float f;
00370             qreal real;
00371             qlonglong ll;
00372             qulonglong ull;
00373             QObject *o;
00374             void *ptr;
00375             PrivateShared *shared;
00376         } data;
00377         uint type : 30;
00378         uint is_shared : 1;
00379         uint is_null : 1;
00380     };
00381  public:
00382     typedef void (*f_construct)(Private *, const void *);
00383     typedef void (*f_clear)(Private *);
00384     typedef bool (*f_null)(const Private *);
00385 #ifndef QT_NO_DATASTREAM
00386     typedef void (*f_load)(Private *, QDataStream &);
00387     typedef void (*f_save)(const Private *, QDataStream &);
00388 #endif
00389     typedef bool (*f_compare)(const Private *, const Private *);
00390     typedef bool (*f_convert)(const QVariant::Private *d, Type t, void *, bool *);
00391     typedef bool (*f_canConvert)(const QVariant::Private *d, Type t);
00392     typedef void (*f_debugStream)(QDebug, const QVariant &);
00393     struct Handler {
00394         f_construct construct;
00395         f_clear clear;
00396         f_null isNull;
00397 #ifndef QT_NO_DATASTREAM
00398         f_load load;
00399         f_save save;
00400 #endif
00401         f_compare compare;
00402         f_convert convert;
00403         f_canConvert canConvert;
00404         f_debugStream debugStream;
00405     };
00406 #endif
00407 
00408     inline bool operator==(const QVariant &v) const
00409     { return cmp(v); }
00410     inline bool operator!=(const QVariant &v) const
00411     { return !cmp(v); }
00412 
00413 protected:
00414     friend inline bool qvariant_cast_helper(const QVariant &, QVariant::Type, void *);
00415     friend int qRegisterGuiVariant();
00416     friend int qUnregisterGuiVariant();
00417     friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
00418 #ifndef QT_NO_DEBUG_STREAM
00419     friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
00420 #endif
00421     Private d;
00422 
00423     static const Handler *handler;
00424 
00425     void create(int type, const void *copy);
00426 #ifdef QT3_SUPPORT
00427     void *castOrDetach(Type t);
00428 #endif
00429     bool cmp(const QVariant &other) const;
00430 
00431 private:
00432     // force compile error, prevent QVariant(bool) to be called
00433     inline QVariant(void *) { Q_ASSERT(false); }
00434 #ifdef QT_NO_CAST_FROM_ASCII
00435     // force compile error when implicit conversion is not wanted
00436     inline QVariant(const char *) { Q_ASSERT(false); }
00437 #endif
00438 #ifndef QT3_SUPPORT
00439     // force compile error, prevent QVariant(QVariant::Type, int) to be called
00440     inline QVariant(bool, int) { Q_ASSERT(false); }
00441 #endif
00442 public:
00443     typedef Private DataPtr;
00444     inline DataPtr &data_ptr() { return d; }
00445 };
00446 
00447 typedef QList<QVariant> QVariantList;
00448 typedef QMap<QString, QVariant> QVariantMap;
00449 typedef QHash<QString, QVariant> QVariantHash;
00450 
00451 inline bool qvariant_cast_helper(const QVariant &v, QVariant::Type tp, void *ptr)
00452 { return QVariant::handler->convert(&v.d, tp, ptr, 0); }
00453 
00454 template <typename T>
00455 inline QVariant qVariantFromValue(const T &t)
00456 {
00457     return QVariant(qMetaTypeId<T>(reinterpret_cast<T *>(0)), &t, QTypeInfo<T>::isPointer);
00458 }
00459 
00460 template <>
00461 inline QVariant qVariantFromValue(const QVariant &t) { return t; }
00462 
00463 template <typename T>
00464 inline void qVariantSetValue(QVariant &v, const T &t)
00465 {
00466     //if possible we reuse the current QVariant private
00467     const uint type = qMetaTypeId<T>(reinterpret_cast<T *>(0));
00468     QVariant::Private &d = v.data_ptr();
00469     if (v.isDetached() && (type == d.type || (type <= uint(QVariant::Char) && d.type <= uint(QVariant::Char)))) {
00470         d.type = type;
00471         d.is_null = false;
00472         T *old = reinterpret_cast<T*>(d.is_shared ? d.data.shared->ptr : &d.data.ptr);
00473         if (QTypeInfo<T>::isComplex)
00474             old->~T();
00475         new (old) T(t); //call the copy constructor
00476     } else {
00477         v = QVariant(type, &t, QTypeInfo<T>::isPointer);
00478     }
00479 }
00480 
00481 template <>
00482 inline void qVariantSetValue<QVariant>(QVariant &v, const QVariant &t)
00483 {
00484     v = t;
00485 }
00486 
00487 
00488 inline QVariant::QVariant() {}
00489 inline bool QVariant::isValid() const { return d.type != Invalid; }
00490 
00491 #ifdef QT3_SUPPORT
00492 inline int &QVariant::asInt()
00493 { return *reinterpret_cast<int *>(castOrDetach(Int)); }
00494 inline uint &QVariant::asUInt()
00495 { return *reinterpret_cast<uint *>(castOrDetach(UInt)); }
00496 inline qlonglong &QVariant::asLongLong()
00497 { return *reinterpret_cast<qlonglong *>(castOrDetach(LongLong)); }
00498 inline qulonglong &QVariant::asULongLong()
00499 { return *reinterpret_cast<qulonglong *>(castOrDetach(ULongLong)); }
00500 inline bool &QVariant::asBool()
00501 { return *reinterpret_cast<bool *>(castOrDetach(Bool)); }
00502 inline double &QVariant::asDouble()
00503 { return *reinterpret_cast<double *>(castOrDetach(Double)); }
00504 inline QByteArray& QVariant::asByteArray()
00505 { return *reinterpret_cast<QByteArray *>(castOrDetach(ByteArray)); }
00506 inline QBitArray& QVariant::asBitArray()
00507 { return *reinterpret_cast<QBitArray *>(castOrDetach(BitArray)); }
00508 inline QString& QVariant::asString()
00509 { return *reinterpret_cast<QString *>(castOrDetach(String)); }
00510 inline QStringList& QVariant::asStringList()
00511 { return *reinterpret_cast<QStringList *>(castOrDetach(StringList)); }
00512 inline QDate& QVariant::asDate()
00513 { return *reinterpret_cast<QDate *>(castOrDetach(Date)); }
00514 inline QTime& QVariant::asTime()
00515 { return *reinterpret_cast<QTime *>(castOrDetach(Time)); }
00516 inline QDateTime& QVariant::asDateTime()
00517 { return *reinterpret_cast<QDateTime *>(castOrDetach(DateTime)); }
00518 inline QList<QVariant>& QVariant::asList()
00519 { return *reinterpret_cast<QList<QVariant> *>(castOrDetach(List)); }
00520 inline QMap<QString, QVariant>& QVariant::asMap()
00521 { return *reinterpret_cast<QMap<QString, QVariant> *>(castOrDetach(Map)); }
00522 inline QPoint &QVariant::asPoint()
00523 { return *reinterpret_cast<QPoint *>(castOrDetach(Point)); }
00524 inline QRect &QVariant::asRect()
00525 { return *reinterpret_cast<QRect *>(castOrDetach(Rect)); }
00526 inline QSize &QVariant::asSize()
00527 { return *reinterpret_cast<QSize *>(castOrDetach(Size)); }
00528 #endif //QT3_SUPPORT
00529 
00530 #ifndef QT_NO_MEMBER_TEMPLATES
00531 template<typename T>
00532 inline void QVariant::setValue(const T &avalue)
00533 { qVariantSetValue(*this, avalue); }
00534 #endif
00535 
00536 #ifndef QT_NO_DATASTREAM
00537 Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant& p);
00538 Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant& p);
00539 Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant::Type& p);
00540 Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant::Type p);
00541 #endif
00542 
00543 inline bool QVariant::isDetached() const
00544 { return !d.is_shared || d.data.shared->ref == 1; }
00545 
00546 
00547 #ifdef qdoc
00548     inline bool operator==(const QVariant &v1, const QVariant &v2);
00549     inline bool operator!=(const QVariant &v1, const QVariant &v2);
00550 #else
00551 
00552 /* Helper class to add one more level of indirection to prevent
00553    implicit casts.
00554 */
00555 class QVariantComparisonHelper
00556 {
00557 public:
00558     inline QVariantComparisonHelper(const QVariant &var)
00559         : v(&var) {}
00560 private:
00561     friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
00562     const QVariant *v;
00563 };
00564 
00565 inline bool operator==(const QVariant &v1, const QVariantComparisonHelper &v2)
00566 {
00567     return v1.cmp(*v2.v);
00568 }
00569 
00570 inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
00571 {
00572     return !operator==(v1, v2);
00573 }
00574 #endif
00575 
00576 #ifndef QT_MOC
00577 template<typename T> inline T qvariant_cast(const QVariant &v)
00578 {
00579     const int vid = qMetaTypeId<T>(static_cast<T *>(0));
00580     if (vid == v.userType())
00581         return *reinterpret_cast<const T *>(v.constData());
00582     if (vid < int(QMetaType::User)) {
00583         T t;
00584         if (qvariant_cast_helper(v, QVariant::Type(vid), &t))
00585             return t;
00586     }
00587     return T();
00588 }
00589 
00590 template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
00591 {
00592     if (v.userType() == QMetaType::QVariant)
00593         return *reinterpret_cast<const QVariant *>(v.constData());
00594     return v;
00595 }
00596 
00597 template<typename T>
00598 inline T qVariantValue(const QVariant &variant)
00599 { return qvariant_cast<T>(variant); }
00600 
00601 template<typename T>
00602 inline bool qVariantCanConvert(const QVariant &variant)
00603 {
00604     return variant.canConvert(static_cast<QVariant::Type>(
00605                 qMetaTypeId<T>(static_cast<T *>(0))));
00606 }
00607 #endif
00608 Q_DECLARE_SHARED(QVariant)
00609 Q_DECLARE_TYPEINFO(QVariant, Q_MOVABLE_TYPE);
00610 
00611 #ifndef QT_NO_DEBUG_STREAM
00612 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
00613 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant::Type);
00614 #endif
00615 
00616 QT_END_NAMESPACE
00617 
00618 Q_DECLARE_BUILTIN_METATYPE(QVariantList, QVariantList)
00619 Q_DECLARE_BUILTIN_METATYPE(QVariantMap, QVariantMap)
00620 Q_DECLARE_BUILTIN_METATYPE(QVariantHash, QVariantHash)
00621 
00622 QT_END_HEADER
00623 
00624 #endif // QVARIANT_H