src/corelib/kernel/qmetatype.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
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 #include "qmetatype.h"
       
    43 #include "qobjectdefs.h"
       
    44 #include "qdatetime.h"
       
    45 #include "qbytearray.h"
       
    46 #include "qreadwritelock.h"
       
    47 #include "qstring.h"
       
    48 #include "qstringlist.h"
       
    49 #include "qvector.h"
       
    50 #include "qlocale.h"
       
    51 
       
    52 #ifdef QT_BOOTSTRAPPED
       
    53 # ifndef QT_NO_GEOM_VARIANT
       
    54 #  define QT_NO_GEOM_VARIANT
       
    55 # endif
       
    56 #else
       
    57 #  include "qbitarray.h"
       
    58 #  include "qurl.h"
       
    59 #  include "qvariant.h"
       
    60 #endif
       
    61 
       
    62 #ifndef QT_NO_GEOM_VARIANT
       
    63 # include "qsize.h"
       
    64 # include "qpoint.h"
       
    65 # include "qrect.h"
       
    66 # include "qline.h"
       
    67 #endif
       
    68 
       
    69 QT_BEGIN_NAMESPACE
       
    70 
       
    71 #define NS(x) QT_PREPEND_NAMESPACE(x)
       
    72 
       
    73 /*!
       
    74     \macro Q_DECLARE_METATYPE(Type)
       
    75     \relates QMetaType
       
    76 
       
    77     This macro makes the type \a Type known to QMetaType as long as it
       
    78     provides a public default constructor, a public copy constructor and
       
    79     a public destructor.
       
    80     It is needed to use the type \a Type as a custom type in QVariant.
       
    81 
       
    82     Ideally, this macro should be placed below the declaration of
       
    83     the class or struct. If that is not possible, it can be put in
       
    84     a private header file which has to be included every time that
       
    85     type is used in a QVariant.
       
    86 
       
    87     Adding a Q_DECLARE_METATYPE() makes the type known to all template
       
    88     based functions, including QVariant. Note that if you intend to
       
    89     use the type in \e queued signal and slot connections or in
       
    90     QObject's property system, you also have to call
       
    91     qRegisterMetaType() since the names are resolved at runtime.
       
    92 
       
    93     This example shows a typical use case of Q_DECLARE_METATYPE():
       
    94 
       
    95     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 0
       
    96 
       
    97     If \c MyStruct is in a namespace, the Q_DECLARE_METATYPE() macro
       
    98     has to be outside the namespace:
       
    99 
       
   100     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 1
       
   101 
       
   102     Since \c{MyStruct} is now known to QMetaType, it can be used in QVariant:
       
   103 
       
   104     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 2
       
   105 
       
   106     \sa qRegisterMetaType()
       
   107 */
       
   108 
       
   109 /*!
       
   110     \enum QMetaType::Type
       
   111 
       
   112     These are the built-in types supported by QMetaType:
       
   113 
       
   114     \value Void \c void
       
   115     \value Bool \c bool
       
   116     \value Int \c int
       
   117     \value UInt \c{unsigned int}
       
   118     \value Double \c double
       
   119     \value QChar QChar
       
   120     \value QString QString
       
   121     \value QByteArray QByteArray
       
   122 
       
   123     \value VoidStar \c{void *}
       
   124     \value Long \c{long}
       
   125     \value LongLong LongLong
       
   126     \value Short \c{short}
       
   127     \value Char \c{char}
       
   128     \value ULong \c{unsigned long}
       
   129     \value ULongLong ULongLong
       
   130     \value UShort \c{unsigned short}
       
   131     \value UChar \c{unsigned char}
       
   132     \value Float \c float
       
   133     \value QObjectStar QObject *
       
   134     \value QWidgetStar QWidget *
       
   135 
       
   136     \value QColorGroup QColorGroup
       
   137     \value QCursor QCursor
       
   138     \value QDate QDate
       
   139     \value QSize QSize
       
   140     \value QTime QTime
       
   141     \value QVariantList QVariantList
       
   142     \value QPolygon QPolygon
       
   143     \value QColor QColor
       
   144     \value QSizeF QSizeF
       
   145     \value QRectF QRectF
       
   146     \value QLine QLine
       
   147     \value QTextLength QTextLength
       
   148     \value QStringList QStringList
       
   149     \value QVariantMap QVariantMap
       
   150     \value QVariantHash QVariantHash
       
   151     \value QIcon QIcon
       
   152     \value QPen QPen
       
   153     \value QLineF QLineF
       
   154     \value QTextFormat QTextFormat
       
   155     \value QRect QRect
       
   156     \value QPoint QPoint
       
   157     \value QUrl QUrl
       
   158     \value QRegExp QRegExp
       
   159     \value QDateTime QDateTime
       
   160     \value QPointF QPointF
       
   161     \value QPalette QPalette
       
   162     \value QFont QFont
       
   163     \value QBrush QBrush
       
   164     \value QRegion QRegion
       
   165     \value QBitArray QBitArray
       
   166     \value QImage QImage
       
   167     \value QKeySequence QKeySequence
       
   168     \value QSizePolicy QSizePolicy
       
   169     \value QPixmap QPixmap
       
   170     \value QLocale QLocale
       
   171     \value QBitmap QBitmap
       
   172     \value QMatrix QMatrix
       
   173     \value QTransform QTransform
       
   174     \value QMatrix4x4 QMatrix4x4
       
   175     \value QVector2D QVector2D
       
   176     \value QVector3D QVector3D
       
   177     \value QVector4D QVector4D
       
   178     \value QQuaternion QQuaternion
       
   179 
       
   180     \value User  Base value for user types
       
   181 
       
   182     \omitvalue FirstCoreExtType
       
   183     \omitvalue FirstGuiType
       
   184     \omitvalue LastCoreExtType
       
   185     \omitvalue LastCoreType
       
   186     \omitvalue LastGuiType
       
   187     \omitvalue QReal
       
   188 
       
   189     Additional types can be registered using Q_DECLARE_METATYPE().
       
   190 
       
   191     \sa type(), typeName()
       
   192 */
       
   193 
       
   194 /*!
       
   195     \class QMetaType
       
   196     \brief The QMetaType class manages named types in the meta-object system.
       
   197 
       
   198     \ingroup objectmodel
       
   199     \threadsafe
       
   200 
       
   201     The class is used as a helper to marshall types in QVariant and
       
   202     in queued signals and slots connections. It associates a type
       
   203     name to a type so that it can be created and destructed
       
   204     dynamically at run-time. Declare new types with Q_DECLARE_METATYPE()
       
   205     to make them available to QVariant and other template-based functions.
       
   206     Call qRegisterMetaType() to make type available to non-template based
       
   207     functions, such as the queued signal and slot connections.
       
   208 
       
   209     Any class or struct that has a public default
       
   210     constructor, a public copy constructor, and a public destructor
       
   211     can be registered.
       
   212 
       
   213     The following code allocates and destructs an instance of
       
   214     \c{MyClass}:
       
   215 
       
   216     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 3
       
   217 
       
   218     If we want the stream operators \c operator<<() and \c
       
   219     operator>>() to work on QVariant objects that store custom types,
       
   220     the custom type must provide \c operator<<() and \c operator>>()
       
   221     operators.
       
   222 
       
   223     \sa Q_DECLARE_METATYPE(), QVariant::setValue(), QVariant::value(), QVariant::fromValue()
       
   224 */
       
   225 
       
   226 /* Note: these MUST be in the order of the enums */
       
   227 static const struct { const char * typeName; int type; } types[] = {
       
   228 
       
   229     /* All Core types */
       
   230     {"void", QMetaType::Void},
       
   231     {"bool", QMetaType::Bool},
       
   232     {"int", QMetaType::Int},
       
   233     {"uint", QMetaType::UInt},
       
   234     {"qlonglong", QMetaType::LongLong},
       
   235     {"qulonglong", QMetaType::ULongLong},
       
   236     {"double", QMetaType::Double},
       
   237     {"QChar", QMetaType::QChar},
       
   238     {"QVariantMap", QMetaType::QVariantMap},
       
   239     {"QVariantList", QMetaType::QVariantList},
       
   240     {"QString", QMetaType::QString},
       
   241     {"QStringList", QMetaType::QStringList},
       
   242     {"QByteArray", QMetaType::QByteArray},
       
   243     {"QBitArray", QMetaType::QBitArray},
       
   244     {"QDate", QMetaType::QDate},
       
   245     {"QTime", QMetaType::QTime},
       
   246     {"QDateTime", QMetaType::QDateTime},
       
   247     {"QUrl", QMetaType::QUrl},
       
   248     {"QLocale", QMetaType::QLocale},
       
   249     {"QRect", QMetaType::QRect},
       
   250     {"QRectF", QMetaType::QRectF},
       
   251     {"QSize", QMetaType::QSize},
       
   252     {"QSizeF", QMetaType::QSizeF},
       
   253     {"QLine", QMetaType::QLine},
       
   254     {"QLineF", QMetaType::QLineF},
       
   255     {"QPoint", QMetaType::QPoint},
       
   256     {"QPointF", QMetaType::QPointF},
       
   257     {"QRegExp", QMetaType::QRegExp},
       
   258     {"QVariantHash", QMetaType::QVariantHash},
       
   259 
       
   260     /* All GUI types */
       
   261     {"QColorGroup", 63},
       
   262     {"QFont", QMetaType::QFont},
       
   263     {"QPixmap", QMetaType::QPixmap},
       
   264     {"QBrush", QMetaType::QBrush},
       
   265     {"QColor", QMetaType::QColor},
       
   266     {"QPalette", QMetaType::QPalette},
       
   267     {"QIcon", QMetaType::QIcon},
       
   268     {"QImage", QMetaType::QImage},
       
   269     {"QPolygon", QMetaType::QPolygon},
       
   270     {"QRegion", QMetaType::QRegion},
       
   271     {"QBitmap", QMetaType::QBitmap},
       
   272     {"QCursor", QMetaType::QCursor},
       
   273     {"QSizePolicy", QMetaType::QSizePolicy},
       
   274     {"QKeySequence", QMetaType::QKeySequence},
       
   275     {"QPen", QMetaType::QPen},
       
   276     {"QTextLength", QMetaType::QTextLength},
       
   277     {"QTextFormat", QMetaType::QTextFormat},
       
   278     {"QMatrix", QMetaType::QMatrix},
       
   279     {"QTransform", QMetaType::QTransform},
       
   280     {"QMatrix4x4", QMetaType::QMatrix4x4},
       
   281     {"QVector2D", QMetaType::QVector2D},
       
   282     {"QVector3D", QMetaType::QVector3D},
       
   283     {"QVector4D", QMetaType::QVector4D},
       
   284     {"QQuaternion", QMetaType::QQuaternion},
       
   285 
       
   286     /* All Metatype builtins */
       
   287     {"void*", QMetaType::VoidStar},
       
   288     {"long", QMetaType::Long},
       
   289     {"short", QMetaType::Short},
       
   290     {"char", QMetaType::Char},
       
   291     {"ulong", QMetaType::ULong},
       
   292     {"ushort", QMetaType::UShort},
       
   293     {"uchar", QMetaType::UChar},
       
   294     {"float", QMetaType::Float},
       
   295     {"QObject*", QMetaType::QObjectStar},
       
   296     {"QWidget*", QMetaType::QWidgetStar},
       
   297 
       
   298     /* Type aliases - order doesn't matter */
       
   299     {"unsigned long", QMetaType::ULong},
       
   300     {"unsigned int", QMetaType::UInt},
       
   301     {"unsigned short", QMetaType::UShort},
       
   302     {"unsigned char", QMetaType::UChar},
       
   303     {"long long", QMetaType::LongLong},
       
   304     {"unsigned long long", QMetaType::ULongLong},
       
   305     {"qint8", QMetaType::Char},
       
   306     {"quint8", QMetaType::UChar},
       
   307     {"qint16", QMetaType::Short},
       
   308     {"quint16", QMetaType::UShort},
       
   309     {"qint32", QMetaType::Int},
       
   310     {"quint32", QMetaType::UInt},
       
   311     {"qint64", QMetaType::LongLong},
       
   312     {"quint64", QMetaType::ULongLong},
       
   313     {"QList<QVariant>", QMetaType::QVariantList},
       
   314     {"QMap<QString,QVariant>", QMetaType::QVariantMap},
       
   315     {"QHash<QString,QVariant>", QMetaType::QVariantHash},
       
   316     // let QMetaTypeId2 figure out the type at compile time
       
   317     {"qreal", QMetaTypeId2<qreal>::MetaType},
       
   318 
       
   319     {0, QMetaType::Void}
       
   320 };
       
   321 
       
   322 struct QMetaTypeGuiHelper
       
   323 {
       
   324     QMetaType::Constructor constr;
       
   325     QMetaType::Destructor destr;
       
   326 #ifndef QT_NO_DATASTREAM
       
   327     QMetaType::SaveOperator saveOp;
       
   328     QMetaType::LoadOperator loadOp;
       
   329 #endif
       
   330 };
       
   331 Q_CORE_EXPORT const QMetaTypeGuiHelper *qMetaTypeGuiHelper = 0;
       
   332 
       
   333 class QCustomTypeInfo
       
   334 {
       
   335 public:
       
   336     QCustomTypeInfo() : typeName(), constr(0), destr(0)
       
   337 #ifndef QT_NO_DATASTREAM
       
   338     , saveOp(0), loadOp(0)
       
   339 #endif
       
   340     {}
       
   341 
       
   342     QByteArray typeName;
       
   343     QMetaType::Constructor constr;
       
   344     QMetaType::Destructor destr;
       
   345 #ifndef QT_NO_DATASTREAM
       
   346     QMetaType::SaveOperator saveOp;
       
   347     QMetaType::LoadOperator loadOp;
       
   348 #endif
       
   349 };
       
   350 
       
   351 Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
       
   352 Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
       
   353 Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
       
   354 
       
   355 #ifndef QT_NO_DATASTREAM
       
   356 /*! \internal
       
   357 */
       
   358 void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp,
       
   359                                         LoadOperator loadOp)
       
   360 {
       
   361     int idx = type(typeName);
       
   362     if (!idx)
       
   363         return;
       
   364 
       
   365     QVector<QCustomTypeInfo> *ct = customTypes();
       
   366     if (!ct)
       
   367         return;
       
   368     QWriteLocker locker(customTypesLock());
       
   369     QCustomTypeInfo &inf = (*ct)[idx - User];
       
   370     inf.saveOp = saveOp;
       
   371     inf.loadOp = loadOp;
       
   372 }
       
   373 #endif // QT_NO_DATASTREAM
       
   374 
       
   375 /*!
       
   376     Returns the type name associated with the given \a type, or 0 if no
       
   377     matching type was found. The returned pointer must not be deleted.
       
   378 
       
   379     \sa type(), isRegistered(), Type
       
   380 */
       
   381 const char *QMetaType::typeName(int type)
       
   382 {
       
   383     enum { GuiTypeCount = LastGuiType - FirstGuiType };
       
   384 
       
   385     if (type >= 0 && type <= LastCoreType) {
       
   386         return types[type].typeName;
       
   387     } else if (type >= FirstGuiType && type <= LastGuiType) {
       
   388         return types[type - FirstGuiType + LastCoreType + 1].typeName;
       
   389     } else if (type >= FirstCoreExtType && type <= LastCoreExtType) {
       
   390         return types[type - FirstCoreExtType + GuiTypeCount + LastCoreType + 2].typeName;
       
   391     } else if (type >= User) {
       
   392         const QVector<QCustomTypeInfo> * const ct = customTypes();
       
   393         QReadLocker locker(customTypesLock());
       
   394         return ct && ct->count() > type - User && !ct->at(type - User).typeName.isEmpty()
       
   395                 ? ct->at(type - User).typeName.constData()
       
   396                 : static_cast<const char *>(0);
       
   397     }
       
   398 
       
   399     return 0;
       
   400 }
       
   401 
       
   402 /*! \internal
       
   403     Same as QMetaType::type(), but doesn't lock the mutex.
       
   404 */
       
   405 static int qMetaTypeType_unlocked(const QByteArray &typeName)
       
   406 {
       
   407     int i = 0;
       
   408     while (types[i].typeName && strcmp(typeName.constData(), types[i].typeName))
       
   409         ++i;
       
   410     if (!types[i].type) {
       
   411         const QVector<QCustomTypeInfo> * const ct = customTypes();
       
   412         if (!ct)
       
   413             return 0;
       
   414 
       
   415         for (int v = 0; v < ct->count(); ++v) {
       
   416             if (ct->at(v).typeName == typeName)
       
   417                 return v + QMetaType::User;
       
   418         }
       
   419     }
       
   420     return types[i].type;
       
   421 }
       
   422 
       
   423 /*! \internal
       
   424 
       
   425     Registers a user type for marshalling, with \a typeName, a \a
       
   426     destructor, and a \a constructor. Returns the type's handle,
       
   427     or -1 if the type could not be registered.
       
   428  */
       
   429 int QMetaType::registerType(const char *typeName, Destructor destructor,
       
   430                             Constructor constructor)
       
   431 {
       
   432     QVector<QCustomTypeInfo> *ct = customTypes();
       
   433     if (!ct || !typeName || !destructor || !constructor)
       
   434         return -1;
       
   435 
       
   436 #ifdef QT_NO_QOBJECT
       
   437     NS(QByteArray) normalizedTypeName = typeName;
       
   438 #else
       
   439     NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
       
   440 #endif
       
   441 
       
   442     QWriteLocker locker(customTypesLock());
       
   443     int idx = qMetaTypeType_unlocked(normalizedTypeName);
       
   444 
       
   445     if (!idx) {
       
   446         QCustomTypeInfo inf;
       
   447         inf.typeName = normalizedTypeName;
       
   448         inf.constr = constructor;
       
   449         inf.destr = destructor;
       
   450         idx = ct->size() + User;
       
   451         ct->append(inf);
       
   452     }
       
   453     return idx;
       
   454 }
       
   455 
       
   456 /*!
       
   457     \since 4.4
       
   458 
       
   459     Unregisters a user type, with \a typeName.
       
   460 
       
   461     \sa type(), typeName()
       
   462  */
       
   463 void QMetaType::unregisterType(const char *typeName)
       
   464 {
       
   465     QVector<QCustomTypeInfo> *ct = customTypes();
       
   466     if (!ct || !typeName)
       
   467         return;
       
   468 
       
   469 #ifdef QT_NO_QOBJECT
       
   470     NS(QByteArray) normalizedTypeName = typeName;
       
   471 #else
       
   472     NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
       
   473 #endif
       
   474     QWriteLocker locker(customTypesLock());
       
   475     for (int v = 0; v < ct->count(); ++v) {
       
   476         if (ct->at(v).typeName == typeName) {
       
   477             QCustomTypeInfo &inf = (*ct)[v];
       
   478             inf.typeName.clear();
       
   479             inf.constr = 0;
       
   480             inf.destr = 0;
       
   481         }
       
   482     }
       
   483 }
       
   484 
       
   485 /*!
       
   486     Returns true if the datatype with ID \a type is registered;
       
   487     otherwise returns false.
       
   488 
       
   489     \sa type(), typeName(), Type
       
   490 */
       
   491 bool QMetaType::isRegistered(int type)
       
   492 {
       
   493     if (type >= 0 && type < User) {
       
   494         // predefined type
       
   495         return true;
       
   496     }
       
   497     QReadLocker locker(customTypesLock());
       
   498     const QVector<QCustomTypeInfo> * const ct = customTypes();
       
   499     return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty());
       
   500 }
       
   501 
       
   502 /*!
       
   503     Returns a handle to the type called \a typeName, or 0 if there is
       
   504     no such type.
       
   505 
       
   506     \sa isRegistered(), typeName(), Type
       
   507 */
       
   508 int QMetaType::type(const char *typeName)
       
   509 {
       
   510 #ifdef QT_NO_QOBJECT
       
   511     const NS(QByteArray) normalizedTypeName = typeName;
       
   512 #else
       
   513     const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
       
   514 #endif
       
   515 
       
   516     QReadLocker locker(customTypesLock());
       
   517     return qMetaTypeType_unlocked(normalizedTypeName);
       
   518 }
       
   519 
       
   520 #ifndef QT_NO_DATASTREAM
       
   521 /*!
       
   522     Writes the object pointed to by \a data with the ID \a type to
       
   523     the given \a stream. Returns true if the object is saved
       
   524     successfully; otherwise returns false.
       
   525 
       
   526     The type must have been registered with qRegisterMetaType() and
       
   527     qRegisterMetaTypeStreamOperators() beforehand.
       
   528 
       
   529     Normally, you should not need to call this function directly.
       
   530     Instead, use QVariant's \c operator<<(), which relies on save()
       
   531     to stream custom types.
       
   532 
       
   533     \sa load(), qRegisterMetaTypeStreamOperators()
       
   534 */
       
   535 bool QMetaType::save(QDataStream &stream, int type, const void *data)
       
   536 {
       
   537     if (!data || !isRegistered(type))
       
   538         return false;
       
   539 
       
   540     switch(type) {
       
   541     case QMetaType::Void:
       
   542     case QMetaType::VoidStar:
       
   543     case QMetaType::QObjectStar:
       
   544     case QMetaType::QWidgetStar:
       
   545         return false;
       
   546     case QMetaType::Long:
       
   547         stream << qlonglong(*static_cast<const long *>(data));
       
   548         break;
       
   549     case QMetaType::Int:
       
   550         stream << *static_cast<const int *>(data);
       
   551         break;
       
   552     case QMetaType::Short:
       
   553         stream << *static_cast<const short *>(data);
       
   554         break;
       
   555     case QMetaType::Char:
       
   556         // force a char to be signed
       
   557         stream << *static_cast<const signed char *>(data);
       
   558         break;
       
   559     case QMetaType::ULong:
       
   560         stream << qulonglong(*static_cast<const ulong *>(data));
       
   561         break;
       
   562     case QMetaType::UInt:
       
   563         stream << *static_cast<const uint *>(data);
       
   564         break;
       
   565     case QMetaType::LongLong:
       
   566         stream << *static_cast<const qlonglong *>(data);
       
   567         break;
       
   568     case QMetaType::ULongLong:
       
   569         stream << *static_cast<const qulonglong *>(data);
       
   570         break;
       
   571     case QMetaType::UShort:
       
   572         stream << *static_cast<const ushort *>(data);
       
   573         break;
       
   574     case QMetaType::UChar:
       
   575         stream << *static_cast<const uchar *>(data);
       
   576         break;
       
   577     case QMetaType::Bool:
       
   578         stream << qint8(*static_cast<const bool *>(data));
       
   579         break;
       
   580     case QMetaType::Float:
       
   581         stream << *static_cast<const float *>(data);
       
   582         break;
       
   583     case QMetaType::Double:
       
   584         stream << *static_cast<const double *>(data);
       
   585         break;
       
   586     case QMetaType::QChar:
       
   587         stream << *static_cast<const NS(QChar) *>(data);
       
   588         break;
       
   589 #ifndef QT_BOOTSTRAPPED
       
   590     case QMetaType::QVariantMap:
       
   591         stream << *static_cast<const NS(QVariantMap)*>(data);
       
   592         break;
       
   593     case QMetaType::QVariantHash:
       
   594         stream << *static_cast<const NS(QVariantHash)*>(data);
       
   595         break;
       
   596     case QMetaType::QVariantList:
       
   597         stream << *static_cast<const NS(QVariantList)*>(data);
       
   598         break;
       
   599 #endif
       
   600     case QMetaType::QByteArray:
       
   601         stream << *static_cast<const NS(QByteArray)*>(data);
       
   602         break;
       
   603     case QMetaType::QString:
       
   604         stream << *static_cast<const NS(QString)*>(data);
       
   605         break;
       
   606     case QMetaType::QStringList:
       
   607         stream << *static_cast<const NS(QStringList)*>(data);
       
   608         break;
       
   609 #ifndef QT_BOOTSTRAPPED
       
   610     case QMetaType::QBitArray:
       
   611         stream << *static_cast<const NS(QBitArray)*>(data);
       
   612         break;
       
   613 #endif
       
   614     case QMetaType::QDate:
       
   615         stream << *static_cast<const NS(QDate)*>(data);
       
   616         break;
       
   617     case QMetaType::QTime:
       
   618         stream << *static_cast<const NS(QTime)*>(data);
       
   619         break;
       
   620     case QMetaType::QDateTime:
       
   621         stream << *static_cast<const NS(QDateTime)*>(data);
       
   622         break;
       
   623 #ifndef QT_BOOTSTRAPPED
       
   624     case QMetaType::QUrl:
       
   625         stream << *static_cast<const NS(QUrl)*>(data);
       
   626         break;
       
   627 #endif
       
   628     case QMetaType::QLocale:
       
   629         stream << *static_cast<const NS(QLocale)*>(data);
       
   630         break;
       
   631 #ifndef QT_NO_GEOM_VARIANT
       
   632     case QMetaType::QRect:
       
   633         stream << *static_cast<const NS(QRect)*>(data);
       
   634         break;
       
   635     case QMetaType::QRectF:
       
   636         stream << *static_cast<const NS(QRectF)*>(data);
       
   637         break;
       
   638     case QMetaType::QSize:
       
   639         stream << *static_cast<const NS(QSize)*>(data);
       
   640         break;
       
   641     case QMetaType::QSizeF:
       
   642         stream << *static_cast<const NS(QSizeF)*>(data);
       
   643         break;
       
   644     case QMetaType::QLine:
       
   645         stream << *static_cast<const NS(QLine)*>(data);
       
   646         break;
       
   647     case QMetaType::QLineF:
       
   648         stream << *static_cast<const NS(QLineF)*>(data);
       
   649         break;
       
   650     case QMetaType::QPoint:
       
   651         stream << *static_cast<const NS(QPoint)*>(data);
       
   652         break;
       
   653     case QMetaType::QPointF:
       
   654         stream << *static_cast<const NS(QPointF)*>(data);
       
   655         break;
       
   656 #endif
       
   657 #ifndef QT_NO_REGEXP
       
   658     case QMetaType::QRegExp:
       
   659         stream << *static_cast<const NS(QRegExp)*>(data);
       
   660         break;
       
   661 #endif
       
   662 #ifdef QT3_SUPPORT
       
   663     case QMetaType::QColorGroup:
       
   664 #endif
       
   665     case QMetaType::QFont:
       
   666     case QMetaType::QPixmap:
       
   667     case QMetaType::QBrush:
       
   668     case QMetaType::QColor:
       
   669     case QMetaType::QPalette:
       
   670     case QMetaType::QIcon:
       
   671     case QMetaType::QImage:
       
   672     case QMetaType::QPolygon:
       
   673     case QMetaType::QRegion:
       
   674     case QMetaType::QBitmap:
       
   675     case QMetaType::QCursor:
       
   676     case QMetaType::QSizePolicy:
       
   677     case QMetaType::QKeySequence:
       
   678     case QMetaType::QPen:
       
   679     case QMetaType::QTextLength:
       
   680     case QMetaType::QTextFormat:
       
   681     case QMetaType::QMatrix:
       
   682     case QMetaType::QTransform:
       
   683     case QMetaType::QMatrix4x4:
       
   684     case QMetaType::QVector2D:
       
   685     case QMetaType::QVector3D:
       
   686     case QMetaType::QVector4D:
       
   687     case QMetaType::QQuaternion:
       
   688         if (!qMetaTypeGuiHelper)
       
   689             return false;
       
   690         qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
       
   691         break;
       
   692     default: {
       
   693         const QVector<QCustomTypeInfo> * const ct = customTypes();
       
   694         if (!ct)
       
   695             return false;
       
   696 
       
   697         SaveOperator saveOp = 0;
       
   698         {
       
   699             QReadLocker locker(customTypesLock());
       
   700             saveOp = ct->at(type - User).saveOp;
       
   701         }
       
   702 
       
   703         if (!saveOp)
       
   704             return false;
       
   705         saveOp(stream, data);
       
   706         break; }
       
   707     }
       
   708 
       
   709     return true;
       
   710 }
       
   711 
       
   712 /*!
       
   713     Reads the object of the specified \a type from the given \a
       
   714     stream into \a data. Returns true if the object is loaded
       
   715     successfully; otherwise returns false.
       
   716 
       
   717     The type must have been registered with qRegisterMetaType() and
       
   718     qRegisterMetaTypeStreamOperators() beforehand.
       
   719 
       
   720     Normally, you should not need to call this function directly.
       
   721     Instead, use QVariant's \c operator>>(), which relies on load()
       
   722     to stream custom types.
       
   723 
       
   724     \sa save(), qRegisterMetaTypeStreamOperators()
       
   725 */
       
   726 bool QMetaType::load(QDataStream &stream, int type, void *data)
       
   727 {
       
   728     if (!data || !isRegistered(type))
       
   729         return false;
       
   730 
       
   731     switch(type) {
       
   732     case QMetaType::Void:
       
   733     case QMetaType::VoidStar:
       
   734     case QMetaType::QObjectStar:
       
   735     case QMetaType::QWidgetStar:
       
   736         return false;
       
   737     case QMetaType::Long: {
       
   738         qlonglong l;
       
   739         stream >> l;
       
   740         *static_cast<long *>(data) = long(l);
       
   741         break; }
       
   742     case QMetaType::Int:
       
   743         stream >> *static_cast<int *>(data);
       
   744         break;
       
   745     case QMetaType::Short:
       
   746         stream >> *static_cast<short *>(data);
       
   747         break;
       
   748     case QMetaType::Char:
       
   749         // force a char to be signed
       
   750         stream >> *static_cast<signed char *>(data);
       
   751         break;
       
   752     case QMetaType::ULong: {
       
   753         qulonglong ul;
       
   754         stream >> ul;
       
   755         *static_cast<ulong *>(data) = ulong(ul);
       
   756         break; }
       
   757     case QMetaType::UInt:
       
   758         stream >> *static_cast<uint *>(data);
       
   759         break;
       
   760     case QMetaType::LongLong:
       
   761         stream >> *static_cast<qlonglong *>(data);
       
   762         break;
       
   763     case QMetaType::ULongLong:
       
   764         stream >> *static_cast<qulonglong *>(data);
       
   765         break;
       
   766     case QMetaType::UShort:
       
   767         stream >> *static_cast<ushort *>(data);
       
   768         break;
       
   769     case QMetaType::UChar:
       
   770         stream >> *static_cast<uchar *>(data);
       
   771         break;
       
   772     case QMetaType::Bool: {
       
   773         qint8 b;
       
   774         stream >> b;
       
   775         *static_cast<bool *>(data) = b;
       
   776         break; }
       
   777     case QMetaType::Float:
       
   778         stream >> *static_cast<float *>(data);
       
   779         break;
       
   780     case QMetaType::Double:
       
   781         stream >> *static_cast<double *>(data);
       
   782         break;
       
   783     case QMetaType::QChar:
       
   784         stream >> *static_cast< NS(QChar)*>(data);
       
   785         break;
       
   786 #ifndef QT_BOOTSTRAPPED
       
   787     case QMetaType::QVariantMap:
       
   788         stream >> *static_cast< NS(QVariantMap)*>(data);
       
   789         break;
       
   790     case QMetaType::QVariantHash:
       
   791         stream >> *static_cast< NS(QVariantHash)*>(data);
       
   792         break;
       
   793     case QMetaType::QVariantList:
       
   794         stream >> *static_cast< NS(QVariantList)*>(data);
       
   795         break;
       
   796 #endif
       
   797     case QMetaType::QByteArray:
       
   798         stream >> *static_cast< NS(QByteArray)*>(data);
       
   799         break;
       
   800     case QMetaType::QString:
       
   801         stream >> *static_cast< NS(QString)*>(data);
       
   802         break;
       
   803     case QMetaType::QStringList:
       
   804         stream >> *static_cast< NS(QStringList)*>(data);
       
   805         break;
       
   806 #ifndef QT_BOOTSTRAPPED
       
   807     case QMetaType::QBitArray:
       
   808         stream >> *static_cast< NS(QBitArray)*>(data);
       
   809         break;
       
   810 #endif
       
   811     case QMetaType::QDate:
       
   812         stream >> *static_cast< NS(QDate)*>(data);
       
   813         break;
       
   814     case QMetaType::QTime:
       
   815         stream >> *static_cast< NS(QTime)*>(data);
       
   816         break;
       
   817     case QMetaType::QDateTime:
       
   818         stream >> *static_cast< NS(QDateTime)*>(data);
       
   819         break;
       
   820 #ifndef QT_BOOTSTRAPPED
       
   821     case QMetaType::QUrl:
       
   822         stream >> *static_cast< NS(QUrl)*>(data);
       
   823         break;
       
   824 #endif
       
   825     case QMetaType::QLocale:
       
   826         stream >> *static_cast< NS(QLocale)*>(data);
       
   827         break;
       
   828 #ifndef QT_NO_GEOM_VARIANT
       
   829     case QMetaType::QRect:
       
   830         stream >> *static_cast< NS(QRect)*>(data);
       
   831         break;
       
   832     case QMetaType::QRectF:
       
   833         stream >> *static_cast< NS(QRectF)*>(data);
       
   834         break;
       
   835     case QMetaType::QSize:
       
   836         stream >> *static_cast< NS(QSize)*>(data);
       
   837         break;
       
   838     case QMetaType::QSizeF:
       
   839         stream >> *static_cast< NS(QSizeF)*>(data);
       
   840         break;
       
   841     case QMetaType::QLine:
       
   842         stream >> *static_cast< NS(QLine)*>(data);
       
   843         break;
       
   844     case QMetaType::QLineF:
       
   845         stream >> *static_cast< NS(QLineF)*>(data);
       
   846         break;
       
   847     case QMetaType::QPoint:
       
   848         stream >> *static_cast< NS(QPoint)*>(data);
       
   849         break;
       
   850     case QMetaType::QPointF:
       
   851         stream >> *static_cast< NS(QPointF)*>(data);
       
   852         break;
       
   853 #endif
       
   854 #ifndef QT_NO_REGEXP
       
   855     case QMetaType::QRegExp:
       
   856         stream >> *static_cast< NS(QRegExp)*>(data);
       
   857         break;
       
   858 #endif
       
   859 #ifdef QT3_SUPPORT
       
   860     case QMetaType::QColorGroup:
       
   861 #endif
       
   862     case QMetaType::QFont:
       
   863     case QMetaType::QPixmap:
       
   864     case QMetaType::QBrush:
       
   865     case QMetaType::QColor:
       
   866     case QMetaType::QPalette:
       
   867     case QMetaType::QIcon:
       
   868     case QMetaType::QImage:
       
   869     case QMetaType::QPolygon:
       
   870     case QMetaType::QRegion:
       
   871     case QMetaType::QBitmap:
       
   872     case QMetaType::QCursor:
       
   873     case QMetaType::QSizePolicy:
       
   874     case QMetaType::QKeySequence:
       
   875     case QMetaType::QPen:
       
   876     case QMetaType::QTextLength:
       
   877     case QMetaType::QTextFormat:
       
   878     case QMetaType::QMatrix:
       
   879     case QMetaType::QTransform:
       
   880     case QMetaType::QMatrix4x4:
       
   881     case QMetaType::QVector2D:
       
   882     case QMetaType::QVector3D:
       
   883     case QMetaType::QVector4D:
       
   884     case QMetaType::QQuaternion:
       
   885         if (!qMetaTypeGuiHelper)
       
   886             return false;
       
   887         qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data);
       
   888         break;
       
   889     default: {
       
   890         const QVector<QCustomTypeInfo> * const ct = customTypes();
       
   891         if (!ct)
       
   892             return false;
       
   893 
       
   894         LoadOperator loadOp = 0;
       
   895         {
       
   896             QReadLocker locker(customTypesLock());
       
   897             loadOp = ct->at(type - User).loadOp;
       
   898         }
       
   899 
       
   900         if (!loadOp)
       
   901             return false;
       
   902         loadOp(stream, data);
       
   903         break; }
       
   904     }
       
   905     return true;
       
   906 }
       
   907 #endif // QT_NO_DATASTREAM
       
   908 
       
   909 /*!
       
   910     Returns a copy of \a copy, assuming it is of type \a type. If \a
       
   911     copy is zero, creates a default type.
       
   912 
       
   913     \sa destroy(), isRegistered(), Type
       
   914 */
       
   915 void *QMetaType::construct(int type, const void *copy)
       
   916 {
       
   917     if (copy) {
       
   918         switch(type) {
       
   919         case QMetaType::VoidStar:
       
   920         case QMetaType::QObjectStar:
       
   921         case QMetaType::QWidgetStar:
       
   922             return new void *(*static_cast<void* const *>(copy));
       
   923         case QMetaType::Long:
       
   924             return new long(*static_cast<const long*>(copy));
       
   925         case QMetaType::Int:
       
   926             return new int(*static_cast<const int*>(copy));
       
   927         case QMetaType::Short:
       
   928             return new short(*static_cast<const short*>(copy));
       
   929         case QMetaType::Char:
       
   930             return new char(*static_cast<const char*>(copy));
       
   931         case QMetaType::ULong:
       
   932             return new ulong(*static_cast<const ulong*>(copy));
       
   933         case QMetaType::UInt:
       
   934             return new uint(*static_cast<const uint*>(copy));
       
   935         case QMetaType::LongLong:
       
   936             return new qlonglong(*static_cast<const qlonglong*>(copy));
       
   937         case QMetaType::ULongLong:
       
   938             return new qulonglong(*static_cast<const qulonglong*>(copy));
       
   939         case QMetaType::UShort:
       
   940             return new ushort(*static_cast<const ushort*>(copy));
       
   941         case QMetaType::UChar:
       
   942             return new uchar(*static_cast<const uchar*>(copy));
       
   943         case QMetaType::Bool:
       
   944             return new bool(*static_cast<const bool*>(copy));
       
   945         case QMetaType::Float:
       
   946             return new float(*static_cast<const float*>(copy));
       
   947         case QMetaType::Double:
       
   948             return new double(*static_cast<const double*>(copy));
       
   949         case QMetaType::QChar:
       
   950             return new NS(QChar)(*static_cast<const NS(QChar)*>(copy));
       
   951 #ifndef QT_BOOTSTRAPPED
       
   952         case QMetaType::QVariantMap:
       
   953             return new NS(QVariantMap)(*static_cast<const NS(QVariantMap)*>(copy));
       
   954         case QMetaType::QVariantHash:
       
   955             return new NS(QVariantHash)(*static_cast<const NS(QVariantHash)*>(copy));
       
   956         case QMetaType::QVariantList:
       
   957             return new NS(QVariantList)(*static_cast<const NS(QVariantList)*>(copy));
       
   958 #endif
       
   959         case QMetaType::QByteArray:
       
   960             return new NS(QByteArray)(*static_cast<const NS(QByteArray)*>(copy));
       
   961         case QMetaType::QString:
       
   962             return new NS(QString)(*static_cast<const NS(QString)*>(copy));
       
   963         case QMetaType::QStringList:
       
   964             return new NS(QStringList)(*static_cast<const NS(QStringList)*>(copy));
       
   965 #ifndef QT_BOOTSTRAPPED
       
   966         case QMetaType::QBitArray:
       
   967             return new NS(QBitArray)(*static_cast<const NS(QBitArray)*>(copy));
       
   968 #endif
       
   969         case QMetaType::QDate:
       
   970             return new NS(QDate)(*static_cast<const NS(QDate)*>(copy));
       
   971         case QMetaType::QTime:
       
   972             return new NS(QTime)(*static_cast<const NS(QTime)*>(copy));
       
   973         case QMetaType::QDateTime:
       
   974             return new NS(QDateTime)(*static_cast<const NS(QDateTime)*>(copy));
       
   975 #ifndef QT_BOOTSTRAPPED
       
   976         case QMetaType::QUrl:
       
   977             return new NS(QUrl)(*static_cast<const NS(QUrl)*>(copy));
       
   978 #endif
       
   979         case QMetaType::QLocale:
       
   980             return new NS(QLocale)(*static_cast<const NS(QLocale)*>(copy));
       
   981 #ifndef QT_NO_GEOM_VARIANT
       
   982         case QMetaType::QRect:
       
   983             return new NS(QRect)(*static_cast<const NS(QRect)*>(copy));
       
   984         case QMetaType::QRectF:
       
   985             return new NS(QRectF)(*static_cast<const NS(QRectF)*>(copy));
       
   986         case QMetaType::QSize:
       
   987             return new NS(QSize)(*static_cast<const NS(QSize)*>(copy));
       
   988         case QMetaType::QSizeF:
       
   989             return new NS(QSizeF)(*static_cast<const NS(QSizeF)*>(copy));
       
   990         case QMetaType::QLine:
       
   991             return new NS(QLine)(*static_cast<const NS(QLine)*>(copy));
       
   992         case QMetaType::QLineF:
       
   993             return new NS(QLineF)(*static_cast<const NS(QLineF)*>(copy));
       
   994         case QMetaType::QPoint:
       
   995             return new NS(QPoint)(*static_cast<const NS(QPoint)*>(copy));
       
   996         case QMetaType::QPointF:
       
   997             return new NS(QPointF)(*static_cast<const NS(QPointF)*>(copy));
       
   998 #endif
       
   999 #ifndef QT_NO_REGEXP
       
  1000         case QMetaType::QRegExp:
       
  1001             return new NS(QRegExp)(*static_cast<const NS(QRegExp)*>(copy));
       
  1002 #endif
       
  1003         case QMetaType::Void:
       
  1004             return 0;
       
  1005         default:
       
  1006             ;
       
  1007         }
       
  1008     } else {
       
  1009         switch(type) {
       
  1010         case QMetaType::VoidStar:
       
  1011         case QMetaType::QObjectStar:
       
  1012         case QMetaType::QWidgetStar:
       
  1013             return new void *;
       
  1014         case QMetaType::Long:
       
  1015             return new long;
       
  1016         case QMetaType::Int:
       
  1017             return new int;
       
  1018         case QMetaType::Short:
       
  1019             return new short;
       
  1020         case QMetaType::Char:
       
  1021             return new char;
       
  1022         case QMetaType::ULong:
       
  1023             return new ulong;
       
  1024         case QMetaType::UInt:
       
  1025             return new uint;
       
  1026         case QMetaType::LongLong:
       
  1027             return new qlonglong;
       
  1028         case QMetaType::ULongLong:
       
  1029             return new qulonglong;
       
  1030         case QMetaType::UShort:
       
  1031             return new ushort;
       
  1032         case QMetaType::UChar:
       
  1033             return new uchar;
       
  1034         case QMetaType::Bool:
       
  1035             return new bool;
       
  1036         case QMetaType::Float:
       
  1037             return new float;
       
  1038         case QMetaType::Double:
       
  1039             return new double;
       
  1040         case QMetaType::QChar:
       
  1041             return new NS(QChar);
       
  1042 #ifndef QT_BOOTSTRAPPED
       
  1043         case QMetaType::QVariantMap:
       
  1044             return new NS(QVariantMap);
       
  1045         case QMetaType::QVariantHash:
       
  1046             return new NS(QVariantHash);
       
  1047         case QMetaType::QVariantList:
       
  1048             return new NS(QVariantList);
       
  1049 #endif
       
  1050         case QMetaType::QByteArray:
       
  1051             return new NS(QByteArray);
       
  1052         case QMetaType::QString:
       
  1053             return new NS(QString);
       
  1054         case QMetaType::QStringList:
       
  1055             return new NS(QStringList);
       
  1056 #ifndef QT_BOOTSTRAPPED
       
  1057         case QMetaType::QBitArray:
       
  1058             return new NS(QBitArray);
       
  1059 #endif
       
  1060         case QMetaType::QDate:
       
  1061             return new NS(QDate);
       
  1062         case QMetaType::QTime:
       
  1063             return new NS(QTime);
       
  1064         case QMetaType::QDateTime:
       
  1065             return new NS(QDateTime);
       
  1066 #ifndef QT_BOOTSTRAPPED
       
  1067         case QMetaType::QUrl:
       
  1068             return new NS(QUrl);
       
  1069 #endif
       
  1070         case QMetaType::QLocale:
       
  1071             return new NS(QLocale);
       
  1072 #ifndef QT_NO_GEOM_VARIANT
       
  1073         case QMetaType::QRect:
       
  1074             return new NS(QRect);
       
  1075         case QMetaType::QRectF:
       
  1076             return new NS(QRectF);
       
  1077         case QMetaType::QSize:
       
  1078             return new NS(QSize);
       
  1079         case QMetaType::QSizeF:
       
  1080             return new NS(QSizeF);
       
  1081         case QMetaType::QLine:
       
  1082             return new NS(QLine);
       
  1083         case QMetaType::QLineF:
       
  1084             return new NS(QLineF);
       
  1085         case QMetaType::QPoint:
       
  1086             return new NS(QPoint);
       
  1087         case QMetaType::QPointF:
       
  1088             return new NS(QPointF);
       
  1089 #endif
       
  1090 #ifndef QT_NO_REGEXP
       
  1091         case QMetaType::QRegExp:
       
  1092             return new NS(QRegExp);
       
  1093 #endif
       
  1094         case QMetaType::Void:
       
  1095             return 0;
       
  1096         default:
       
  1097             ;
       
  1098         }
       
  1099     }
       
  1100 
       
  1101     Constructor constr = 0;
       
  1102     if (type >= FirstGuiType && type <= LastGuiType) {
       
  1103         if (!qMetaTypeGuiHelper)
       
  1104             return 0;
       
  1105         constr = qMetaTypeGuiHelper[type - FirstGuiType].constr;
       
  1106     } else {
       
  1107         const QVector<QCustomTypeInfo> * const ct = customTypes();
       
  1108         QReadLocker locker(customTypesLock());
       
  1109         if (type < User || !ct || ct->count() <= type - User)
       
  1110             return 0;
       
  1111         if (ct->at(type - User).typeName.isEmpty())
       
  1112             return 0;
       
  1113         constr = ct->at(type - User).constr;
       
  1114     }
       
  1115 
       
  1116     return constr(copy);
       
  1117 }
       
  1118 
       
  1119 /*!
       
  1120     Destroys the \a data, assuming it is of the \a type given.
       
  1121 
       
  1122     \sa construct(), isRegistered(), Type
       
  1123 */
       
  1124 void QMetaType::destroy(int type, void *data)
       
  1125 {
       
  1126     if (!data)
       
  1127         return;
       
  1128     switch(type) {
       
  1129     case QMetaType::VoidStar:
       
  1130     case QMetaType::QObjectStar:
       
  1131     case QMetaType::QWidgetStar:
       
  1132         delete static_cast<void**>(data);
       
  1133         break;
       
  1134     case QMetaType::Long:
       
  1135         delete static_cast<long*>(data);
       
  1136         break;
       
  1137     case QMetaType::Int:
       
  1138         delete static_cast<int*>(data);
       
  1139         break;
       
  1140     case QMetaType::Short:
       
  1141         delete static_cast<short*>(data);
       
  1142         break;
       
  1143     case QMetaType::Char:
       
  1144         delete static_cast<char*>(data);
       
  1145         break;
       
  1146     case QMetaType::ULong:
       
  1147         delete static_cast<ulong*>(data);
       
  1148         break;
       
  1149     case QMetaType::LongLong:
       
  1150         delete static_cast<qlonglong*>(data);
       
  1151         break;
       
  1152     case QMetaType::ULongLong:
       
  1153         delete static_cast<qulonglong*>(data);
       
  1154         break;
       
  1155     case QMetaType::UInt:
       
  1156         delete static_cast<uint*>(data);
       
  1157         break;
       
  1158     case QMetaType::UShort:
       
  1159         delete static_cast<ushort*>(data);
       
  1160         break;
       
  1161     case QMetaType::UChar:
       
  1162         delete static_cast<uchar*>(data);
       
  1163         break;
       
  1164     case QMetaType::Bool:
       
  1165         delete static_cast<bool*>(data);
       
  1166         break;
       
  1167     case QMetaType::Float:
       
  1168         delete static_cast<float*>(data);
       
  1169         break;
       
  1170     case QMetaType::Double:
       
  1171         delete static_cast<double*>(data);
       
  1172         break;
       
  1173     case QMetaType::QChar:
       
  1174         delete static_cast< NS(QChar)* >(data);
       
  1175         break;
       
  1176 #ifndef QT_BOOTSTRAPPED
       
  1177     case QMetaType::QVariantMap:
       
  1178         delete static_cast< NS(QVariantMap)* >(data);
       
  1179         break;
       
  1180     case QMetaType::QVariantHash:
       
  1181         delete static_cast< NS(QVariantHash)* >(data);
       
  1182         break;
       
  1183     case QMetaType::QVariantList:
       
  1184         delete static_cast< NS(QVariantList)* >(data);
       
  1185         break;
       
  1186 #endif
       
  1187     case QMetaType::QByteArray:
       
  1188         delete static_cast< NS(QByteArray)* >(data);
       
  1189         break;
       
  1190     case QMetaType::QString:
       
  1191         delete static_cast< NS(QString)* >(data);
       
  1192         break;
       
  1193     case QMetaType::QStringList:
       
  1194         delete static_cast< NS(QStringList)* >(data);
       
  1195         break;
       
  1196 #ifndef QT_BOOTSTRAPPED
       
  1197     case QMetaType::QBitArray:
       
  1198         delete static_cast< NS(QBitArray)* >(data);
       
  1199         break;
       
  1200 #endif
       
  1201     case QMetaType::QDate:
       
  1202         delete static_cast< NS(QDate)* >(data);
       
  1203         break;
       
  1204     case QMetaType::QTime:
       
  1205         delete static_cast< NS(QTime)* >(data);
       
  1206         break;
       
  1207     case QMetaType::QDateTime:
       
  1208         delete static_cast< NS(QDateTime)* >(data);
       
  1209         break;
       
  1210 #ifndef QT_BOOTSTRAPPED
       
  1211     case QMetaType::QUrl:
       
  1212         delete static_cast< NS(QUrl)* >(data);
       
  1213 #endif
       
  1214         break;
       
  1215     case QMetaType::QLocale:
       
  1216         delete static_cast< NS(QLocale)* >(data);
       
  1217         break;
       
  1218 #ifndef QT_NO_GEOM_VARIANT
       
  1219     case QMetaType::QRect:
       
  1220         delete static_cast< NS(QRect)* >(data);
       
  1221         break;
       
  1222     case QMetaType::QRectF:
       
  1223         delete static_cast< NS(QRectF)* >(data);
       
  1224         break;
       
  1225     case QMetaType::QSize:
       
  1226         delete static_cast< NS(QSize)* >(data);
       
  1227         break;
       
  1228     case QMetaType::QSizeF:
       
  1229         delete static_cast< NS(QSizeF)* >(data);
       
  1230         break;
       
  1231     case QMetaType::QLine:
       
  1232         delete static_cast< NS(QLine)* >(data);
       
  1233         break;
       
  1234     case QMetaType::QLineF:
       
  1235         delete static_cast< NS(QLineF)* >(data);
       
  1236         break;
       
  1237     case QMetaType::QPoint:
       
  1238         delete static_cast< NS(QPoint)* >(data);
       
  1239         break;
       
  1240     case QMetaType::QPointF:
       
  1241         delete static_cast< NS(QPointF)* >(data);
       
  1242         break;
       
  1243 #endif
       
  1244 #ifndef QT_NO_REGEXP
       
  1245     case QMetaType::QRegExp:
       
  1246         delete static_cast< NS(QRegExp)* >(data);
       
  1247         break;
       
  1248 #endif
       
  1249     case QMetaType::Void:
       
  1250         break;
       
  1251     default: {
       
  1252         const QVector<QCustomTypeInfo> * const ct = customTypes();
       
  1253         Destructor destr = 0;
       
  1254         if (type >= FirstGuiType && type <= LastGuiType) {
       
  1255             Q_ASSERT(qMetaTypeGuiHelper);
       
  1256 
       
  1257             if (!qMetaTypeGuiHelper)
       
  1258                 return;
       
  1259             destr = qMetaTypeGuiHelper[type - FirstGuiType].destr;
       
  1260         } else {
       
  1261             QReadLocker locker(customTypesLock());
       
  1262             if (type < User || !ct || ct->count() <= type - User)
       
  1263                 break;
       
  1264             if (ct->at(type - User).typeName.isEmpty())
       
  1265                 break;
       
  1266             destr = ct->at(type - User).destr;
       
  1267         }
       
  1268         destr(data);
       
  1269         break; }
       
  1270     }
       
  1271 }
       
  1272 
       
  1273 /*!
       
  1274     \fn int qRegisterMetaType(const char *typeName)
       
  1275     \relates QMetaType
       
  1276     \threadsafe
       
  1277 
       
  1278     Registers the type name \a typeName for the type \c{T}. Returns
       
  1279     the internal ID used by QMetaType. Any class or struct that has a
       
  1280     public default constructor, a public copy constructor and a public
       
  1281     destructor can be registered.
       
  1282 
       
  1283     After a type has been registered, you can create and destroy
       
  1284     objects of that type dynamically at run-time.
       
  1285 
       
  1286     This example registers the class \c{MyClass}:
       
  1287 
       
  1288     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 4
       
  1289 
       
  1290     \sa qRegisterMetaTypeStreamOperators(), QMetaType::isRegistered(),
       
  1291         Q_DECLARE_METATYPE()
       
  1292 */
       
  1293 
       
  1294 /*!
       
  1295     \fn int qRegisterMetaTypeStreamOperators(const char *typeName)
       
  1296     \relates QMetaType
       
  1297     \threadsafe
       
  1298 
       
  1299     Registers the stream operators for the type \c{T} called \a
       
  1300     typeName.
       
  1301 
       
  1302     Afterward, the type can be streamed using QMetaType::load() and
       
  1303     QMetaType::save(). These functions are used when streaming a
       
  1304     QVariant.
       
  1305 
       
  1306     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 5
       
  1307 
       
  1308     The stream operators should have the following signatures:
       
  1309 
       
  1310     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 6
       
  1311 
       
  1312     \sa qRegisterMetaType(), QMetaType::isRegistered(), Q_DECLARE_METATYPE()
       
  1313 */
       
  1314 
       
  1315 /*! \typedef QMetaType::Destructor
       
  1316     \internal
       
  1317 */
       
  1318 /*! \typedef QMetaType::Constructor
       
  1319     \internal
       
  1320 */
       
  1321 /*! \typedef QMetaType::SaveOperator
       
  1322     \internal
       
  1323 */
       
  1324 /*! \typedef QMetaType::LoadOperator
       
  1325     \internal
       
  1326 */
       
  1327 
       
  1328 /*!
       
  1329     \fn int qRegisterMetaType()
       
  1330     \relates QMetaType
       
  1331     \threadsafe
       
  1332     \since 4.2
       
  1333 
       
  1334     Call this function to register the type \c T. \c T must be declared with
       
  1335     Q_DECLARE_METATYPE(). Returns the meta type Id.
       
  1336 
       
  1337     Example:
       
  1338 
       
  1339     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 7
       
  1340 
       
  1341     To use the type \c T in QVariant, using Q_DECLARE_METATYPE() is
       
  1342     sufficient. To use the type \c T in queued signal and slot connections,
       
  1343     \c{qRegisterMetaType<T>()} must be called before the first connection
       
  1344     is established.
       
  1345 
       
  1346     Also, to use type \c T with the QObject::property() API,
       
  1347     \c{qRegisterMetaType<T>()} must be called before it is used, typically
       
  1348     in the constructor of the class that uses \c T, or in the \c{main()}
       
  1349     function.
       
  1350 
       
  1351     \sa Q_DECLARE_METATYPE()
       
  1352  */
       
  1353 
       
  1354 /*! \fn int qMetaTypeId()
       
  1355     \relates QMetaType
       
  1356     \threadsafe
       
  1357     \since 4.1
       
  1358 
       
  1359     Returns the meta type id of type \c T at compile time. If the
       
  1360     type was not declared with Q_DECLARE_METATYPE(), compilation will
       
  1361     fail.
       
  1362 
       
  1363     Typical usage:
       
  1364 
       
  1365     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 8
       
  1366 
       
  1367     QMetaType::type() returns the same ID as qMetaTypeId(), but does
       
  1368     a lookup at runtime based on the name of the type.
       
  1369     QMetaType::type() is a bit slower, but compilation succeeds if a
       
  1370     type is not registered.
       
  1371 
       
  1372     \sa Q_DECLARE_METATYPE(), QMetaType::type()
       
  1373 */
       
  1374 
       
  1375 QT_END_NAMESPACE