src/corelib/kernel/qvariant.h
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtCore module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    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 
       
    53 QT_BEGIN_HEADER
       
    54 
       
    55 QT_BEGIN_NAMESPACE
       
    56 
       
    57 QT_MODULE(Core)
       
    58 
       
    59 class QBitArray;
       
    60 class QDataStream;
       
    61 class QDate;
       
    62 class QDateTime;
       
    63 class QLine;
       
    64 class QLineF;
       
    65 class QLocale;
       
    66 class QMatrix;
       
    67 class QTransform;
       
    68 class QStringList;
       
    69 class QTime;
       
    70 class QPoint;
       
    71 class QPointF;
       
    72 class QSize;
       
    73 class QSizeF;
       
    74 class QRect;
       
    75 class QRectF;
       
    76 #ifndef QT_NO_REGEXP
       
    77 class QRegExp;
       
    78 #endif
       
    79 class QTextFormat;
       
    80 class QTextLength;
       
    81 class QUrl;
       
    82 class QVariant;
       
    83 class QVariantComparisonHelper;
       
    84 
       
    85 #ifndef QT_NO_MEMBER_TEMPLATES
       
    86 template <typename T>
       
    87 inline QVariant qVariantFromValue(const T &);
       
    88 
       
    89 template <typename T>
       
    90 inline void qVariantSetValue(QVariant &, const T &);
       
    91 
       
    92 template<typename T>
       
    93 inline T qVariantValue(const QVariant &);
       
    94 
       
    95 template<typename T>
       
    96 inline bool qVariantCanConvert(const QVariant &);
       
    97 #endif
       
    98 
       
    99 class 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 
       
   405 protected:
       
   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 
       
   423 private:
       
   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
       
   434 public:
       
   435     typedef Private DataPtr;
       
   436     inline DataPtr &data_ptr() { return d; }
       
   437 };
       
   438 
       
   439 typedef QList<QVariant> QVariantList;
       
   440 typedef QMap<QString, QVariant> QVariantMap;
       
   441 typedef QHash<QString, QVariant> QVariantHash;
       
   442 
       
   443 inline bool qvariant_cast_helper(const QVariant &v, QVariant::Type tp, void *ptr)
       
   444 { return QVariant::handler->convert(&v.d, tp, ptr, 0); }
       
   445 
       
   446 template <typename T>
       
   447 inline QVariant qVariantFromValue(const T &t)
       
   448 {
       
   449     return QVariant(qMetaTypeId<T>(reinterpret_cast<T *>(0)), &t, QTypeInfo<T>::isPointer);
       
   450 }
       
   451 
       
   452 template <>
       
   453 inline QVariant qVariantFromValue(const QVariant &t) { return t; }
       
   454 
       
   455 template <typename T>
       
   456 inline void qVariantSetValue(QVariant &v, const T &t)
       
   457 {
       
   458     //if possible we reuse the current QVariant private
       
   459     const int type = qMetaTypeId<T>(reinterpret_cast<T *>(0));
       
   460     QVariant::Private &d = v.data_ptr();
       
   461     if (v.isDetached() && (type <= int(QVariant::Char) || type == d.type)) {
       
   462         d.type = type;
       
   463         T *old = reinterpret_cast<T*>(d.is_shared ? d.data.shared->ptr : &d.data.ptr);
       
   464         if (QTypeInfo<T>::isComplex)
       
   465             old->~T();
       
   466         new (old) T(t); //call the copy constructor
       
   467     } else {
       
   468         v = QVariant(type, &t, QTypeInfo<T>::isPointer);
       
   469     }
       
   470 }
       
   471 
       
   472 inline QVariant::QVariant() {}
       
   473 inline bool QVariant::isValid() const { return d.type != Invalid; }
       
   474 
       
   475 #ifdef QT3_SUPPORT
       
   476 inline int &QVariant::asInt()
       
   477 { return *reinterpret_cast<int *>(castOrDetach(Int)); }
       
   478 inline uint &QVariant::asUInt()
       
   479 { return *reinterpret_cast<uint *>(castOrDetach(UInt)); }
       
   480 inline qlonglong &QVariant::asLongLong()
       
   481 { return *reinterpret_cast<qlonglong *>(castOrDetach(LongLong)); }
       
   482 inline qulonglong &QVariant::asULongLong()
       
   483 { return *reinterpret_cast<qulonglong *>(castOrDetach(ULongLong)); }
       
   484 inline bool &QVariant::asBool()
       
   485 { return *reinterpret_cast<bool *>(castOrDetach(Bool)); }
       
   486 inline double &QVariant::asDouble()
       
   487 { return *reinterpret_cast<double *>(castOrDetach(Double)); }
       
   488 inline QByteArray& QVariant::asByteArray()
       
   489 { return *reinterpret_cast<QByteArray *>(castOrDetach(ByteArray)); }
       
   490 inline QBitArray& QVariant::asBitArray()
       
   491 { return *reinterpret_cast<QBitArray *>(castOrDetach(BitArray)); }
       
   492 inline QString& QVariant::asString()
       
   493 { return *reinterpret_cast<QString *>(castOrDetach(String)); }
       
   494 inline QStringList& QVariant::asStringList()
       
   495 { return *reinterpret_cast<QStringList *>(castOrDetach(StringList)); }
       
   496 inline QDate& QVariant::asDate()
       
   497 { return *reinterpret_cast<QDate *>(castOrDetach(Date)); }
       
   498 inline QTime& QVariant::asTime()
       
   499 { return *reinterpret_cast<QTime *>(castOrDetach(Time)); }
       
   500 inline QDateTime& QVariant::asDateTime()
       
   501 { return *reinterpret_cast<QDateTime *>(castOrDetach(DateTime)); }
       
   502 inline QList<QVariant>& QVariant::asList()
       
   503 { return *reinterpret_cast<QList<QVariant> *>(castOrDetach(List)); }
       
   504 inline QMap<QString, QVariant>& QVariant::asMap()
       
   505 { return *reinterpret_cast<QMap<QString, QVariant> *>(castOrDetach(Map)); }
       
   506 inline QPoint &QVariant::asPoint()
       
   507 { return *reinterpret_cast<QPoint *>(castOrDetach(Point)); }
       
   508 inline QRect &QVariant::asRect()
       
   509 { return *reinterpret_cast<QRect *>(castOrDetach(Rect)); }
       
   510 inline QSize &QVariant::asSize()
       
   511 { return *reinterpret_cast<QSize *>(castOrDetach(Size)); }
       
   512 #endif //QT3_SUPPORT
       
   513 
       
   514 #ifndef QT_NO_MEMBER_TEMPLATES
       
   515 template<typename T>
       
   516 inline void QVariant::setValue(const T &avalue)
       
   517 { qVariantSetValue(*this, avalue); }
       
   518 #endif
       
   519 
       
   520 #ifndef QT_NO_DATASTREAM
       
   521 Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant& p);
       
   522 Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant& p);
       
   523 Q_CORE_EXPORT QDataStream& operator>> (QDataStream& s, QVariant::Type& p);
       
   524 Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant::Type p);
       
   525 #endif
       
   526 
       
   527 inline bool QVariant::isDetached() const
       
   528 { return !d.is_shared || d.data.shared->ref == 1; }
       
   529 
       
   530 
       
   531 #ifdef qdoc
       
   532     inline bool operator==(const QVariant &v1, const QVariant &v2);
       
   533     inline bool operator!=(const QVariant &v1, const QVariant &v2);
       
   534 #else
       
   535 
       
   536 /* Helper class to add one more level of indirection to prevent
       
   537    implicit casts.
       
   538 */
       
   539 class QVariantComparisonHelper
       
   540 {
       
   541 public:
       
   542     inline QVariantComparisonHelper(const QVariant &var)
       
   543         : v(&var) {}
       
   544 private:
       
   545     friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
       
   546     const QVariant *v;
       
   547 };
       
   548 
       
   549 inline bool operator==(const QVariant &v1, const QVariantComparisonHelper &v2)
       
   550 {
       
   551     return v1.cmp(*v2.v);
       
   552 }
       
   553 
       
   554 inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
       
   555 {
       
   556     return !operator==(v1, v2);
       
   557 }
       
   558 #endif
       
   559 
       
   560 #ifndef QT_MOC
       
   561 #if !defined qdoc && defined Q_CC_MSVC && _MSC_VER < 1300
       
   562 
       
   563 template<typename T> T qvariant_cast(const QVariant &v, T * = 0)
       
   564 {
       
   565     const int vid = qMetaTypeId<T>(static_cast<T *>(0));
       
   566     if (vid == v.userType())
       
   567         return *reinterpret_cast<const T *>(v.constData());
       
   568     if (vid < int(QMetaType::User)) {
       
   569         T t;
       
   570         if (qvariant_cast_helper(v, QVariant::Type(vid), &t))
       
   571             return t;
       
   572     }
       
   573     return T();
       
   574 }
       
   575 
       
   576 template<typename T>
       
   577 inline T qVariantValue(const QVariant &variant, T *t = 0)
       
   578 { return qvariant_cast<T>(variant, t); }
       
   579 
       
   580 template<typename T>
       
   581 inline bool qVariantCanConvert(const QVariant &variant, T *t = 0)
       
   582 {
       
   583     return variant.canConvert(static_cast<QVariant::Type>(qMetaTypeId<T>(t)));
       
   584 }
       
   585 #else
       
   586 
       
   587 template<typename T> T qvariant_cast(const QVariant &v)
       
   588 {
       
   589     const int vid = qMetaTypeId<T>(static_cast<T *>(0));
       
   590     if (vid == v.userType())
       
   591         return *reinterpret_cast<const T *>(v.constData());
       
   592     if (vid < int(QMetaType::User)) {
       
   593         T t;
       
   594         if (qvariant_cast_helper(v, QVariant::Type(vid), &t))
       
   595             return t;
       
   596     }
       
   597     return T();
       
   598 }
       
   599 
       
   600 template<typename T>
       
   601 inline T qVariantValue(const QVariant &variant)
       
   602 { return qvariant_cast<T>(variant); }
       
   603 
       
   604 template<typename T>
       
   605 inline bool qVariantCanConvert(const QVariant &variant)
       
   606 {
       
   607     return variant.canConvert(static_cast<QVariant::Type>(
       
   608                 qMetaTypeId<T>(static_cast<T *>(0))));
       
   609 }
       
   610 #endif
       
   611 #endif
       
   612 Q_DECLARE_SHARED(QVariant)
       
   613 Q_DECLARE_TYPEINFO(QVariant, Q_MOVABLE_TYPE);
       
   614 
       
   615 #ifndef QT_NO_DEBUG_STREAM
       
   616 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
       
   617 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant::Type);
       
   618 #endif
       
   619 
       
   620 QT_END_NAMESPACE
       
   621 
       
   622 Q_DECLARE_BUILTIN_METATYPE(QVariantList, QVariantList)
       
   623 Q_DECLARE_BUILTIN_METATYPE(QVariantMap, QVariantMap)
       
   624 Q_DECLARE_BUILTIN_METATYPE(QVariantHash, QVariantHash)
       
   625 
       
   626 QT_END_HEADER
       
   627 
       
   628 #endif // QVARIANT_H