Introduce QMetaType::UnknownType.
[profile/ivi/qtbase.git] / src / corelib / kernel / qvariant.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qvariant.h"
43 #include "qbitarray.h"
44 #include "qbytearray.h"
45 #include "qdatastream.h"
46 #include "qdebug.h"
47 #include "qmap.h"
48 #include "qdatetime.h"
49 #include "qeasingcurve.h"
50 #include "qlist.h"
51 #include "qstring.h"
52 #include "qstringlist.h"
53 #include "qurl.h"
54 #include "qlocale.h"
55 #include "quuid.h"
56 #ifndef QT_BOOTSTRAPPED
57 #include "qabstractitemmodel.h"
58 #endif
59 #include "private/qvariant_p.h"
60 #include "qmetatype_p.h"
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 #include <float.h>
70
71 QT_BEGIN_NAMESPACE
72
73 #ifndef DBL_DIG
74 #  define DBL_DIG 10
75 #endif
76 #ifndef FLT_DIG
77 #  define FLT_DIG 6
78 #endif
79
80 namespace {
81 class HandlersManager
82 {
83     static const QVariant::Handler *Handlers[QModulesPrivate::ModulesCount];
84 public:
85     const QVariant::Handler *operator[] (const int typeId) const
86     {
87         return Handlers[QModulesPrivate::moduleForType(typeId)];
88     }
89
90     void registerHandler(const QModulesPrivate::Names name, const QVariant::Handler *handler)
91     {
92         Handlers[name] = handler;
93     }
94
95     inline void unregisterHandler(const QModulesPrivate::Names name);
96 };
97 }  // namespace
98
99 namespace {
100 template<typename T>
101 struct TypeDefinition {
102     static const bool IsAvailable = true;
103 };
104
105 // Ignore these types, as incomplete
106 #ifdef QT_BOOTSTRAPPED
107 template<> struct TypeDefinition<QEasingCurve> { static const bool IsAvailable = false; };
108 template<> struct TypeDefinition<QModelIndex> { static const bool IsAvailable = false; };
109 #endif
110 #ifdef QT_NO_GEOM_VARIANT
111 template<> struct TypeDefinition<QRect> { static const bool IsAvailable = false; };
112 template<> struct TypeDefinition<QRectF> { static const bool IsAvailable = false; };
113 template<> struct TypeDefinition<QSize> { static const bool IsAvailable = false; };
114 template<> struct TypeDefinition<QSizeF> { static const bool IsAvailable = false; };
115 template<> struct TypeDefinition<QLine> { static const bool IsAvailable = false; };
116 template<> struct TypeDefinition<QLineF> { static const bool IsAvailable = false; };
117 template<> struct TypeDefinition<QPoint> { static const bool IsAvailable = false; };
118 template<> struct TypeDefinition<QPointF> { static const bool IsAvailable = false; };
119 #endif
120
121 struct CoreTypesFilter {
122     template<typename T>
123     struct Acceptor {
124         static const bool IsAccepted = QTypeModuleInfo<T>::IsCore && TypeDefinition<T>::IsAvailable;
125     };
126 };
127 } // annonymous used to hide TypeDefinition
128
129 namespace { // annonymous used to hide QVariant handlers
130
131 static void construct(QVariant::Private *x, const void *copy)
132 {
133     QVariantConstructor<CoreTypesFilter> constructor(x, copy);
134     QMetaTypeSwitcher::switcher<void>(constructor, x->type, 0);
135 }
136
137 static void clear(QVariant::Private *d)
138 {
139     QVariantDestructor<CoreTypesFilter> cleaner(d);
140     QMetaTypeSwitcher::switcher<void>(cleaner, d->type, 0);
141 }
142
143 static bool isNull(const QVariant::Private *d)
144 {
145     QVariantIsNull<CoreTypesFilter> isNull(d);
146     return QMetaTypeSwitcher::switcher<bool>(isNull, d->type, 0);
147 }
148
149 /*!
150   \internal
151
152   Compares \a a to \a b. The caller guarantees that \a a and \a b
153   are of the same type.
154  */
155 static bool compare(const QVariant::Private *a, const QVariant::Private *b)
156 {
157     QVariantComparator<CoreTypesFilter> comparator(a, b);
158     return QMetaTypeSwitcher::switcher<bool>(comparator, a->type, 0);
159 }
160
161 /*!
162   \internal
163  */
164 static qlonglong qMetaTypeNumber(const QVariant::Private *d)
165 {
166     switch (d->type) {
167     case QMetaType::Int:
168         return d->data.i;
169     case QMetaType::LongLong:
170         return d->data.ll;
171     case QMetaType::Char:
172         return qlonglong(d->data.c);
173     case QMetaType::Short:
174         return qlonglong(d->data.s);
175     case QMetaType::Long:
176         return qlonglong(d->data.l);
177     case QMetaType::Float:
178         return qRound64(d->data.f);
179     case QVariant::Double:
180         return qRound64(d->data.d);
181     }
182     Q_ASSERT(false);
183     return 0;
184 }
185
186 static qulonglong qMetaTypeUNumber(const QVariant::Private *d)
187 {
188     switch (d->type) {
189     case QVariant::UInt:
190         return d->data.u;
191     case QVariant::ULongLong:
192         return d->data.ull;
193     case QMetaType::UChar:
194         return d->data.uc;
195     case QMetaType::UShort:
196         return d->data.us;
197     case QMetaType::ULong:
198         return d->data.ul;
199     }
200     Q_ASSERT(false);
201     return 0;
202 }
203
204 static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
205 {
206     *ok = true;
207
208     switch (uint(d->type)) {
209     case QVariant::String:
210         return v_cast<QString>(d)->toLongLong(ok);
211     case QVariant::Char:
212         return v_cast<QChar>(d)->unicode();
213     case QVariant::ByteArray:
214         return v_cast<QByteArray>(d)->toLongLong(ok);
215     case QVariant::Bool:
216         return qlonglong(d->data.b);
217     case QVariant::Double:
218     case QVariant::Int:
219     case QMetaType::Char:
220     case QMetaType::Short:
221     case QMetaType::Long:
222     case QMetaType::Float:
223     case QMetaType::LongLong:
224         return qMetaTypeNumber(d);
225     case QVariant::ULongLong:
226     case QVariant::UInt:
227     case QMetaType::UChar:
228     case QMetaType::UShort:
229     case QMetaType::ULong:
230         return qlonglong(qMetaTypeUNumber(d));
231     }
232
233     *ok = false;
234     return Q_INT64_C(0);
235 }
236
237 static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
238 {
239     *ok = true;
240
241     switch (uint(d->type)) {
242     case QVariant::String:
243         return v_cast<QString>(d)->toULongLong(ok);
244     case QVariant::Char:
245         return v_cast<QChar>(d)->unicode();
246     case QVariant::ByteArray:
247         return v_cast<QByteArray>(d)->toULongLong(ok);
248     case QVariant::Bool:
249         return qulonglong(d->data.b);
250     case QVariant::Double:
251     case QVariant::Int:
252     case QMetaType::Char:
253     case QMetaType::Short:
254     case QMetaType::Long:
255     case QMetaType::Float:
256     case QMetaType::LongLong:
257         return qulonglong(qMetaTypeNumber(d));
258     case QVariant::ULongLong:
259     case QVariant::UInt:
260     case QMetaType::UChar:
261     case QMetaType::UShort:
262     case QMetaType::ULong:
263         return qMetaTypeUNumber(d);
264     }
265
266     *ok = false;
267     return Q_UINT64_C(0);
268 }
269
270 template<typename TInput, typename LiteralWrapper>
271 inline bool qt_convertToBool(const QVariant::Private *const d)
272 {
273     TInput str = v_cast<TInput>(d)->toLower();
274     return !(str == LiteralWrapper("0") || str == LiteralWrapper("false") || str.isEmpty());
275 }
276
277 /*!
278  \internal
279
280  Converts \a d to type \a t, which is placed in \a result.
281  */
282 static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
283 {
284     Q_ASSERT(d->type != uint(t));
285     Q_ASSERT(result);
286
287     bool dummy;
288     if (!ok)
289         ok = &dummy;
290
291     switch (uint(t)) {
292     case QVariant::Url:
293         switch (d->type) {
294         case QVariant::String:
295             *static_cast<QUrl *>(result) = QUrl(*v_cast<QString>(d));
296             break;
297         default:
298             return false;
299         }
300         break;
301     case QVariant::String: {
302         QString *str = static_cast<QString *>(result);
303         switch (d->type) {
304         case QVariant::Char:
305             *str = QString(*v_cast<QChar>(d));
306             break;
307         case QMetaType::Char:
308         case QMetaType::UChar:
309             *str = QChar::fromAscii(d->data.c);
310             break;
311         case QMetaType::Short:
312         case QMetaType::Long:
313         case QVariant::Int:
314         case QVariant::LongLong:
315             *str = QString::number(qMetaTypeNumber(d));
316             break;
317         case QVariant::UInt:
318         case QVariant::ULongLong:
319         case QMetaType::UShort:
320         case QMetaType::ULong:
321             *str = QString::number(qMetaTypeUNumber(d));
322             break;
323         case QMetaType::Float:
324             *str = QString::number(d->data.f, 'g', FLT_DIG);
325             break;
326         case QVariant::Double:
327             *str = QString::number(d->data.d, 'g', DBL_DIG);
328             break;
329 #if !defined(QT_NO_DATESTRING)
330         case QVariant::Date:
331             *str = v_cast<QDate>(d)->toString(Qt::ISODate);
332             break;
333         case QVariant::Time:
334             *str = v_cast<QTime>(d)->toString(Qt::ISODate);
335             break;
336         case QVariant::DateTime:
337             *str = v_cast<QDateTime>(d)->toString(Qt::ISODate);
338             break;
339 #endif
340         case QVariant::Bool:
341             *str = QLatin1String(d->data.b ? "true" : "false");
342             break;
343         case QVariant::ByteArray:
344             *str = QString::fromAscii(v_cast<QByteArray>(d)->constData());
345             break;
346         case QVariant::StringList:
347             if (v_cast<QStringList>(d)->count() == 1)
348                 *str = v_cast<QStringList>(d)->at(0);
349             break;
350         case QVariant::Url:
351             *str = v_cast<QUrl>(d)->toString();
352             break;
353         case QVariant::Uuid:
354             *str = v_cast<QUuid>(d)->toString();
355             break;
356         default:
357             return false;
358         }
359         break;
360     }
361     case QVariant::Char: {
362         QChar *c = static_cast<QChar *>(result);
363         switch (d->type) {
364         case QVariant::Int:
365         case QVariant::LongLong:
366         case QMetaType::Char:
367         case QMetaType::Short:
368         case QMetaType::Long:
369         case QMetaType::Float:
370             *c = QChar(ushort(qMetaTypeNumber(d)));
371             break;
372         case QVariant::UInt:
373         case QVariant::ULongLong:
374         case QMetaType::UChar:
375         case QMetaType::UShort:
376         case QMetaType::ULong:
377             *c = QChar(ushort(qMetaTypeUNumber(d)));
378             break;
379         default:
380             return false;
381         }
382         break;
383     }
384 #ifndef QT_NO_GEOM_VARIANT
385     case QVariant::Size: {
386         QSize *s = static_cast<QSize *>(result);
387         switch (d->type) {
388         case QVariant::SizeF:
389             *s = v_cast<QSizeF>(d)->toSize();
390             break;
391         default:
392             return false;
393         }
394         break;
395     }
396
397     case QVariant::SizeF: {
398         QSizeF *s = static_cast<QSizeF *>(result);
399         switch (d->type) {
400         case QVariant::Size:
401             *s = QSizeF(*(v_cast<QSize>(d)));
402             break;
403         default:
404             return false;
405         }
406         break;
407     }
408
409     case QVariant::Line: {
410         QLine *s = static_cast<QLine *>(result);
411         switch (d->type) {
412         case QVariant::LineF:
413             *s = v_cast<QLineF>(d)->toLine();
414             break;
415         default:
416             return false;
417         }
418         break;
419     }
420
421     case QVariant::LineF: {
422         QLineF *s = static_cast<QLineF *>(result);
423         switch (d->type) {
424         case QVariant::Line:
425             *s = QLineF(*(v_cast<QLine>(d)));
426             break;
427         default:
428             return false;
429         }
430         break;
431     }
432 #endif
433     case QVariant::StringList:
434         if (d->type == QVariant::List) {
435             QStringList *slst = static_cast<QStringList *>(result);
436             const QVariantList *list = v_cast<QVariantList >(d);
437             for (int i = 0; i < list->size(); ++i)
438                 slst->append(list->at(i).toString());
439         } else if (d->type == QVariant::String) {
440             QStringList *slst = static_cast<QStringList *>(result);
441             *slst = QStringList(*v_cast<QString>(d));
442         } else {
443             return false;
444         }
445         break;
446     case QVariant::Date: {
447         QDate *dt = static_cast<QDate *>(result);
448         if (d->type == QVariant::DateTime)
449             *dt = v_cast<QDateTime>(d)->date();
450 #ifndef QT_NO_DATESTRING
451         else if (d->type == QVariant::String)
452             *dt = QDate::fromString(*v_cast<QString>(d), Qt::ISODate);
453 #endif
454         else
455             return false;
456
457         return dt->isValid();
458     }
459     case QVariant::Time: {
460         QTime *t = static_cast<QTime *>(result);
461         switch (d->type) {
462         case QVariant::DateTime:
463             *t = v_cast<QDateTime>(d)->time();
464             break;
465 #ifndef QT_NO_DATESTRING
466         case QVariant::String:
467             *t = QTime::fromString(*v_cast<QString>(d), Qt::ISODate);
468             break;
469 #endif
470         default:
471             return false;
472         }
473         return t->isValid();
474     }
475     case QVariant::DateTime: {
476         QDateTime *dt = static_cast<QDateTime *>(result);
477         switch (d->type) {
478 #ifndef QT_NO_DATESTRING
479         case QVariant::String:
480             *dt = QDateTime::fromString(*v_cast<QString>(d), Qt::ISODate);
481             break;
482 #endif
483         case QVariant::Date:
484             *dt = QDateTime(*v_cast<QDate>(d));
485             break;
486         default:
487             return false;
488         }
489         return dt->isValid();
490     }
491     case QVariant::ByteArray: {
492         QByteArray *ba = static_cast<QByteArray *>(result);
493         switch (d->type) {
494         case QVariant::String:
495             *ba = v_cast<QString>(d)->toAscii();
496             break;
497         case QVariant::Double:
498             *ba = QByteArray::number(d->data.d, 'g', DBL_DIG);
499             break;
500         case QMetaType::Float:
501             *ba = QByteArray::number(d->data.f, 'g', FLT_DIG);
502             break;
503         case QMetaType::Char:
504         case QMetaType::UChar:
505             *ba = QByteArray(1, d->data.c);
506             break;
507         case QVariant::Int:
508         case QVariant::LongLong:
509         case QMetaType::Short:
510         case QMetaType::Long:
511             *ba = QByteArray::number(qMetaTypeNumber(d));
512             break;
513         case QVariant::UInt:
514         case QVariant::ULongLong:
515         case QMetaType::UShort:
516         case QMetaType::ULong:
517             *ba = QByteArray::number(qMetaTypeUNumber(d));
518             break;
519         case QVariant::Bool:
520             *ba = QByteArray(d->data.b ? "true" : "false");
521             break;
522         default:
523             return false;
524         }
525     }
526     break;
527     case QMetaType::Short:
528         *static_cast<short *>(result) = short(qConvertToNumber(d, ok));
529         return *ok;
530     case QMetaType::Long:
531         *static_cast<long *>(result) = long(qConvertToNumber(d, ok));
532         return *ok;
533     case QMetaType::UShort:
534         *static_cast<ushort *>(result) = ushort(qConvertToUnsignedNumber(d, ok));
535         return *ok;
536     case QMetaType::ULong:
537         *static_cast<ulong *>(result) = ulong(qConvertToUnsignedNumber(d, ok));
538         return *ok;
539     case QVariant::Int:
540         *static_cast<int *>(result) = int(qConvertToNumber(d, ok));
541         return *ok;
542     case QVariant::UInt:
543         *static_cast<uint *>(result) = uint(qConvertToUnsignedNumber(d, ok));
544         return *ok;
545     case QVariant::LongLong:
546         *static_cast<qlonglong *>(result) = qConvertToNumber(d, ok);
547         return *ok;
548     case QVariant::ULongLong: {
549         *static_cast<qulonglong *>(result) = qConvertToUnsignedNumber(d, ok);
550         return *ok;
551     }
552     case QMetaType::UChar: {
553         *static_cast<uchar *>(result) = qConvertToUnsignedNumber(d, ok);
554         return *ok;
555     }
556     case QVariant::Bool: {
557         bool *b = static_cast<bool *>(result);
558         switch(d->type) {
559         case QVariant::ByteArray:
560             *b = qt_convertToBool<QByteArray, QByteArray>(d);
561             break;
562         case QVariant::String:
563             *b = qt_convertToBool<QString, QLatin1String>(d);
564             break;
565         case QVariant::Char:
566             *b = !v_cast<QChar>(d)->isNull();
567             break;
568         case QVariant::Double:
569         case QVariant::Int:
570         case QVariant::LongLong:
571         case QMetaType::Char:
572         case QMetaType::Short:
573         case QMetaType::Long:
574         case QMetaType::Float:
575             *b = qMetaTypeNumber(d) != Q_INT64_C(0);
576             break;
577         case QVariant::UInt:
578         case QVariant::ULongLong:
579         case QMetaType::UChar:
580         case QMetaType::UShort:
581         case QMetaType::ULong:
582             *b = qMetaTypeUNumber(d) != Q_UINT64_C(0);
583             break;
584         default:
585             *b = false;
586             return false;
587         }
588         break;
589     }
590     case QVariant::Double: {
591         double *f = static_cast<double *>(result);
592         switch (d->type) {
593         case QVariant::String:
594             *f = v_cast<QString>(d)->toDouble(ok);
595             break;
596         case QVariant::ByteArray:
597             *f = v_cast<QByteArray>(d)->toDouble(ok);
598             break;
599         case QVariant::Bool:
600             *f = double(d->data.b);
601             break;
602         case QMetaType::Float:
603             *f = double(d->data.f);
604             break;
605         case QVariant::LongLong:
606         case QVariant::Int:
607         case QMetaType::Char:
608         case QMetaType::Short:
609         case QMetaType::Long:
610             *f = double(qMetaTypeNumber(d));
611             break;
612         case QVariant::UInt:
613         case QVariant::ULongLong:
614         case QMetaType::UChar:
615         case QMetaType::UShort:
616         case QMetaType::ULong:
617             *f = double(qMetaTypeUNumber(d));
618             break;
619         default:
620             *f = 0.0;
621             return false;
622         }
623         break;
624     }
625     case QMetaType::Float: {
626         float *f = static_cast<float *>(result);
627         switch (d->type) {
628         case QVariant::String:
629             *f = v_cast<QString>(d)->toFloat(ok);
630             break;
631         case QVariant::ByteArray:
632             *f = v_cast<QByteArray>(d)->toFloat(ok);
633             break;
634         case QVariant::Bool:
635             *f = float(d->data.b);
636             break;
637         case QVariant::Double:
638             *f = float(d->data.d);
639             break;
640         case QVariant::LongLong:
641         case QVariant::Int:
642         case QMetaType::Char:
643         case QMetaType::Short:
644         case QMetaType::Long:
645             *f = float(qMetaTypeNumber(d));
646             break;
647         case QVariant::UInt:
648         case QVariant::ULongLong:
649         case QMetaType::UChar:
650         case QMetaType::UShort:
651         case QMetaType::ULong:
652             *f = float(qMetaTypeUNumber(d));
653             break;
654         default:
655             *f = 0.0f;
656             return false;
657         }
658         break;
659     }
660     case QVariant::List:
661         if (d->type == QVariant::StringList) {
662             QVariantList *lst = static_cast<QVariantList *>(result);
663             const QStringList *slist = v_cast<QStringList>(d);
664             for (int i = 0; i < slist->size(); ++i)
665                 lst->append(QVariant(slist->at(i)));
666         } else if (qstrcmp(QMetaType::typeName(d->type), "QList<QVariant>") == 0) {
667             *static_cast<QVariantList *>(result) =
668                 *static_cast<QList<QVariant> *>(d->data.shared->ptr);
669         } else {
670             return false;
671         }
672         break;
673     case QVariant::Map:
674         if (qstrcmp(QMetaType::typeName(d->type), "QMap<QString, QVariant>") == 0) {
675             *static_cast<QVariantMap *>(result) =
676                 *static_cast<QMap<QString, QVariant> *>(d->data.shared->ptr);
677         } else {
678             return false;
679         }
680         break;
681     case QVariant::Hash:
682         if (qstrcmp(QMetaType::typeName(d->type), "QHash<QString, QVariant>") == 0) {
683             *static_cast<QVariantHash *>(result) =
684                 *static_cast<QHash<QString, QVariant> *>(d->data.shared->ptr);
685         } else {
686             return false;
687         }
688         break;
689 #ifndef QT_NO_GEOM_VARIANT
690     case QVariant::Rect:
691         if (d->type == QVariant::RectF)
692             *static_cast<QRect *>(result) = (v_cast<QRectF>(d))->toRect();
693         else
694             return false;
695         break;
696     case QVariant::RectF:
697         if (d->type == QVariant::Rect)
698             *static_cast<QRectF *>(result) = *v_cast<QRect>(d);
699         else
700             return false;
701         break;
702     case QVariant::PointF:
703         if (d->type == QVariant::Point)
704             *static_cast<QPointF *>(result) = *v_cast<QPoint>(d);
705         else
706             return false;
707         break;
708     case QVariant::Point:
709         if (d->type == QVariant::PointF)
710             *static_cast<QPoint *>(result) = (v_cast<QPointF>(d))->toPoint();
711         else
712             return false;
713         break;
714     case QMetaType::Char:
715     {
716         *static_cast<qint8 *>(result) = qint8(qConvertToNumber(d, ok));
717         return *ok;
718     }
719 #endif
720     case QVariant::Uuid:
721         switch (d->type) {
722         case QVariant::String:
723             *static_cast<QUuid *>(result) = QUuid(*v_cast<QString>(d));
724             break;
725         default:
726             return false;
727         }
728         break;
729     default:
730         return false;
731     }
732     return true;
733 }
734
735 #if !defined(QT_NO_DEBUG_STREAM)
736 static void streamDebug(QDebug dbg, const QVariant &v)
737 {
738     QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
739     QVariantDebugStream<CoreTypesFilter> stream(dbg, d);
740     QMetaTypeSwitcher::switcher<void>(stream, d->type, 0);
741 }
742 #endif
743
744 const QVariant::Handler qt_kernel_variant_handler = {
745     construct,
746     clear,
747     isNull,
748 #ifndef QT_NO_DATASTREAM
749     0,
750     0,
751 #endif
752     compare,
753     convert,
754     0,
755 #if !defined(QT_NO_DEBUG_STREAM)
756     streamDebug
757 #else
758     0
759 #endif
760 };
761
762 static void dummyConstruct(QVariant::Private *, const void *) { Q_ASSERT_X(false, "QVariant", "Trying to construct an unknown type"); }
763 static void dummyClear(QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to clear an unknown type"); }
764 static bool dummyIsNull(const QVariant::Private *d) { Q_ASSERT_X(false, "QVariant::isNull", "Trying to call isNull on an unknown type"); return d->is_null; }
765 static bool dummyCompare(const QVariant::Private *, const QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to compare an unknown types"); return false; }
766 static bool dummyConvert(const QVariant::Private *, int, void *, bool *) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); return false; }
767 #if !defined(QT_NO_DEBUG_STREAM)
768 static void dummyStreamDebug(QDebug, const QVariant &) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); }
769 #endif
770 const QVariant::Handler qt_dummy_variant_handler = {
771     dummyConstruct,
772     dummyClear,
773     dummyIsNull,
774 #ifndef QT_NO_DATASTREAM
775     0,
776     0,
777 #endif
778     dummyCompare,
779     dummyConvert,
780     0,
781 #if !defined(QT_NO_DEBUG_STREAM)
782     dummyStreamDebug
783 #else
784     0
785 #endif
786 };
787
788 static void customConstruct(QVariant::Private *d, const void *copy)
789 {
790     const QMetaType type(d->type);
791     const uint size = type.sizeOf();
792     if (!size) {
793         d->type = QVariant::Invalid;
794         return;
795     }
796
797     // this logic should match with QVariantIntegrator::CanUseInternalSpace
798     if (size <= sizeof(QVariant::Private::Data)
799             && (type.flags() & QMetaType::MovableType)) {
800         type.construct(&d->data.ptr, copy);
801         d->is_shared = false;
802     } else {
803         void *ptr = type.create(copy);
804         d->is_shared = true;
805         d->data.shared = new QVariant::PrivateShared(ptr);
806     }
807 }
808
809 static void customClear(QVariant::Private *d)
810 {
811     if (!d->is_shared) {
812         QMetaType::destruct(d->type, &d->data.ptr);
813     } else {
814         QMetaType::destroy(d->type, d->data.shared->ptr);
815         delete d->data.shared;
816     }
817 }
818
819 static bool customIsNull(const QVariant::Private *d)
820 {
821     return d->is_null;
822 }
823
824 static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
825 {
826     const char *const typeName = QMetaType::typeName(a->type);
827     if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(a->type)))
828         qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
829
830     const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data.ptr);
831     const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data.ptr);
832
833     uint typeNameLen = qstrlen(typeName);
834     if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*')
835         return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
836
837     if (a->is_null && b->is_null)
838         return true;
839
840     return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
841 }
842
843 static bool customConvert(const QVariant::Private *, int, void *, bool *ok)
844 {
845     if (ok)
846         *ok = false;
847     return false;
848 }
849
850 #if !defined(QT_NO_DEBUG_STREAM)
851 static void customStreamDebug(QDebug, const QVariant &) {}
852 #endif
853
854 const QVariant::Handler qt_custom_variant_handler = {
855     customConstruct,
856     customClear,
857     customIsNull,
858 #ifndef QT_NO_DATASTREAM
859     0,
860     0,
861 #endif
862     customCompare,
863     customConvert,
864     0,
865 #if !defined(QT_NO_DEBUG_STREAM)
866     customStreamDebug
867 #else
868     0
869 #endif
870 };
871
872 } // annonymous used to hide QVariant handlers
873
874 static HandlersManager handlerManager;
875 Q_STATIC_ASSERT_X(!QModulesPrivate::Core, "Initialization assumes that ModulesNames::Core is 0");
876 const QVariant::Handler *HandlersManager::Handlers[QModulesPrivate::ModulesCount]
877                                         = { &qt_kernel_variant_handler, &qt_dummy_variant_handler,
878                                             &qt_dummy_variant_handler, &qt_custom_variant_handler };
879
880 Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler()
881 {
882     return &qt_kernel_variant_handler;
883 }
884
885 inline void HandlersManager::unregisterHandler(const QModulesPrivate::Names name)
886 {
887     Handlers[name] = &qt_dummy_variant_handler;
888 }
889
890 Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names */name, const QVariant::Handler *handler)
891 {
892     handlerManager.registerHandler(static_cast<QModulesPrivate::Names>(name), handler);
893 }
894
895 Q_CORE_EXPORT void QVariantPrivate::unregisterHandler(const int /* Modules::Names */ name)
896 {
897     handlerManager.unregisterHandler(static_cast<QModulesPrivate::Names>(name));
898 }
899
900 /*!
901     \class QVariant
902     \brief The QVariant class acts like a union for the most common Qt data types.
903
904     \ingroup objectmodel
905     \ingroup shared
906
907
908     Because C++ forbids unions from including types that have
909     non-default constructors or destructors, most interesting Qt
910     classes cannot be used in unions. Without QVariant, this would be
911     a problem for QObject::property() and for database work, etc.
912
913     A QVariant object holds a single value of a single type() at a
914     time. (Some type()s are multi-valued, for example a string list.)
915     You can find out what type, T, the variant holds, convert it to a
916     different type using convert(), get its value using one of the
917     toT() functions (e.g., toSize()) and check whether the type can
918     be converted to a particular type using canConvert().
919
920     The methods named toT() (e.g., toInt(), toString()) are const. If
921     you ask for the stored type, they return a copy of the stored
922     object. If you ask for a type that can be generated from the
923     stored type, toT() copies and converts and leaves the object
924     itself unchanged. If you ask for a type that cannot be generated
925     from the stored type, the result depends on the type; see the
926     function documentation for details.
927
928     Here is some example code to demonstrate the use of QVariant:
929
930     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 0
931
932     You can even store QList<QVariant> and QMap<QString, QVariant>
933     values in a variant, so you can easily construct arbitrarily
934     complex data structures of arbitrary types. This is very powerful
935     and versatile, but may prove less memory and speed efficient than
936     storing specific types in standard data structures.
937
938     QVariant also supports the notion of null values, where you can
939     have a defined type with no value set. However, note that QVariant
940     types can only be cast when they have had a value set.
941
942     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 1
943
944     QVariant can be extended to support other types than those
945     mentioned in the \l Type enum. See the \l QMetaType documentation
946     for details.
947
948     \section1 A Note on GUI Types
949
950     Because QVariant is part of the QtCore library, it cannot provide
951     conversion functions to data types defined in QtGui, such as
952     QColor, QImage, and QPixmap. In other words, there is no \c
953     toColor() function. Instead, you can use the QVariant::value() or
954     the qvariant_cast() template function. For example:
955
956     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 2
957
958     The inverse conversion (e.g., from QColor to QVariant) is
959     automatic for all data types supported by QVariant, including
960     GUI-related types:
961
962     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 3
963
964     \section1 Using canConvert() and convert() Consecutively
965
966     When using canConvert() and convert() consecutively, it is possible for
967     canConvert() to return true, but convert() to return false. This
968     is typically because canConvert() only reports the general ability of
969     QVariant to convert between types given suitable data; it is still
970     possible to supply data which cannot actually be converted.
971
972     For example, canConvert() would return true when called on a variant
973     containing a string because, in principle, QVariant is able to convert
974     strings of numbers to integers.
975     However, if the string contains non-numeric characters, it cannot be
976     converted to an integer, and any attempt to convert it will fail.
977     Hence, it is important to have both functions return true for a
978     successful conversion.
979
980     \sa QMetaType
981 */
982
983 /*!
984     \obsolete Use QMetaType::Type instead
985     \enum QVariant::Type
986
987     This enum type defines the types of variable that a QVariant can
988     contain.
989
990     \value Invalid  no type
991     \value BitArray  a QBitArray
992     \value Bitmap  a QBitmap
993     \value Bool  a bool
994     \value Brush  a QBrush
995     \value ByteArray  a QByteArray
996     \value Char  a QChar
997     \value Color  a QColor
998     \value Cursor  a QCursor
999     \value Date  a QDate
1000     \value DateTime  a QDateTime
1001     \value Double  a double
1002     \value EasingCurve a QEasingCurve
1003     \value Uuid a QUuid
1004     \value ModelIndex a QModelIndex
1005     \value Font  a QFont
1006     \value Hash a QVariantHash
1007     \value Icon  a QIcon
1008     \value Image  a QImage
1009     \value Int  an int
1010     \value KeySequence  a QKeySequence
1011     \value Line  a QLine
1012     \value LineF  a QLineF
1013     \value List  a QVariantList
1014     \value Locale  a QLocale
1015     \value LongLong a \l qlonglong
1016     \value Map  a QVariantMap
1017     \value Matrix  a QMatrix
1018     \value Transform  a QTransform
1019     \value Matrix4x4  a QMatrix4x4
1020     \value Palette  a QPalette
1021     \value Pen  a QPen
1022     \value Pixmap  a QPixmap
1023     \value Point  a QPoint
1024     \value PointF  a QPointF
1025     \value Polygon a QPolygon
1026     \value PolygonF a QPolygonF
1027     \value Quaternion  a QQuaternion
1028     \value Rect  a QRect
1029     \value RectF  a QRectF
1030     \value RegExp  a QRegExp
1031     \value Region  a QRegion
1032     \value Size  a QSize
1033     \value SizeF  a QSizeF
1034     \value SizePolicy  a QSizePolicy
1035     \value String  a QString
1036     \value StringList  a QStringList
1037     \value TextFormat  a QTextFormat
1038     \value TextLength  a QTextLength
1039     \value Time  a QTime
1040     \value UInt  a \l uint
1041     \value ULongLong a \l qulonglong
1042     \value Url  a QUrl
1043     \value Vector2D  a QVector2D
1044     \value Vector3D  a QVector3D
1045     \value Vector4D  a QVector4D
1046
1047     \value UserType Base value for user-defined types.
1048
1049     \omitvalue CString
1050     \omitvalue ColorGroup
1051     \omitvalue IconSet
1052     \omitvalue LastGuiType
1053     \omitvalue LastCoreType
1054     \omitvalue LastType
1055 */
1056
1057 /*!
1058     \fn QVariant::QVariant()
1059
1060     Constructs an invalid variant.
1061 */
1062
1063
1064 /*!
1065     \fn QVariant::QVariant(int typeId, const void *copy)
1066
1067     Constructs variant of type \a typeId, and initializes with
1068     \a copy if \a copy is not 0.
1069
1070     Note that you have to pass the address of the variable you want stored.
1071
1072     Usually, you never have to use this constructor, use QVariant::fromValue()
1073     instead to construct variants from the pointer types represented by
1074     \c QMetaType::VoidStar, \c QMetaType::QObjectStar and
1075     \c QMetaType::QWidgetStar.
1076
1077     \sa QVariant::fromValue(), Type
1078 */
1079
1080 /*!
1081     \fn QVariant::QVariant(Type type)
1082
1083     Constructs a null variant of type \a type.
1084 */
1085
1086
1087
1088 /*!
1089     \fn QVariant::create(int type, const void *copy)
1090
1091     \internal
1092
1093     Constructs a variant private of type \a type, and initializes with \a copy if
1094     \a copy is not 0.
1095 */
1096
1097 void QVariant::create(int type, const void *copy)
1098 {
1099     d.type = type;
1100     handlerManager[type]->construct(&d, copy);
1101 }
1102
1103 /*!
1104     \fn QVariant::~QVariant()
1105
1106     Destroys the QVariant and the contained object.
1107
1108     Note that subclasses that reimplement clear() should reimplement
1109     the destructor to call clear(). This destructor calls clear(), but
1110     because it is the destructor, QVariant::clear() is called rather
1111     than a subclass's clear().
1112 */
1113
1114 QVariant::~QVariant()
1115 {
1116     if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
1117         handlerManager[d.type]->clear(&d);
1118 }
1119
1120 /*!
1121   \fn QVariant::QVariant(const QVariant &p)
1122
1123     Constructs a copy of the variant, \a p, passed as the argument to
1124     this constructor.
1125 */
1126
1127 QVariant::QVariant(const QVariant &p)
1128     : d(p.d)
1129 {
1130     if (d.is_shared) {
1131         d.data.shared->ref.ref();
1132     } else if (p.d.type > Char) {
1133         handlerManager[d.type]->construct(&d, p.constData());
1134         d.is_null = p.d.is_null;
1135     }
1136 }
1137
1138 #ifndef QT_NO_DATASTREAM
1139 /*!
1140     Reads the variant from the data stream, \a s.
1141 */
1142 QVariant::QVariant(QDataStream &s)
1143 {
1144     d.is_null = true;
1145     s >> *this;
1146 }
1147 #endif //QT_NO_DATASTREAM
1148
1149 /*!
1150   \fn QVariant::QVariant(const QString &val)
1151
1152     Constructs a new variant with a string value, \a val.
1153 */
1154
1155 /*!
1156   \fn QVariant::QVariant(const QLatin1String &val)
1157
1158     Constructs a new variant with a string value, \a val.
1159 */
1160
1161 /*!
1162   \fn QVariant::QVariant(const char *val)
1163
1164     Constructs a new variant with a string value of \a val.
1165     The variant creates a deep copy of \a val into a QString assuming
1166     UTF-8 encoding on the input \a val.
1167
1168     Note that \a val is converted to a QString for storing in the
1169     variant and QVariant::userType() will return QMetaType::QString for
1170     the variant.
1171
1172     You can disable this operator by defining \c
1173     QT_NO_CAST_FROM_ASCII when you compile your applications.
1174 */
1175
1176 #ifndef QT_NO_CAST_FROM_ASCII
1177 QVariant::QVariant(const char *val)
1178 {
1179     QString s = QString::fromAscii(val);
1180     create(String, &s);
1181 }
1182 #endif
1183
1184 /*!
1185   \fn QVariant::QVariant(const QStringList &val)
1186
1187     Constructs a new variant with a string list value, \a val.
1188 */
1189
1190 /*!
1191   \fn QVariant::QVariant(const QMap<QString, QVariant> &val)
1192
1193     Constructs a new variant with a map of QVariants, \a val.
1194 */
1195
1196 /*!
1197   \fn QVariant::QVariant(const QHash<QString, QVariant> &val)
1198
1199     Constructs a new variant with a hash of QVariants, \a val.
1200 */
1201
1202 /*!
1203   \fn QVariant::QVariant(const QDate &val)
1204
1205     Constructs a new variant with a date value, \a val.
1206 */
1207
1208 /*!
1209   \fn QVariant::QVariant(const QTime &val)
1210
1211     Constructs a new variant with a time value, \a val.
1212 */
1213
1214 /*!
1215   \fn QVariant::QVariant(const QDateTime &val)
1216
1217     Constructs a new variant with a date/time value, \a val.
1218 */
1219
1220 /*!
1221     \since 4.7
1222   \fn QVariant::QVariant(const QEasingCurve &val)
1223
1224     Constructs a new variant with an easing curve value, \a val.
1225 */
1226
1227 /*!
1228   \fn QVariant::QVariant(const QByteArray &val)
1229
1230     Constructs a new variant with a bytearray value, \a val.
1231 */
1232
1233 /*!
1234   \fn QVariant::QVariant(const QBitArray &val)
1235
1236     Constructs a new variant with a bitarray value, \a val.
1237 */
1238
1239 /*!
1240   \fn QVariant::QVariant(const QPoint &val)
1241
1242   Constructs a new variant with a point value of \a val.
1243  */
1244
1245 /*!
1246   \fn QVariant::QVariant(const QPointF &val)
1247
1248   Constructs a new variant with a point value of \a val.
1249  */
1250
1251 /*!
1252   \fn QVariant::QVariant(const QRectF &val)
1253
1254   Constructs a new variant with a rect value of \a val.
1255  */
1256
1257 /*!
1258   \fn QVariant::QVariant(const QLineF &val)
1259
1260   Constructs a new variant with a line value of \a val.
1261  */
1262
1263 /*!
1264   \fn QVariant::QVariant(const QLine &val)
1265
1266   Constructs a new variant with a line value of \a val.
1267  */
1268
1269 /*!
1270   \fn QVariant::QVariant(const QRect &val)
1271
1272   Constructs a new variant with a rect value of \a val.
1273  */
1274
1275 /*!
1276   \fn QVariant::QVariant(const QSize &val)
1277
1278   Constructs a new variant with a size value of \a val.
1279  */
1280
1281 /*!
1282   \fn QVariant::QVariant(const QSizeF &val)
1283
1284   Constructs a new variant with a size value of \a val.
1285  */
1286
1287 /*!
1288   \fn QVariant::QVariant(const QUrl &val)
1289
1290   Constructs a new variant with a url value of \a val.
1291  */
1292
1293 /*!
1294   \fn QVariant::QVariant(int val)
1295
1296     Constructs a new variant with an integer value, \a val.
1297 */
1298
1299 /*!
1300   \fn QVariant::QVariant(uint val)
1301
1302     Constructs a new variant with an unsigned integer value, \a val.
1303 */
1304
1305 /*!
1306   \fn QVariant::QVariant(qlonglong val)
1307
1308     Constructs a new variant with a long long integer value, \a val.
1309 */
1310
1311 /*!
1312   \fn QVariant::QVariant(qulonglong val)
1313
1314     Constructs a new variant with an unsigned long long integer value, \a val.
1315 */
1316
1317
1318 /*!
1319   \fn QVariant::QVariant(bool val)
1320
1321     Constructs a new variant with a boolean value, \a val.
1322 */
1323
1324 /*!
1325   \fn QVariant::QVariant(double val)
1326
1327     Constructs a new variant with a floating point value, \a val.
1328 */
1329
1330 /*!
1331   \fn QVariant::QVariant(float val)
1332
1333     Constructs a new variant with a floating point value, \a val.
1334     \since 4.6
1335 */
1336
1337 /*!
1338     \fn QVariant::QVariant(const QList<QVariant> &val)
1339
1340     Constructs a new variant with a list value, \a val.
1341 */
1342
1343 /*!
1344   \fn QVariant::QVariant(QChar c)
1345
1346   Constructs a new variant with a char value, \a c.
1347 */
1348
1349 /*!
1350   \fn QVariant::QVariant(const QLocale &l)
1351
1352   Constructs a new variant with a locale value, \a l.
1353 */
1354
1355 /*!
1356   \fn QVariant::QVariant(const QRegExp &regExp)
1357
1358   Constructs a new variant with the regexp value \a regExp.
1359 */
1360
1361 /*! \since 4.2
1362   \fn QVariant::QVariant(Qt::GlobalColor color)
1363
1364   Constructs a new variant of type QVariant::Color and initializes
1365   it with \a color.
1366
1367   This is a convenience constructor that allows \c{QVariant(Qt::blue);}
1368   to create a valid QVariant storing a QColor.
1369
1370   Note: This constructor will assert if the application does not link
1371   to the Qt GUI library.
1372  */
1373
1374 QVariant::QVariant(Type type)
1375 { create(type, 0); }
1376 QVariant::QVariant(int typeId, const void *copy)
1377 { create(typeId, copy); d.is_null = false; }
1378
1379 /*! \internal
1380     flags is true if it is a pointer type
1381  */
1382 QVariant::QVariant(int typeId, const void *copy, uint flags)
1383 {
1384     if (flags) { //type is a pointer type
1385         d.type = typeId;
1386         d.data.ptr = *reinterpret_cast<void *const*>(copy);
1387     } else {
1388         create(typeId, copy);
1389     }
1390     d.is_null = false;
1391 }
1392
1393 QVariant::QVariant(int val)
1394 { d.is_null = false; d.type = Int; d.data.i = val; }
1395 QVariant::QVariant(uint val)
1396 { d.is_null = false; d.type = UInt; d.data.u = val; }
1397 QVariant::QVariant(qlonglong val)
1398 { d.is_null = false; d.type = LongLong; d.data.ll = val; }
1399 QVariant::QVariant(qulonglong val)
1400 { d.is_null = false; d.type = ULongLong; d.data.ull = val; }
1401 QVariant::QVariant(bool val)
1402 { d.is_null = false; d.type = Bool; d.data.b = val; }
1403 QVariant::QVariant(double val)
1404 { d.is_null = false; d.type = Double; d.data.d = val; }
1405
1406 QVariant::QVariant(const QByteArray &val)
1407 { d.is_null = false; d.type = ByteArray; v_construct<QByteArray>(&d, val); }
1408 QVariant::QVariant(const QBitArray &val)
1409 { d.is_null = false; d.type = BitArray; v_construct<QBitArray>(&d, val);  }
1410 QVariant::QVariant(const QString &val)
1411 { d.is_null = false; d.type = String; v_construct<QString>(&d, val);  }
1412 QVariant::QVariant(QChar val)
1413 { d.is_null = false; d.type = Char; v_construct<QChar>(&d, val);  }
1414 QVariant::QVariant(const QLatin1String &val)
1415 { QString str(val); d.is_null = false; d.type = String; v_construct<QString>(&d, str); }
1416 QVariant::QVariant(const QStringList &val)
1417 { d.is_null = false; d.type = StringList; v_construct<QStringList>(&d, val); }
1418
1419 QVariant::QVariant(const QDate &val)
1420 { d.is_null = false; d.type = Date; v_construct<QDate>(&d, val); }
1421 QVariant::QVariant(const QTime &val)
1422 { d.is_null = false; d.type = Time; v_construct<QTime>(&d, val); }
1423 QVariant::QVariant(const QDateTime &val)
1424 { d.is_null = false; d.type = DateTime; v_construct<QDateTime>(&d, val); }
1425 #ifndef QT_BOOTSTRAPPED
1426 QVariant::QVariant(const QEasingCurve &val)
1427 { d.is_null = false; d.type = EasingCurve; v_construct<QEasingCurve>(&d, val); }
1428 #endif
1429 QVariant::QVariant(const QList<QVariant> &list)
1430 { d.is_null = false; d.type = List; v_construct<QVariantList>(&d, list); }
1431 QVariant::QVariant(const QMap<QString, QVariant> &map)
1432 { d.is_null = false; d.type = Map; v_construct<QVariantMap>(&d, map); }
1433 QVariant::QVariant(const QHash<QString, QVariant> &hash)
1434 { d.is_null = false; d.type = Hash; v_construct<QVariantHash>(&d, hash); }
1435 #ifndef QT_NO_GEOM_VARIANT
1436 QVariant::QVariant(const QPoint &pt) { d.is_null = false; d.type = Point; v_construct<QPoint>(&d, pt); }
1437 QVariant::QVariant(const QPointF &pt) { d.is_null = false; d.type = PointF; v_construct<QPointF>(&d, pt); }
1438 QVariant::QVariant(const QRectF &r) { d.is_null = false; d.type = RectF; v_construct<QRectF>(&d, r); }
1439 QVariant::QVariant(const QLineF &l) { d.is_null = false; d.type = LineF; v_construct<QLineF>(&d, l); }
1440 QVariant::QVariant(const QLine &l) { d.is_null = false; d.type = Line; v_construct<QLine>(&d, l); }
1441 QVariant::QVariant(const QRect &r) { d.is_null = false; d.type = Rect; v_construct<QRect>(&d, r); }
1442 QVariant::QVariant(const QSize &s) { d.is_null = false; d.type = Size; v_construct<QSize>(&d, s); }
1443 QVariant::QVariant(const QSizeF &s) { d.is_null = false; d.type = SizeF; v_construct<QSizeF>(&d, s); }
1444 #endif
1445 QVariant::QVariant(const QUrl &u) { d.is_null = false; d.type = Url; v_construct<QUrl>(&d, u); }
1446 QVariant::QVariant(const QLocale &l) { d.is_null = false; d.type = Locale; v_construct<QLocale>(&d, l); }
1447 #ifndef QT_NO_REGEXP
1448 QVariant::QVariant(const QRegExp &regExp) { d.is_null = false; d.type = RegExp; v_construct<QRegExp>(&d, regExp); }
1449 #endif
1450 QVariant::QVariant(Qt::GlobalColor color) { create(62, &color); }
1451
1452 /*!
1453     Returns the storage type of the value stored in the variant.
1454     Although this function is declared as returning QVariant::Type,
1455     the return value should be interpreted as QMetaType::Type. In
1456     particular, QVariant::UserType is returned here only if the value
1457     is equal or greater than QMetaType::User.
1458
1459     Note that return values in the ranges QVariant::Char through
1460     QVariant::RegExp and QVariant::Font through QVariant::Transform
1461     correspond to the values in the ranges QMetaType::QChar through
1462     QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion.
1463
1464     Pay particular attention when working with char and QChar
1465     variants.  Note that there is no QVariant constructor specifically
1466     for type char, but there is one for QChar. For a variant of type
1467     QChar, this function returns QVariant::Char, which is the same as
1468     QMetaType::QChar, but for a variant of type \c char, this function
1469     returns QMetaType::Char, which is \e not the same as
1470     QVariant::Char.
1471
1472     Also note that the types \c void*, \c long, \c short, \c unsigned
1473     \c long, \c unsigned \c short, \c unsigned \c char, \c float, \c
1474     QObject*, and \c QWidget* are represented in QMetaType::Type but
1475     not in QVariant::Type, and they can be returned by this function.
1476     However, they are considered to be user defined types when tested
1477     against QVariant::Type.
1478
1479     To test whether an instance of QVariant contains a data type that
1480     is compatible with the data type you are interested in, use
1481     canConvert().
1482 */
1483
1484 QVariant::Type QVariant::type() const
1485 {
1486     return d.type >= QMetaType::User ? UserType : static_cast<Type>(d.type);
1487 }
1488
1489 /*!
1490     Returns the storage type of the value stored in the variant. For
1491     non-user types, this is the same as type().
1492
1493     \sa type()
1494 */
1495
1496 int QVariant::userType() const
1497 {
1498     return d.type;
1499 }
1500
1501 /*!
1502     Assigns the value of the variant \a variant to this variant.
1503 */
1504 QVariant& QVariant::operator=(const QVariant &variant)
1505 {
1506     if (this == &variant)
1507         return *this;
1508
1509     clear();
1510     if (variant.d.is_shared) {
1511         variant.d.data.shared->ref.ref();
1512         d = variant.d;
1513     } else if (variant.d.type > Char) {
1514         d.type = variant.d.type;
1515         handlerManager[d.type]->construct(&d, variant.constData());
1516         d.is_null = variant.d.is_null;
1517     } else {
1518         d = variant.d;
1519     }
1520
1521     return *this;
1522 }
1523
1524 /*!
1525     \fn void QVariant::swap(QVariant &other)
1526     \since 4.8
1527
1528     Swaps variant \a other with this variant. This operation is very
1529     fast and never fails.
1530 */
1531
1532 /*!
1533     \fn void QVariant::detach()
1534
1535     \internal
1536 */
1537
1538 void QVariant::detach()
1539 {
1540     if (!d.is_shared || d.data.shared->ref.load() == 1)
1541         return;
1542
1543     Private dd;
1544     dd.type = d.type;
1545     handlerManager[d.type]->construct(&dd, constData());
1546     if (!d.data.shared->ref.deref())
1547         handlerManager[d.type]->clear(&d);
1548     d.data.shared = dd.data.shared;
1549 }
1550
1551 /*!
1552     \fn bool QVariant::isDetached() const
1553
1554     \internal
1555 */
1556
1557 // ### Qt 5: change typeName()(and froends= to return a QString. Suggestion from Harald.
1558 /*!
1559     Returns the name of the type stored in the variant. The returned
1560     strings describe the C++ datatype used to store the data: for
1561     example, "QFont", "QString", or "QVariantList". An Invalid
1562     variant returns 0.
1563 */
1564 const char *QVariant::typeName() const
1565 {
1566     return typeToName(d.type);
1567 }
1568
1569 /*!
1570     Convert this variant to type Invalid and free up any resources
1571     used.
1572 */
1573 void QVariant::clear()
1574 {
1575     if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
1576         handlerManager[d.type]->clear(&d);
1577     d.type = Invalid;
1578     d.is_null = true;
1579     d.is_shared = false;
1580 }
1581
1582 /*!
1583     Converts the int representation of the storage type, \a typeId, to
1584     its string representation.
1585
1586     Returns a null pointer if the type is QVariant::Invalid or doesn't exist.
1587 */
1588 const char *QVariant::typeToName(int typeId)
1589 {
1590     if (typeId == Invalid)
1591         return 0;
1592
1593     return QMetaType::typeName(typeId);
1594 }
1595
1596
1597 /*!
1598     Converts the string representation of the storage type given in \a
1599     name, to its enum representation.
1600
1601     If the string representation cannot be converted to any enum
1602     representation, the variant is set to \c Invalid.
1603 */
1604 QVariant::Type QVariant::nameToType(const char *name)
1605 {
1606     if (!name || !*name)
1607         return Invalid;
1608
1609     int metaType = QMetaType::type(name);
1610     return metaType <= int(UserType) ? QVariant::Type(metaType) : UserType;
1611 }
1612
1613 #ifndef QT_NO_DATASTREAM
1614 enum { MapFromThreeCount = 36 };
1615 static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] =
1616 {
1617     QVariant::Invalid,
1618     QVariant::Map,
1619     QVariant::List,
1620     QVariant::String,
1621     QVariant::StringList,
1622     QVariant::Font,
1623     QVariant::Pixmap,
1624     QVariant::Brush,
1625     QVariant::Rect,
1626     QVariant::Size,
1627     QVariant::Color,
1628     QVariant::Palette,
1629     0, // ColorGroup
1630     QVariant::Icon,
1631     QVariant::Point,
1632     QVariant::Image,
1633     QVariant::Int,
1634     QVariant::UInt,
1635     QVariant::Bool,
1636     QVariant::Double,
1637     QVariant::ByteArray,
1638     QVariant::Polygon,
1639     QVariant::Region,
1640     QVariant::Bitmap,
1641     QVariant::Cursor,
1642     QVariant::SizePolicy,
1643     QVariant::Date,
1644     QVariant::Time,
1645     QVariant::DateTime,
1646     QVariant::ByteArray,
1647     QVariant::BitArray,
1648     QVariant::KeySequence,
1649     QVariant::Pen,
1650     QVariant::LongLong,
1651     QVariant::ULongLong,
1652     QVariant::EasingCurve
1653 };
1654
1655 /*!
1656     Internal function for loading a variant from stream \a s. Use the
1657     stream operators instead.
1658
1659     \internal
1660 */
1661 void QVariant::load(QDataStream &s)
1662 {
1663     clear();
1664
1665     quint32 typeId;
1666     s >> typeId;
1667     if (s.version() < QDataStream::Qt_4_0) {
1668         if (typeId >= MapFromThreeCount)
1669             return;
1670         typeId = mapIdFromQt3ToCurrent[typeId];
1671     } else if (s.version() < QDataStream::Qt_5_0) {
1672         if (typeId == 127 /* QVariant::UserType */) {
1673             typeId = QMetaType::User;
1674         } else if (typeId >= 128 && typeId != QVariant::UserType) {
1675             // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
1676             // by moving all ids down by 97.
1677             typeId -= 97;
1678         } else if (typeId == 69 /* QIcon */) {
1679             // In Qt5 after modularization project this types where moved to a separate module (and ids were downgraded)
1680             typeId = QMetaType::QIcon;
1681         } else if (typeId == 75 /* QSizePolicy */) {
1682             typeId = QMetaType::QSizePolicy;
1683         } else if (typeId >= 70) {
1684             // and as a result this types recieved lower ids too
1685             if (typeId <= 74) { // QImage QPolygon QRegion QBitmap QCursor
1686                 typeId -=1;
1687             } else if (typeId <= 86) { // QKeySequence QPen QTextLength QTextFormat QMatrix QTransform QMatrix4x4 QVector2D QVector3D QVector4D QQuaternion
1688                 typeId -=2;
1689             }
1690         }
1691     }
1692
1693     qint8 is_null = false;
1694     if (s.version() >= QDataStream::Qt_4_2)
1695         s >> is_null;
1696     if (typeId == QVariant::UserType) {
1697         QByteArray name;
1698         s >> name;
1699         typeId = QMetaType::type(name);
1700         if (typeId == QMetaType::UnknownType) {
1701             s.setStatus(QDataStream::ReadCorruptData);
1702             return;
1703         }
1704     }
1705     create(static_cast<int>(typeId), 0);
1706     d.is_null = is_null;
1707
1708     if (!isValid()) {
1709         // Since we wrote something, we should read something
1710         QString x;
1711         s >> x;
1712         d.is_null = true;
1713         return;
1714     }
1715
1716     // const cast is safe since we operate on a newly constructed variant
1717     if (!QMetaType::load(s, d.type, const_cast<void *>(constData()))) {
1718         s.setStatus(QDataStream::ReadCorruptData);
1719         qWarning("QVariant::load: unable to load type %d.", d.type);
1720     }
1721 }
1722
1723 /*!
1724     Internal function for saving a variant to the stream \a s. Use the
1725     stream operators instead.
1726
1727     \internal
1728 */
1729 void QVariant::save(QDataStream &s) const
1730 {
1731     quint32 typeId = type();
1732     if (s.version() < QDataStream::Qt_4_0) {
1733         int i;
1734         for (i = MapFromThreeCount - 1; i >= 0; i--) {
1735             if (mapIdFromQt3ToCurrent[i] == typeId) {
1736                 typeId = i;
1737                 break;
1738             }
1739         }
1740         if (i == -1) {
1741             s << QVariant();
1742             return;
1743         }
1744     } else if (s.version() < QDataStream::Qt_5_0) {
1745         if (typeId == QMetaType::User) {
1746             typeId = 127; // QVariant::UserType had this value in Qt4
1747         } else if (typeId >= 128 - 97 && typeId <= LastCoreType) {
1748             // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
1749             // by moving all ids down by 97.
1750             typeId += 97;
1751         } else if (typeId == QMetaType::QIcon) {
1752             // In Qt5 after modularization project this types where moved to a separate module (and ids were downgraded)
1753             typeId = 69;
1754         } else if (typeId == QMetaType::QSizePolicy) {
1755             typeId = 75;
1756         } else if (typeId >= QMetaType::QImage) {
1757             // and as a result this types recieved lower ids too
1758             if (typeId <= QMetaType::QCursor) {
1759                 typeId +=1;
1760             } else if (typeId <= QMetaType::QQuaternion) {
1761                 typeId +=2;
1762             }
1763         }
1764     }
1765     s << typeId;
1766     if (s.version() >= QDataStream::Qt_4_2)
1767         s << qint8(d.is_null);
1768     if (d.type >= QVariant::UserType) {
1769         s << QMetaType::typeName(userType());
1770     }
1771
1772     if (!isValid()) {
1773         s << QString();
1774         return;
1775     }
1776
1777     if (!QMetaType::save(s, d.type, constData())) {
1778         qWarning("QVariant::save: unable to save type '%s' (type id: %d).\n", QMetaType::typeName(d.type), d.type);
1779         Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
1780     }
1781 }
1782
1783 /*!
1784     \since 4.4
1785
1786     Reads a variant \a p from the stream \a s.
1787
1788     \sa \link datastreamformat.html Format of the QDataStream
1789     operators \endlink
1790 */
1791 QDataStream& operator>>(QDataStream &s, QVariant &p)
1792 {
1793     p.load(s);
1794     return s;
1795 }
1796
1797 /*!
1798     Writes a variant \a p to the stream \a s.
1799
1800     \sa \link datastreamformat.html Format of the QDataStream
1801     operators \endlink
1802 */
1803 QDataStream& operator<<(QDataStream &s, const QVariant &p)
1804 {
1805     p.save(s);
1806     return s;
1807 }
1808
1809 /*!
1810     Reads a variant type \a p in enum representation from the stream \a s.
1811 */
1812 QDataStream& operator>>(QDataStream &s, QVariant::Type &p)
1813 {
1814     quint32 u;
1815     s >> u;
1816     p = (QVariant::Type)u;
1817
1818     return s;
1819 }
1820
1821 /*!
1822     Writes a variant type \a p to the stream \a s.
1823 */
1824 QDataStream& operator<<(QDataStream &s, const QVariant::Type p)
1825 {
1826     s << static_cast<quint32>(p);
1827
1828     return s;
1829 }
1830
1831 #endif //QT_NO_DATASTREAM
1832
1833 /*!
1834     \fn bool QVariant::isValid() const
1835
1836     Returns true if the storage type of this variant is not
1837     QVariant::Invalid; otherwise returns false.
1838 */
1839
1840 template <typename T>
1841 inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &handlerManager)
1842 {
1843     const uint targetType = qMetaTypeId<T>();
1844     if (d.type == targetType)
1845         return *v_cast<T>(&d);
1846
1847     T ret;
1848     handlerManager[d.type]->convert(&d, targetType, &ret, 0);
1849     return ret;
1850 }
1851
1852 /*!
1853     \fn QStringList QVariant::toStringList() const
1854
1855     Returns the variant as a QStringList if the variant has type()
1856     StringList, \l String, or \l List of a type that can be converted
1857     to QString; otherwise returns an empty list.
1858
1859     \sa canConvert(), convert()
1860 */
1861 QStringList QVariant::toStringList() const
1862 {
1863     return qVariantToHelper<QStringList>(d, handlerManager);
1864 }
1865
1866 /*!
1867     Returns the variant as a QString if the variant has type() \l
1868     String, \l Bool, \l ByteArray, \l Char, \l Date, \l DateTime, \l
1869     Double, \l Int, \l LongLong, \l StringList, \l Time, \l UInt, or
1870     \l ULongLong; otherwise returns an empty string.
1871
1872     \sa canConvert(), convert()
1873 */
1874 QString QVariant::toString() const
1875 {
1876     return qVariantToHelper<QString>(d, handlerManager);
1877 }
1878
1879 /*!
1880     Returns the variant as a QMap<QString, QVariant> if the variant
1881     has type() \l Map; otherwise returns an empty map.
1882
1883     \sa canConvert(), convert()
1884 */
1885 QVariantMap QVariant::toMap() const
1886 {
1887     return qVariantToHelper<QVariantMap>(d, handlerManager);
1888 }
1889
1890 /*!
1891     Returns the variant as a QHash<QString, QVariant> if the variant
1892     has type() \l Hash; otherwise returns an empty map.
1893
1894     \sa canConvert(), convert()
1895 */
1896 QVariantHash QVariant::toHash() const
1897 {
1898     return qVariantToHelper<QVariantHash>(d, handlerManager);
1899 }
1900
1901 /*!
1902     \fn QDate QVariant::toDate() const
1903
1904     Returns the variant as a QDate if the variant has type() \l Date,
1905     \l DateTime, or \l String; otherwise returns an invalid date.
1906
1907     If the type() is \l String, an invalid date will be returned if the
1908     string cannot be parsed as a Qt::ISODate format date.
1909
1910     \sa canConvert(), convert()
1911 */
1912 QDate QVariant::toDate() const
1913 {
1914     return qVariantToHelper<QDate>(d, handlerManager);
1915 }
1916
1917 /*!
1918     \fn QTime QVariant::toTime() const
1919
1920     Returns the variant as a QTime if the variant has type() \l Time,
1921     \l DateTime, or \l String; otherwise returns an invalid time.
1922
1923     If the type() is \l String, an invalid time will be returned if
1924     the string cannot be parsed as a Qt::ISODate format time.
1925
1926     \sa canConvert(), convert()
1927 */
1928 QTime QVariant::toTime() const
1929 {
1930     return qVariantToHelper<QTime>(d, handlerManager);
1931 }
1932
1933 /*!
1934     \fn QDateTime QVariant::toDateTime() const
1935
1936     Returns the variant as a QDateTime if the variant has type() \l
1937     DateTime, \l Date, or \l String; otherwise returns an invalid
1938     date/time.
1939
1940     If the type() is \l String, an invalid date/time will be returned
1941     if the string cannot be parsed as a Qt::ISODate format date/time.
1942
1943     \sa canConvert(), convert()
1944 */
1945 QDateTime QVariant::toDateTime() const
1946 {
1947     return qVariantToHelper<QDateTime>(d, handlerManager);
1948 }
1949
1950 /*!
1951     \since 4.7
1952     \fn QEasingCurve QVariant::toEasingCurve() const
1953
1954     Returns the variant as a QEasingCurve if the variant has type() \l
1955     EasingCurve; otherwise returns a default easing curve.
1956
1957     \sa canConvert(), convert()
1958 */
1959 #ifndef QT_BOOTSTRAPPED
1960 QEasingCurve QVariant::toEasingCurve() const
1961 {
1962     return qVariantToHelper<QEasingCurve>(d, handlerManager);
1963 }
1964 #endif
1965
1966 /*!
1967     \fn QByteArray QVariant::toByteArray() const
1968
1969     Returns the variant as a QByteArray if the variant has type() \l
1970     ByteArray or \l String (converted using QString::fromAscii());
1971     otherwise returns an empty byte array.
1972
1973     \sa canConvert(), convert()
1974 */
1975 QByteArray QVariant::toByteArray() const
1976 {
1977     return qVariantToHelper<QByteArray>(d, handlerManager);
1978 }
1979
1980 #ifndef QT_NO_GEOM_VARIANT
1981 /*!
1982     \fn QPoint QVariant::toPoint() const
1983
1984     Returns the variant as a QPoint if the variant has type()
1985     \l Point or \l PointF; otherwise returns a null QPoint.
1986
1987     \sa canConvert(), convert()
1988 */
1989 QPoint QVariant::toPoint() const
1990 {
1991     return qVariantToHelper<QPoint>(d, handlerManager);
1992 }
1993
1994 /*!
1995     \fn QRect QVariant::toRect() const
1996
1997     Returns the variant as a QRect if the variant has type() \l Rect;
1998     otherwise returns an invalid QRect.
1999
2000     \sa canConvert(), convert()
2001 */
2002 QRect QVariant::toRect() const
2003 {
2004     return qVariantToHelper<QRect>(d, handlerManager);
2005 }
2006
2007 /*!
2008     \fn QSize QVariant::toSize() const
2009
2010     Returns the variant as a QSize if the variant has type() \l Size;
2011     otherwise returns an invalid QSize.
2012
2013     \sa canConvert(), convert()
2014 */
2015 QSize QVariant::toSize() const
2016 {
2017     return qVariantToHelper<QSize>(d, handlerManager);
2018 }
2019
2020 /*!
2021     \fn QSizeF QVariant::toSizeF() const
2022
2023     Returns the variant as a QSizeF if the variant has type() \l
2024     SizeF; otherwise returns an invalid QSizeF.
2025
2026     \sa canConvert(), convert()
2027 */
2028 QSizeF QVariant::toSizeF() const
2029 {
2030     return qVariantToHelper<QSizeF>(d, handlerManager);
2031 }
2032
2033 /*!
2034     \fn QRectF QVariant::toRectF() const
2035
2036     Returns the variant as a QRectF if the variant has type() \l Rect
2037     or \l RectF; otherwise returns an invalid QRectF.
2038
2039     \sa canConvert(), convert()
2040 */
2041 QRectF QVariant::toRectF() const
2042 {
2043     return qVariantToHelper<QRectF>(d, handlerManager);
2044 }
2045
2046 /*!
2047     \fn QLineF QVariant::toLineF() const
2048
2049     Returns the variant as a QLineF if the variant has type() \l
2050     LineF; otherwise returns an invalid QLineF.
2051
2052     \sa canConvert(), convert()
2053 */
2054 QLineF QVariant::toLineF() const
2055 {
2056     return qVariantToHelper<QLineF>(d, handlerManager);
2057 }
2058
2059 /*!
2060     \fn QLine QVariant::toLine() const
2061
2062     Returns the variant as a QLine if the variant has type() \l Line;
2063     otherwise returns an invalid QLine.
2064
2065     \sa canConvert(), convert()
2066 */
2067 QLine QVariant::toLine() const
2068 {
2069     return qVariantToHelper<QLine>(d, handlerManager);
2070 }
2071
2072 /*!
2073     \fn QPointF QVariant::toPointF() const
2074
2075     Returns the variant as a QPointF if the variant has type() \l
2076     Point or \l PointF; otherwise returns a null QPointF.
2077
2078     \sa canConvert(), convert()
2079 */
2080 QPointF QVariant::toPointF() const
2081 {
2082     return qVariantToHelper<QPointF>(d, handlerManager);
2083 }
2084
2085 #endif // QT_NO_GEOM_VARIANT
2086
2087 /*!
2088     \fn QUrl QVariant::toUrl() const
2089
2090     Returns the variant as a QUrl if the variant has type()
2091     \l Url; otherwise returns an invalid QUrl.
2092
2093     \sa canConvert(), convert()
2094 */
2095 QUrl QVariant::toUrl() const
2096 {
2097     return qVariantToHelper<QUrl>(d, handlerManager);
2098 }
2099
2100 /*!
2101     \fn QLocale QVariant::toLocale() const
2102
2103     Returns the variant as a QLocale if the variant has type()
2104     \l Locale; otherwise returns an invalid QLocale.
2105
2106     \sa canConvert(), convert()
2107 */
2108 QLocale QVariant::toLocale() const
2109 {
2110     return qVariantToHelper<QLocale>(d, handlerManager);
2111 }
2112
2113 /*!
2114     \fn QRegExp QVariant::toRegExp() const
2115     \since 4.1
2116
2117     Returns the variant as a QRegExp if the variant has type() \l
2118     RegExp; otherwise returns an empty QRegExp.
2119
2120     \sa canConvert(), convert()
2121 */
2122 #ifndef QT_NO_REGEXP
2123 QRegExp QVariant::toRegExp() const
2124 {
2125     return qVariantToHelper<QRegExp>(d, handlerManager);
2126 }
2127 #endif
2128
2129 /*!
2130     \fn QChar QVariant::toChar() const
2131
2132     Returns the variant as a QChar if the variant has type() \l Char,
2133     \l Int, or \l UInt; otherwise returns an invalid QChar.
2134
2135     \sa canConvert(), convert()
2136 */
2137 QChar QVariant::toChar() const
2138 {
2139     return qVariantToHelper<QChar>(d, handlerManager);
2140 }
2141
2142 /*!
2143     Returns the variant as a QBitArray if the variant has type()
2144     \l BitArray; otherwise returns an empty bit array.
2145
2146     \sa canConvert(), convert()
2147 */
2148 QBitArray QVariant::toBitArray() const
2149 {
2150     return qVariantToHelper<QBitArray>(d, handlerManager);
2151 }
2152
2153 template <typename T>
2154 inline T qNumVariantToHelper(const QVariant::Private &d,
2155                              const HandlersManager &handlerManager, bool *ok, const T& val)
2156 {
2157     uint t = qMetaTypeId<T>();
2158     if (ok)
2159         *ok = true;
2160     if (d.type == t)
2161         return val;
2162
2163     T ret = 0;
2164     if (!handlerManager[d.type]->convert(&d, t, &ret, ok) && ok)
2165         *ok = false;
2166     return ret;
2167 }
2168
2169 /*!
2170     Returns the variant as an int if the variant has type() \l Int,
2171     \l Bool, \l ByteArray, \l Char, \l Double, \l LongLong, \l
2172     String, \l UInt, or \l ULongLong; otherwise returns 0.
2173
2174     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2175     converted to an int; otherwise \c{*}\a{ok} is set to false.
2176
2177     \bold{Warning:} If the value is convertible to a \l LongLong but is too
2178     large to be represented in an int, the resulting arithmetic overflow will
2179     not be reflected in \a ok. A simple workaround is to use QString::toInt().
2180     Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
2181
2182     \sa canConvert(), convert()
2183 */
2184 int QVariant::toInt(bool *ok) const
2185 {
2186     return qNumVariantToHelper<int>(d, handlerManager, ok, d.data.i);
2187 }
2188
2189 /*!
2190     Returns the variant as an unsigned int if the variant has type()
2191     \l UInt,  \l Bool, \l ByteArray, \l Char, \l Double, \l Int, \l
2192     LongLong, \l String, or \l ULongLong; otherwise returns 0.
2193
2194     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2195     converted to an unsigned int; otherwise \c{*}\a{ok} is set to false.
2196
2197     \bold{Warning:} If the value is convertible to a \l ULongLong but is too
2198     large to be represented in an unsigned int, the resulting arithmetic overflow will
2199     not be reflected in \a ok. A simple workaround is to use QString::toUInt().
2200     Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
2201
2202     \sa canConvert(), convert()
2203 */
2204 uint QVariant::toUInt(bool *ok) const
2205 {
2206     return qNumVariantToHelper<uint>(d, handlerManager, ok, d.data.u);
2207 }
2208
2209 /*!
2210     Returns the variant as a long long int if the variant has type()
2211     \l LongLong, \l Bool, \l ByteArray, \l Char, \l Double, \l Int,
2212     \l String, \l UInt, or \l ULongLong; otherwise returns 0.
2213
2214     If \a ok is non-null: \c{*}\c{ok} is set to true if the value could be
2215     converted to an int; otherwise \c{*}\c{ok} is set to false.
2216
2217     \sa canConvert(), convert()
2218 */
2219 qlonglong QVariant::toLongLong(bool *ok) const
2220 {
2221     return qNumVariantToHelper<qlonglong>(d, handlerManager, ok, d.data.ll);
2222 }
2223
2224 /*!
2225     Returns the variant as as an unsigned long long int if the
2226     variant has type() \l ULongLong, \l Bool, \l ByteArray, \l Char,
2227     \l Double, \l Int, \l LongLong, \l String, or \l UInt; otherwise
2228     returns 0.
2229
2230     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2231     converted to an int; otherwise \c{*}\a{ok} is set to false.
2232
2233     \sa canConvert(), convert()
2234 */
2235 qulonglong QVariant::toULongLong(bool *ok) const
2236 {
2237     return qNumVariantToHelper<qulonglong>(d, handlerManager, ok, d.data.ull);
2238 }
2239
2240 /*!
2241     Returns the variant as a bool if the variant has type() Bool.
2242
2243     Returns true if the variant has type() \l Bool, \l Char, \l Double,
2244     \l Int, \l LongLong, \l UInt, or \l ULongLong and the value is
2245     non-zero, or if the variant has type \l String or \l ByteArray and
2246     its lower-case content is not empty, "0" or "false"; otherwise
2247     returns false.
2248
2249     \sa canConvert(), convert()
2250 */
2251 bool QVariant::toBool() const
2252 {
2253     if (d.type == Bool)
2254         return d.data.b;
2255
2256     bool res = false;
2257     handlerManager[d.type]->convert(&d, Bool, &res, 0);
2258
2259     return res;
2260 }
2261
2262 /*!
2263     Returns the variant as a double if the variant has type() \l
2264     Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
2265     UInt, or \l ULongLong; otherwise returns 0.0.
2266
2267     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2268     converted to a double; otherwise \c{*}\a{ok} is set to false.
2269
2270     \sa canConvert(), convert()
2271 */
2272 double QVariant::toDouble(bool *ok) const
2273 {
2274     return qNumVariantToHelper<double>(d, handlerManager, ok, d.data.d);
2275 }
2276
2277 /*!
2278     Returns the variant as a float if the variant has type() \l
2279     Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
2280     UInt, or \l ULongLong; otherwise returns 0.0.
2281
2282     \since 4.6
2283
2284     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2285     converted to a double; otherwise \c{*}\a{ok} is set to false.
2286
2287     \sa canConvert(), convert()
2288 */
2289 float QVariant::toFloat(bool *ok) const
2290 {
2291     return qNumVariantToHelper<float>(d, handlerManager, ok, d.data.f);
2292 }
2293
2294 /*!
2295     Returns the variant as a qreal if the variant has type() \l
2296     Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
2297     UInt, or \l ULongLong; otherwise returns 0.0.
2298
2299     \since 4.6
2300
2301     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2302     converted to a double; otherwise \c{*}\a{ok} is set to false.
2303
2304     \sa canConvert(), convert()
2305 */
2306 qreal QVariant::toReal(bool *ok) const
2307 {
2308     return qNumVariantToHelper<qreal>(d, handlerManager, ok, d.data.real);
2309 }
2310
2311 /*!
2312     Returns the variant as a QVariantList if the variant has type()
2313     \l List or \l StringList; otherwise returns an empty list.
2314
2315     \sa canConvert(), convert()
2316 */
2317 QVariantList QVariant::toList() const
2318 {
2319     return qVariantToHelper<QVariantList>(d, handlerManager);
2320 }
2321
2322
2323 static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
2324 {
2325 /*Invalid*/     0,
2326
2327 /*Bool*/          1 << QVariant::Double     | 1 << QVariant::Int        | 1 << QVariant::UInt
2328                 | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong  | 1 << QVariant::ByteArray
2329                 | 1 << QVariant::String     | 1 << QVariant::Char,
2330
2331 /*Int*/           1 << QVariant::UInt       | 1 << QVariant::String     | 1 << QVariant::Double
2332                 | 1 << QVariant::Bool       | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong
2333                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
2334
2335 /*UInt*/          1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::Double
2336                 | 1 << QVariant::Bool       | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong
2337                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
2338
2339 /*LLong*/         1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::Double
2340                 | 1 << QVariant::Bool       | 1 << QVariant::UInt       | 1 << QVariant::ULongLong
2341                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
2342
2343 /*ULlong*/        1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::Double
2344                 | 1 << QVariant::Bool       | 1 << QVariant::UInt       | 1 << QVariant::LongLong
2345                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
2346
2347 /*double*/        1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::ULongLong
2348                 | 1 << QVariant::Bool       | 1 << QVariant::UInt       | 1 << QVariant::LongLong
2349                 | 1 << QVariant::ByteArray,
2350
2351 /*QChar*/         1 << QVariant::Int        | 1 << QVariant::UInt       | 1 << QVariant::LongLong
2352                 | 1 << QVariant::ULongLong,
2353
2354 /*QMap*/          0,
2355
2356 /*QList*/         1 << QVariant::StringList,
2357
2358 /*QString*/       1 << QVariant::StringList | 1 << QVariant::ByteArray  | 1 << QVariant::Int
2359                 | 1 << QVariant::UInt       | 1 << QVariant::Bool       | 1 << QVariant::Double
2360                 | 1 << QVariant::Date       | 1 << QVariant::Time       | 1 << QVariant::DateTime
2361                 | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong  | 1 << QVariant::Char
2362                 | 1 << QVariant::Url        | 1 << QVariant::Uuid,
2363
2364 /*QStringList*/   1 << QVariant::List       | 1 << QVariant::String,
2365
2366 /*QByteArray*/    1 << QVariant::String     | 1 << QVariant::Int        | 1 << QVariant::UInt | 1 << QVariant::Bool
2367                 | 1 << QVariant::Double     | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong,
2368
2369 /*QBitArray*/     0,
2370
2371 /*QDate*/         1 << QVariant::String     | 1 << QVariant::DateTime,
2372
2373 /*QTime*/         1 << QVariant::String     | 1 << QVariant::DateTime,
2374
2375 /*QDateTime*/     1 << QVariant::String     | 1 << QVariant::Date,
2376
2377 /*QUrl*/          1 << QVariant::String,
2378
2379 /*QLocale*/       0,
2380
2381 /*QRect*/         1 << QVariant::RectF,
2382
2383 /*QRectF*/        1 << QVariant::Rect,
2384
2385 /*QSize*/         1 << QVariant::SizeF,
2386
2387 /*QSizeF*/        1 << QVariant::Size,
2388
2389 /*QLine*/         1 << QVariant::LineF,
2390
2391 /*QLineF*/        1 << QVariant::Line,
2392
2393 /*QPoint*/        1 << QVariant::PointF,
2394
2395 /*QPointF*/       1 << QVariant::Point,
2396
2397 /*QRegExp*/       0,
2398
2399 /*QHash*/         0,
2400
2401 /*QEasingCurve*/  0,
2402
2403 /*QUuid*/         1 << QVariant::String
2404 };
2405
2406 /*!
2407     Returns true if the variant's type can be cast to the requested
2408     type, \a targetTypeId. Such casting is done automatically when calling the
2409     toInt(), toBool(), ... methods.
2410
2411     The following casts are done automatically:
2412
2413     \table
2414     \header \o Type \o Automatically Cast To
2415     \row \o \l Bool \o \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
2416     \row \o \l ByteArray \o \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
2417     \row \o \l Char \o \l Bool, \l Int, \l UInt, \l LongLong, \l ULongLong
2418     \row \o \l Color \o \l String
2419     \row \o \l Date \o \l DateTime, \l String
2420     \row \o \l DateTime \o \l Date, \l String, \l Time
2421     \row \o \l Double \o \l Bool, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
2422     \row \o \l Font \o \l String
2423     \row \o \l Int \o \l Bool, \l Char, \l Double, \l LongLong, \l String, \l UInt, \l ULongLong
2424     \row \o \l KeySequence \o \l Int, \l String
2425     \row \o \l List \o \l StringList (if the list's items can be converted to strings)
2426     \row \o \l LongLong \o \l Bool, \l ByteArray, \l Char, \l Double, \l Int, \l String, \l UInt, \l ULongLong
2427     \row \o \l Point \o PointF
2428     \row \o \l Rect \o RectF
2429     \row \o \l String \o \l Bool, \l ByteArray, \l Char, \l Color, \l Date, \l DateTime, \l Double,
2430                          \l Font, \l Int, \l KeySequence, \l LongLong, \l StringList, \l Time, \l UInt,
2431                          \l ULongLong
2432     \row \o \l StringList \o \l List, \l String (if the list contains exactly one item)
2433     \row \o \l Time \o \l String
2434     \row \o \l UInt \o \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l ULongLong
2435     \row \o \l ULongLong \o \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt
2436     \endtable
2437
2438     \sa convert()
2439 */
2440 bool QVariant::canConvert(int targetTypeId) const
2441 {
2442     // TODO Reimplement this function, currently it works but it is a historical mess.
2443     const uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type);
2444     if (uint(targetTypeId) == uint(QMetaType::Float)) targetTypeId = QVariant::Double;
2445
2446     if (currentType == uint(targetTypeId))
2447         return true;
2448
2449     // FIXME It should be LastCoreType intead of Uuid
2450     if (currentType > int(QMetaType::QUuid) || targetTypeId > int(QMetaType::QUuid)) {
2451         switch (uint(targetTypeId)) {
2452         case QVariant::Int:
2453             return currentType == QVariant::KeySequence
2454                    || currentType == QMetaType::ULong
2455                    || currentType == QMetaType::Long
2456                    || currentType == QMetaType::UShort
2457                    || currentType == QMetaType::UChar
2458                    || currentType == QMetaType::Char
2459                    || currentType == QMetaType::Short;
2460         case QVariant::Image:
2461             return currentType == QVariant::Pixmap || currentType == QVariant::Bitmap;
2462         case QVariant::Pixmap:
2463             return currentType == QVariant::Image || currentType == QVariant::Bitmap
2464                               || currentType == QVariant::Brush;
2465         case QVariant::Bitmap:
2466             return currentType == QVariant::Pixmap || currentType == QVariant::Image;
2467         case QVariant::ByteArray:
2468             return currentType == QVariant::Color;
2469         case QVariant::String:
2470             return currentType == QVariant::KeySequence || currentType == QVariant::Font
2471                               || currentType == QVariant::Color;
2472         case QVariant::KeySequence:
2473             return currentType == QVariant::String || currentType == QVariant::Int;
2474         case QVariant::Font:
2475             return currentType == QVariant::String;
2476         case QVariant::Color:
2477             return currentType == QVariant::String || currentType == QVariant::ByteArray
2478                               || currentType == QVariant::Brush;
2479         case QVariant::Brush:
2480             return currentType == QVariant::Color || currentType == QVariant::Pixmap;
2481         case QMetaType::Long:
2482         case QMetaType::Char:
2483         case QMetaType::UChar:
2484         case QMetaType::ULong:
2485         case QMetaType::Short:
2486         case QMetaType::UShort:
2487             return qCanConvertMatrix[QVariant::Int] & (1 << currentType) || currentType == QVariant::Int;
2488         default:
2489             return false;
2490         }
2491     }
2492
2493     if (targetTypeId == String && currentType == StringList)
2494         return v_cast<QStringList>(&d)->count() == 1;
2495     else
2496         return qCanConvertMatrix[targetTypeId] & (1 << currentType);
2497 }
2498
2499 /*!
2500     Casts the variant to the requested type, \a targetTypeId. If the cast cannot be
2501     done, the variant is cleared. Returns true if the current type of
2502     the variant was successfully cast; otherwise returns false.
2503
2504     \warning For historical reasons, converting a null QVariant results
2505     in a null value of the desired type (e.g., an empty string for
2506     QString) and a result of false.
2507
2508     \sa canConvert(), clear()
2509 */
2510
2511 bool QVariant::convert(int targetTypeId)
2512 {
2513     if (d.type == uint(targetTypeId))
2514         return true;
2515
2516     QVariant oldValue = *this;
2517
2518     clear();
2519     if (!oldValue.canConvert(targetTypeId))
2520         return false;
2521
2522     create(targetTypeId, 0);
2523     if (oldValue.isNull())
2524         return false;
2525
2526     bool isOk = true;
2527     if (!handlerManager[d.type]->convert(&oldValue.d, targetTypeId, data(), &isOk))
2528         isOk = false;
2529     d.is_null = !isOk;
2530     return isOk;
2531 }
2532
2533 /*!
2534   \fn convert(const int type, void *ptr) const
2535   \internal
2536   Created for qvariant_cast() usage
2537 */
2538 bool QVariant::convert(const int type, void *ptr) const
2539 {
2540     Q_ASSERT(type < int(QMetaType::User));
2541     return handlerManager[type]->convert(&d, type, ptr, 0);
2542 }
2543
2544
2545 /*!
2546     \fn bool operator==(const QVariant &v1, const QVariant &v2)
2547
2548     \relates QVariant
2549
2550     Returns true if \a v1 and \a v2 are equal; otherwise returns false.
2551
2552     \warning This function doesn't support custom types registered
2553     with qRegisterMetaType().
2554 */
2555 /*!
2556     \fn bool operator!=(const QVariant &v1, const QVariant &v2)
2557
2558     \relates QVariant
2559
2560     Returns false if \a v1 and \a v2 are equal; otherwise returns true.
2561
2562     \warning This function doesn't support custom types registered
2563     with qRegisterMetaType().
2564 */
2565
2566 /*! \fn bool QVariant::operator==(const QVariant &v) const
2567
2568     Compares this QVariant with \a v and returns true if they are
2569     equal; otherwise returns false.
2570
2571     In the case of custom types, their equalness operators are not called.
2572     Instead the values' addresses are compared.
2573 */
2574
2575 /*!
2576     \fn bool QVariant::operator!=(const QVariant &v) const
2577
2578     Compares this QVariant with \a v and returns true if they are not
2579     equal; otherwise returns false.
2580
2581     \warning This function doesn't support custom types registered
2582     with qRegisterMetaType().
2583 */
2584
2585 static bool qIsNumericType(uint tp)
2586 {
2587     return (tp >= QVariant::Bool && tp <= QVariant::Double)
2588            || (tp >= QMetaType::Long && tp <= QMetaType::Float);
2589 }
2590
2591 static bool qIsFloatingPoint(uint tp)
2592 {
2593     return tp == QVariant::Double || tp == QMetaType::Float;
2594 }
2595
2596 /*! \internal
2597  */
2598 bool QVariant::cmp(const QVariant &v) const
2599 {
2600     QVariant v2 = v;
2601     if (d.type != v2.d.type) {
2602         if (qIsNumericType(d.type) && qIsNumericType(v.d.type)) {
2603             if (qIsFloatingPoint(d.type) || qIsFloatingPoint(v.d.type))
2604                 return qFuzzyCompare(toReal(), v.toReal());
2605             else
2606                 return toLongLong() == v.toLongLong();
2607         }
2608         if (!v2.canConvert(d.type) || !v2.convert(d.type))
2609             return false;
2610     }
2611     return handlerManager[d.type]->compare(&d, &v2.d);
2612 }
2613
2614 /*! \internal
2615  */
2616
2617 const void *QVariant::constData() const
2618 {
2619     return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr);
2620 }
2621
2622 /*!
2623     \fn const void* QVariant::data() const
2624
2625     \internal
2626 */
2627
2628 /*! \internal */
2629 void* QVariant::data()
2630 {
2631     detach();
2632     return const_cast<void *>(constData());
2633 }
2634
2635
2636 /*!
2637   Returns true if this is a NULL variant, false otherwise.
2638 */
2639 bool QVariant::isNull() const
2640 {
2641     return handlerManager[d.type]->isNull(&d);
2642 }
2643
2644 #ifndef QT_NO_DEBUG_STREAM
2645 QDebug operator<<(QDebug dbg, const QVariant &v)
2646 {
2647     dbg.nospace() << "QVariant(" << QMetaType::typeName(v.userType()) << ", ";
2648     handlerManager[v.d.type]->debugStream(dbg, v);
2649     dbg.nospace() << ')';
2650     return dbg.space();
2651 }
2652
2653 QDebug operator<<(QDebug dbg, const QVariant::Type p)
2654 {
2655     dbg.nospace() << "QVariant::" << QMetaType::typeName(p);
2656     return dbg.space();
2657 }
2658 #endif
2659
2660
2661 /*! \fn void QVariant::setValue(const T &value)
2662
2663     Stores a copy of \a value. If \c{T} is a type that QVariant
2664     doesn't support, QMetaType is used to store the value. A compile
2665     error will occur if QMetaType doesn't handle the type.
2666
2667     Example:
2668
2669     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 4
2670
2671     \sa value(), fromValue(), canConvert()
2672  */
2673
2674 /*! \fn T QVariant::value() const
2675
2676     Returns the stored value converted to the template type \c{T}.
2677     Call canConvert() to find out whether a type can be converted.
2678     If the value cannot be converted, \l{default-constructed value}
2679     will be returned.
2680
2681     If the type \c{T} is supported by QVariant, this function behaves
2682     exactly as toString(), toInt() etc.
2683
2684     Example:
2685
2686     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 5
2687
2688     \sa setValue(), fromValue(), canConvert()
2689 */
2690
2691 /*! \fn bool QVariant::canConvert() const
2692
2693     Returns true if the variant can be converted to the template type \c{T},
2694     otherwise false.
2695
2696     Example:
2697
2698     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 6
2699
2700     \sa convert()
2701 */
2702
2703 /*! \fn static QVariant QVariant::fromValue(const T &value)
2704
2705     Returns a QVariant containing a copy of \a value. Behaves
2706     exactly like setValue() otherwise.
2707
2708     Example:
2709
2710     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 7
2711
2712     \note If you are working with custom types, you should use
2713     the Q_DECLARE_METATYPE() macro to register your custom type.
2714
2715     \sa setValue(), value()
2716 */
2717
2718 /*!
2719     \fn QVariant qVariantFromValue(const T &value)
2720     \relates QVariant
2721     \obsolete
2722
2723     Returns a variant containing a copy of the given \a value
2724     with template type \c{T}.
2725
2726     This function is equivalent to QVariant::fromValue(\a value).
2727
2728     \note This function was provided as a workaround for MSVC 6
2729     which did not support member template functions. It is advised
2730     to use the other form in new code.
2731
2732     For example, a QObject pointer can be stored in a variant with the
2733     following code:
2734
2735     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 8
2736
2737     \sa QVariant::fromValue()
2738 */
2739
2740 /*! \fn void qVariantSetValue(QVariant &variant, const T &value)
2741     \relates QVariant
2742     \obsolete
2743
2744     Sets the contents of the given \a variant to a copy of the
2745     \a value with the specified template type \c{T}.
2746
2747     This function is equivalent to QVariant::setValue(\a value).
2748
2749     \note This function was provided as a workaround for MSVC 6
2750     which did not support member template functions. It is advised
2751     to use the other form in new code.
2752
2753     \sa QVariant::setValue()
2754 */
2755
2756 /*!
2757     \fn T qvariant_cast(const QVariant &value)
2758     \relates QVariant
2759
2760     Returns the given \a value converted to the template type \c{T}.
2761
2762     This function is equivalent to QVariant::value().
2763
2764     \sa QVariant::value()
2765 */
2766
2767 /*! \fn T qVariantValue(const QVariant &value)
2768     \relates QVariant
2769     \obsolete
2770
2771     Returns the given \a value converted to the template type \c{T}.
2772
2773     This function is equivalent to
2774     \l{QVariant::value()}{QVariant::value}<T>(\a value).
2775
2776     \note This function was provided as a workaround for MSVC 6
2777     which did not support member template functions. It is advised
2778     to use the other form in new code.
2779
2780     \sa QVariant::value(), qvariant_cast()
2781 */
2782
2783 /*! \fn bool qVariantCanConvert(const QVariant &value)
2784     \relates QVariant
2785     \obsolete
2786
2787     Returns true if the given \a value can be converted to the
2788     template type specified; otherwise returns false.
2789
2790     This function is equivalent to QVariant::canConvert(\a value).
2791
2792     \note This function was provided as a workaround for MSVC 6
2793     which did not support member template functions. It is advised
2794     to use the other form in new code.
2795
2796     \sa QVariant::canConvert()
2797 */
2798
2799 /*!
2800     \typedef QVariantList
2801     \relates QVariant
2802
2803     Synonym for QList<QVariant>.
2804 */
2805
2806 /*!
2807     \typedef QVariantMap
2808     \relates QVariant
2809
2810     Synonym for QMap<QString, QVariant>.
2811 */
2812
2813 /*!
2814     \typedef QVariantHash
2815     \relates QVariant
2816     \since 4.5
2817
2818     Synonym for QHash<QString, QVariant>.
2819 */
2820
2821 /*!
2822     \typedef QVariant::DataPtr
2823     \internal
2824 */
2825
2826 /*!
2827     \fn DataPtr &QVariant::data_ptr()
2828     \internal
2829 */
2830
2831 QT_END_NAMESPACE