Give a more verbose warning during QVariant serialization.
[profile/ivi/qtbase.git] / src / corelib / kernel / qvariant.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
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 TypeDefiniton {
102     static const bool IsAvailable = true;
103 };
104
105 // Ignore these types, as incomplete
106 #ifdef QT_BOOTSTRAPPED
107 template<> struct TypeDefiniton<QEasingCurve> { static const bool IsAvailable = false; };
108 template<> struct TypeDefiniton<QModelIndex> { static const bool IsAvailable = false; };
109 #endif
110 #ifdef QT_NO_GEOM_VARIANT
111 template<> struct TypeDefiniton<QRect> { static const bool IsAvailable = false; };
112 template<> struct TypeDefiniton<QRectF> { static const bool IsAvailable = false; };
113 template<> struct TypeDefiniton<QSize> { static const bool IsAvailable = false; };
114 template<> struct TypeDefiniton<QSizeF> { static const bool IsAvailable = false; };
115 template<> struct TypeDefiniton<QLine> { static const bool IsAvailable = false; };
116 template<> struct TypeDefiniton<QLineF> { static const bool IsAvailable = false; };
117 template<> struct TypeDefiniton<QPoint> { static const bool IsAvailable = false; };
118 template<> struct TypeDefiniton<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 && TypeDefiniton<T>::IsAvailable;
125     };
126 };
127 } // annonymous used to hide TypeDefiniton
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, QVariant::Type 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) && !defined(Q_BROKEN_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) && !defined(Q_BROKEN_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 *, QVariant::Type , void *, bool *) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); return false; }
767 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_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) && !defined(Q_BROKEN_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 uint size = QMetaType::sizeOf(d->type);
791     if (!size) {
792         d->type = QVariant::Invalid;
793         return;
794     }
795
796     // this logic should match with QVariantIntegrator::CanUseInternalSpace
797     if (size <= sizeof(QVariant::Private::Data)
798             && (QMetaType::typeFlags(d->type) & QMetaType::MovableType)) {
799         QMetaType::construct(d->type, &d->data.ptr, copy);
800         d->is_shared = false;
801     } else {
802         void *ptr = QMetaType::create(d->type, copy);
803         d->is_shared = true;
804         d->data.shared = new QVariant::PrivateShared(ptr);
805     }
806 }
807
808 static void customClear(QVariant::Private *d)
809 {
810     if (!d->is_shared) {
811         QMetaType::destruct(d->type, &d->data.ptr);
812     } else {
813         QMetaType::destroy(d->type, d->data.shared->ptr);
814         delete d->data.shared;
815     }
816 }
817
818 static bool customIsNull(const QVariant::Private *d)
819 {
820     return d->is_null;
821 }
822
823 static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
824 {
825     const char *const typeName = QMetaType::typeName(a->type);
826     if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(a->type)))
827         qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
828
829     const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data.ptr);
830     const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data.ptr);
831
832     uint typeNameLen = qstrlen(typeName);
833     if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*')
834         return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
835
836     if (a->is_null && b->is_null)
837         return true;
838
839     return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
840 }
841
842 static bool customConvert(const QVariant::Private *, QVariant::Type, void *, bool *ok)
843 {
844     if (ok)
845         *ok = false;
846     return false;
847 }
848
849 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
850 static void customStreamDebug(QDebug, const QVariant &) {}
851 #endif
852
853 const QVariant::Handler qt_custom_variant_handler = {
854     customConstruct,
855     customClear,
856     customIsNull,
857 #ifndef QT_NO_DATASTREAM
858     0,
859     0,
860 #endif
861     customCompare,
862     customConvert,
863     0,
864 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
865     customStreamDebug
866 #else
867     0
868 #endif
869 };
870
871 } // annonymous used to hide QVariant handlers
872
873 static HandlersManager handlerManager;
874 Q_STATIC_ASSERT_X(!QModulesPrivate::Core, "Initialization assumes that ModulesNames::Core is 0");
875 const QVariant::Handler *HandlersManager::Handlers[QModulesPrivate::ModulesCount]
876                                         = { &qt_kernel_variant_handler, &qt_dummy_variant_handler,
877                                             &qt_dummy_variant_handler, &qt_custom_variant_handler };
878
879 Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler()
880 {
881     return &qt_kernel_variant_handler;
882 }
883
884 inline void HandlersManager::unregisterHandler(const QModulesPrivate::Names name)
885 {
886     Handlers[name] = &qt_dummy_variant_handler;
887 }
888
889 Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names */name, const QVariant::Handler *handler)
890 {
891     handlerManager.registerHandler(static_cast<QModulesPrivate::Names>(name), handler);
892 }
893
894 Q_CORE_EXPORT void QVariantPrivate::unregisterHandler(const int /* Modules::Names */ name)
895 {
896     handlerManager.unregisterHandler(static_cast<QModulesPrivate::Names>(name));
897 }
898
899 /*!
900     \class QVariant
901     \brief The QVariant class acts like a union for the most common Qt data types.
902
903     \ingroup objectmodel
904     \ingroup shared
905
906
907     Because C++ forbids unions from including types that have
908     non-default constructors or destructors, most interesting Qt
909     classes cannot be used in unions. Without QVariant, this would be
910     a problem for QObject::property() and for database work, etc.
911
912     A QVariant object holds a single value of a single type() at a
913     time. (Some type()s are multi-valued, for example a string list.)
914     You can find out what type, T, the variant holds, convert it to a
915     different type using convert(), get its value using one of the
916     toT() functions (e.g., toSize()) and check whether the type can
917     be converted to a particular type using canConvert().
918
919     The methods named toT() (e.g., toInt(), toString()) are const. If
920     you ask for the stored type, they return a copy of the stored
921     object. If you ask for a type that can be generated from the
922     stored type, toT() copies and converts and leaves the object
923     itself unchanged. If you ask for a type that cannot be generated
924     from the stored type, the result depends on the type; see the
925     function documentation for details.
926
927     Here is some example code to demonstrate the use of QVariant:
928
929     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 0
930
931     You can even store QList<QVariant> and QMap<QString, QVariant>
932     values in a variant, so you can easily construct arbitrarily
933     complex data structures of arbitrary types. This is very powerful
934     and versatile, but may prove less memory and speed efficient than
935     storing specific types in standard data structures.
936
937     QVariant also supports the notion of null values, where you can
938     have a defined type with no value set. However, note that QVariant
939     types can only be cast when they have had a value set.
940
941     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 1
942
943     QVariant can be extended to support other types than those
944     mentioned in the \l Type enum. See the \l QMetaType documentation
945     for details.
946
947     \section1 A Note on GUI Types
948
949     Because QVariant is part of the QtCore library, it cannot provide
950     conversion functions to data types defined in QtGui, such as
951     QColor, QImage, and QPixmap. In other words, there is no \c
952     toColor() function. Instead, you can use the QVariant::value() or
953     the qvariant_cast() template function. For example:
954
955     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 2
956
957     The inverse conversion (e.g., from QColor to QVariant) is
958     automatic for all data types supported by QVariant, including
959     GUI-related types:
960
961     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 3
962
963     \section1 Using canConvert() and convert() Consecutively
964
965     When using canConvert() and convert() consecutively, it is possible for
966     canConvert() to return true, but convert() to return false. This
967     is typically because canConvert() only reports the general ability of
968     QVariant to convert between types given suitable data; it is still
969     possible to supply data which cannot actually be converted.
970
971     For example, canConvert() would return true when called on a variant
972     containing a string because, in principle, QVariant is able to convert
973     strings of numbers to integers.
974     However, if the string contains non-numeric characters, it cannot be
975     converted to an integer, and any attempt to convert it will fail.
976     Hence, it is important to have both functions return true for a
977     successful conversion.
978
979     \sa QMetaType
980 */
981
982 /*!
983     \obsolete Use QMetaType::Type instead
984     \enum QVariant::Type
985
986     This enum type defines the types of variable that a QVariant can
987     contain.
988
989     \value Invalid  no type
990     \value BitArray  a QBitArray
991     \value Bitmap  a QBitmap
992     \value Bool  a bool
993     \value Brush  a QBrush
994     \value ByteArray  a QByteArray
995     \value Char  a QChar
996     \value Color  a QColor
997     \value Cursor  a QCursor
998     \value Date  a QDate
999     \value DateTime  a QDateTime
1000     \value Double  a double
1001     \value EasingCurve a QEasingCurve
1002     \value Uuid a QUuid
1003     \value ModelIndex a QModelIndex
1004     \value Font  a QFont
1005     \value Hash a QVariantHash
1006     \value Icon  a QIcon
1007     \value Image  a QImage
1008     \value Int  an int
1009     \value KeySequence  a QKeySequence
1010     \value Line  a QLine
1011     \value LineF  a QLineF
1012     \value List  a QVariantList
1013     \value Locale  a QLocale
1014     \value LongLong a \l qlonglong
1015     \value Map  a QVariantMap
1016     \value Matrix  a QMatrix
1017     \value Transform  a QTransform
1018     \value Matrix4x4  a QMatrix4x4
1019     \value Palette  a QPalette
1020     \value Pen  a QPen
1021     \value Pixmap  a QPixmap
1022     \value Point  a QPoint
1023     \value PointF  a QPointF
1024     \value Polygon a QPolygon
1025     \value PolygonF a QPolygonF
1026     \value Quaternion  a QQuaternion
1027     \value Rect  a QRect
1028     \value RectF  a QRectF
1029     \value RegExp  a QRegExp
1030     \value Region  a QRegion
1031     \value Size  a QSize
1032     \value SizeF  a QSizeF
1033     \value SizePolicy  a QSizePolicy
1034     \value String  a QString
1035     \value StringList  a QStringList
1036     \value TextFormat  a QTextFormat
1037     \value TextLength  a QTextLength
1038     \value Time  a QTime
1039     \value UInt  a \l uint
1040     \value ULongLong a \l qulonglong
1041     \value Url  a QUrl
1042     \value Vector2D  a QVector2D
1043     \value Vector3D  a QVector3D
1044     \value Vector4D  a QVector4D
1045
1046     \value UserType Base value for user-defined types.
1047
1048     \omitvalue CString
1049     \omitvalue ColorGroup
1050     \omitvalue IconSet
1051     \omitvalue LastGuiType
1052     \omitvalue LastCoreType
1053     \omitvalue LastType
1054 */
1055
1056 /*!
1057     \fn QVariant::QVariant()
1058
1059     Constructs an invalid variant.
1060 */
1061
1062
1063 /*!
1064     \fn QVariant::QVariant(int typeOrUserType, const void *copy)
1065
1066     Constructs variant of type \a typeOrUserType, and initializes with
1067     \a copy if \a copy is not 0.
1068
1069     Note that you have to pass the address of the variable you want stored.
1070
1071     Usually, you never have to use this constructor, use QVariant::fromValue()
1072     instead to construct variants from the pointer types represented by
1073     \c QMetaType::VoidStar, \c QMetaType::QObjectStar and
1074     \c QMetaType::QWidgetStar.
1075
1076     \sa QVariant::fromValue(), Type
1077 */
1078
1079 /*!
1080     \fn QVariant::QVariant(Type type)
1081
1082     Constructs a null variant of type \a type.
1083 */
1084
1085
1086
1087 /*!
1088     \fn QVariant::create(int type, const void *copy)
1089
1090     \internal
1091
1092     Constructs a variant private of type \a type, and initializes with \a copy if
1093     \a copy is not 0.
1094 */
1095
1096 void QVariant::create(int type, const void *copy)
1097 {
1098     d.type = type;
1099     handlerManager[type]->construct(&d, copy);
1100 }
1101
1102 /*!
1103     \fn QVariant::~QVariant()
1104
1105     Destroys the QVariant and the contained object.
1106
1107     Note that subclasses that reimplement clear() should reimplement
1108     the destructor to call clear(). This destructor calls clear(), but
1109     because it is the destructor, QVariant::clear() is called rather
1110     than a subclass's clear().
1111 */
1112
1113 QVariant::~QVariant()
1114 {
1115     if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
1116         handlerManager[d.type]->clear(&d);
1117 }
1118
1119 /*!
1120   \fn QVariant::QVariant(const QVariant &p)
1121
1122     Constructs a copy of the variant, \a p, passed as the argument to
1123     this constructor.
1124 */
1125
1126 QVariant::QVariant(const QVariant &p)
1127     : d(p.d)
1128 {
1129     if (d.is_shared) {
1130         d.data.shared->ref.ref();
1131     } else if (p.d.type > Char) {
1132         handlerManager[d.type]->construct(&d, p.constData());
1133         d.is_null = p.d.is_null;
1134     }
1135 }
1136
1137 #ifndef QT_NO_DATASTREAM
1138 /*!
1139     Reads the variant from the data stream, \a s.
1140 */
1141 QVariant::QVariant(QDataStream &s)
1142 {
1143     d.is_null = true;
1144     s >> *this;
1145 }
1146 #endif //QT_NO_DATASTREAM
1147
1148 /*!
1149   \fn QVariant::QVariant(const QString &val)
1150
1151     Constructs a new variant with a string value, \a val.
1152 */
1153
1154 /*!
1155   \fn QVariant::QVariant(const QLatin1String &val)
1156
1157     Constructs a new variant with a string value, \a val.
1158 */
1159
1160 /*!
1161   \fn QVariant::QVariant(const char *val)
1162
1163     Constructs a new variant with a string value of \a val.
1164     The variant creates a deep copy of \a val, using the encoding
1165     set by QTextCodec::setCodecForCStrings().
1166
1167     Note that \a val is converted to a QString for storing in the
1168     variant and QVariant::type() will return QMetaType::QString for
1169     the variant.
1170
1171     You can disable this operator by defining \c
1172     QT_NO_CAST_FROM_ASCII when you compile your applications.
1173
1174     \sa QTextCodec::setCodecForCStrings()
1175 */
1176
1177 #ifndef QT_NO_CAST_FROM_ASCII
1178 QVariant::QVariant(const char *val)
1179 {
1180     QString s = QString::fromAscii(val);
1181     create(String, &s);
1182 }
1183 #endif
1184
1185 /*!
1186   \fn QVariant::QVariant(const QStringList &val)
1187
1188     Constructs a new variant with a string list value, \a val.
1189 */
1190
1191 /*!
1192   \fn QVariant::QVariant(const QMap<QString, QVariant> &val)
1193
1194     Constructs a new variant with a map of QVariants, \a val.
1195 */
1196
1197 /*!
1198   \fn QVariant::QVariant(const QHash<QString, QVariant> &val)
1199
1200     Constructs a new variant with a hash of QVariants, \a val.
1201 */
1202
1203 /*!
1204   \fn QVariant::QVariant(const QDate &val)
1205
1206     Constructs a new variant with a date value, \a val.
1207 */
1208
1209 /*!
1210   \fn QVariant::QVariant(const QTime &val)
1211
1212     Constructs a new variant with a time value, \a val.
1213 */
1214
1215 /*!
1216   \fn QVariant::QVariant(const QDateTime &val)
1217
1218     Constructs a new variant with a date/time value, \a val.
1219 */
1220
1221 /*!
1222     \since 4.7
1223   \fn QVariant::QVariant(const QEasingCurve &val)
1224
1225     Constructs a new variant with an easing curve value, \a val.
1226 */
1227
1228 /*!
1229   \fn QVariant::QVariant(const QByteArray &val)
1230
1231     Constructs a new variant with a bytearray value, \a val.
1232 */
1233
1234 /*!
1235   \fn QVariant::QVariant(const QBitArray &val)
1236
1237     Constructs a new variant with a bitarray value, \a val.
1238 */
1239
1240 /*!
1241   \fn QVariant::QVariant(const QPoint &val)
1242
1243   Constructs a new variant with a point value of \a val.
1244  */
1245
1246 /*!
1247   \fn QVariant::QVariant(const QPointF &val)
1248
1249   Constructs a new variant with a point value of \a val.
1250  */
1251
1252 /*!
1253   \fn QVariant::QVariant(const QRectF &val)
1254
1255   Constructs a new variant with a rect value of \a val.
1256  */
1257
1258 /*!
1259   \fn QVariant::QVariant(const QLineF &val)
1260
1261   Constructs a new variant with a line value of \a val.
1262  */
1263
1264 /*!
1265   \fn QVariant::QVariant(const QLine &val)
1266
1267   Constructs a new variant with a line value of \a val.
1268  */
1269
1270 /*!
1271   \fn QVariant::QVariant(const QRect &val)
1272
1273   Constructs a new variant with a rect value of \a val.
1274  */
1275
1276 /*!
1277   \fn QVariant::QVariant(const QSize &val)
1278
1279   Constructs a new variant with a size value of \a val.
1280  */
1281
1282 /*!
1283   \fn QVariant::QVariant(const QSizeF &val)
1284
1285   Constructs a new variant with a size value of \a val.
1286  */
1287
1288 /*!
1289   \fn QVariant::QVariant(const QUrl &val)
1290
1291   Constructs a new variant with a url value of \a val.
1292  */
1293
1294 /*!
1295   \fn QVariant::QVariant(int val)
1296
1297     Constructs a new variant with an integer value, \a val.
1298 */
1299
1300 /*!
1301   \fn QVariant::QVariant(uint val)
1302
1303     Constructs a new variant with an unsigned integer value, \a val.
1304 */
1305
1306 /*!
1307   \fn QVariant::QVariant(qlonglong val)
1308
1309     Constructs a new variant with a long long integer value, \a val.
1310 */
1311
1312 /*!
1313   \fn QVariant::QVariant(qulonglong val)
1314
1315     Constructs a new variant with an unsigned long long integer value, \a val.
1316 */
1317
1318
1319 /*!
1320   \fn QVariant::QVariant(bool val)
1321
1322     Constructs a new variant with a boolean value, \a val.
1323 */
1324
1325 /*!
1326   \fn QVariant::QVariant(double val)
1327
1328     Constructs a new variant with a floating point value, \a val.
1329 */
1330
1331 /*!
1332   \fn QVariant::QVariant(float val)
1333
1334     Constructs a new variant with a floating point value, \a val.
1335     \since 4.6
1336 */
1337
1338 /*!
1339     \fn QVariant::QVariant(const QList<QVariant> &val)
1340
1341     Constructs a new variant with a list value, \a val.
1342 */
1343
1344 /*!
1345   \fn QVariant::QVariant(const QChar &c)
1346
1347   Constructs a new variant with a char value, \a c.
1348 */
1349
1350 /*!
1351   \fn QVariant::QVariant(const QLocale &l)
1352
1353   Constructs a new variant with a locale value, \a l.
1354 */
1355
1356 /*!
1357   \fn QVariant::QVariant(const QRegExp &regExp)
1358
1359   Constructs a new variant with the regexp value \a regExp.
1360 */
1361
1362 /*! \since 4.2
1363   \fn QVariant::QVariant(Qt::GlobalColor color)
1364
1365   Constructs a new variant of type QVariant::Color and initializes
1366   it with \a color.
1367
1368   This is a convenience constructor that allows \c{QVariant(Qt::blue);}
1369   to create a valid QVariant storing a QColor.
1370
1371   Note: This constructor will assert if the application does not link
1372   to the Qt GUI library.
1373  */
1374
1375 QVariant::QVariant(Type type)
1376 { create(type, 0); }
1377 QVariant::QVariant(int typeOrUserType, const void *copy)
1378 { create(typeOrUserType, copy); d.is_null = false; }
1379
1380 /*! \internal
1381     flags is true if it is a pointer type
1382  */
1383 QVariant::QVariant(int typeOrUserType, const void *copy, uint flags)
1384 {
1385     if (flags) { //type is a pointer type
1386         d.type = typeOrUserType;
1387         d.data.ptr = *reinterpret_cast<void *const*>(copy);
1388     } else {
1389         create(typeOrUserType, copy);
1390     }
1391     d.is_null = false;
1392 }
1393
1394 QVariant::QVariant(int val)
1395 { d.is_null = false; d.type = Int; d.data.i = val; }
1396 QVariant::QVariant(uint val)
1397 { d.is_null = false; d.type = UInt; d.data.u = val; }
1398 QVariant::QVariant(qlonglong val)
1399 { d.is_null = false; d.type = LongLong; d.data.ll = val; }
1400 QVariant::QVariant(qulonglong val)
1401 { d.is_null = false; d.type = ULongLong; d.data.ull = val; }
1402 QVariant::QVariant(bool val)
1403 { d.is_null = false; d.type = Bool; d.data.b = val; }
1404 QVariant::QVariant(double val)
1405 { d.is_null = false; d.type = Double; d.data.d = val; }
1406
1407 QVariant::QVariant(const QByteArray &val)
1408 { d.is_null = false; d.type = ByteArray; v_construct<QByteArray>(&d, val); }
1409 QVariant::QVariant(const QBitArray &val)
1410 { d.is_null = false; d.type = BitArray; v_construct<QBitArray>(&d, val);  }
1411 QVariant::QVariant(const QString &val)
1412 { d.is_null = false; d.type = String; v_construct<QString>(&d, val);  }
1413 QVariant::QVariant(const QChar &val)
1414 { d.is_null = false; d.type = Char; v_construct<QChar>(&d, val);  }
1415 QVariant::QVariant(const QLatin1String &val)
1416 { QString str(val); d.is_null = false; d.type = String; v_construct<QString>(&d, str); }
1417 QVariant::QVariant(const QStringList &val)
1418 { d.is_null = false; d.type = StringList; v_construct<QStringList>(&d, val); }
1419
1420 QVariant::QVariant(const QDate &val)
1421 { d.is_null = false; d.type = Date; v_construct<QDate>(&d, val); }
1422 QVariant::QVariant(const QTime &val)
1423 { d.is_null = false; d.type = Time; v_construct<QTime>(&d, val); }
1424 QVariant::QVariant(const QDateTime &val)
1425 { d.is_null = false; d.type = DateTime; v_construct<QDateTime>(&d, val); }
1426 #ifndef QT_BOOTSTRAPPED
1427 QVariant::QVariant(const QEasingCurve &val)
1428 { d.is_null = false; d.type = EasingCurve; v_construct<QEasingCurve>(&d, val); }
1429 #endif
1430 QVariant::QVariant(const QList<QVariant> &list)
1431 { d.is_null = false; d.type = List; v_construct<QVariantList>(&d, list); }
1432 QVariant::QVariant(const QMap<QString, QVariant> &map)
1433 { d.is_null = false; d.type = Map; v_construct<QVariantMap>(&d, map); }
1434 QVariant::QVariant(const QHash<QString, QVariant> &hash)
1435 { d.is_null = false; d.type = Hash; v_construct<QVariantHash>(&d, hash); }
1436 #ifndef QT_NO_GEOM_VARIANT
1437 QVariant::QVariant(const QPoint &pt) { d.is_null = false; d.type = Point; v_construct<QPoint>(&d, pt); }
1438 QVariant::QVariant(const QPointF &pt) { d.is_null = false; d.type = PointF; v_construct<QPointF>(&d, pt); }
1439 QVariant::QVariant(const QRectF &r) { d.is_null = false; d.type = RectF; v_construct<QRectF>(&d, r); }
1440 QVariant::QVariant(const QLineF &l) { d.is_null = false; d.type = LineF; v_construct<QLineF>(&d, l); }
1441 QVariant::QVariant(const QLine &l) { d.is_null = false; d.type = Line; v_construct<QLine>(&d, l); }
1442 QVariant::QVariant(const QRect &r) { d.is_null = false; d.type = Rect; v_construct<QRect>(&d, r); }
1443 QVariant::QVariant(const QSize &s) { d.is_null = false; d.type = Size; v_construct<QSize>(&d, s); }
1444 QVariant::QVariant(const QSizeF &s) { d.is_null = false; d.type = SizeF; v_construct<QSizeF>(&d, s); }
1445 #endif
1446 QVariant::QVariant(const QUrl &u) { d.is_null = false; d.type = Url; v_construct<QUrl>(&d, u); }
1447 QVariant::QVariant(const QLocale &l) { d.is_null = false; d.type = Locale; v_construct<QLocale>(&d, l); }
1448 #ifndef QT_NO_REGEXP
1449 QVariant::QVariant(const QRegExp &regExp) { d.is_null = false; d.type = RegExp; v_construct<QRegExp>(&d, regExp); }
1450 #endif
1451 QVariant::QVariant(Qt::GlobalColor color) { create(62, &color); }
1452
1453 /*!
1454     Returns the storage type of the value stored in the variant.
1455     Although this function is declared as returning QVariant::Type,
1456     the return value should be interpreted as QMetaType::Type. In
1457     particular, QVariant::UserType is returned here only if the value
1458     is equal or greater than QMetaType::User.
1459
1460     Note that return values in the ranges QVariant::Char through
1461     QVariant::RegExp and QVariant::Font through QVariant::Transform
1462     correspond to the values in the ranges QMetaType::QChar through
1463     QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion.
1464
1465     Pay particular attention when working with char and QChar
1466     variants.  Note that there is no QVariant constructor specifically
1467     for type char, but there is one for QChar. For a variant of type
1468     QChar, this function returns QVariant::Char, which is the same as
1469     QMetaType::QChar, but for a variant of type \c char, this function
1470     returns QMetaType::Char, which is \e not the same as
1471     QVariant::Char.
1472
1473     Also note that the types \c void*, \c long, \c short, \c unsigned
1474     \c long, \c unsigned \c short, \c unsigned \c char, \c float, \c
1475     QObject*, and \c QWidget* are represented in QMetaType::Type but
1476     not in QVariant::Type, and they can be returned by this function.
1477     However, they are considered to be user defined types when tested
1478     against QVariant::Type.
1479
1480     To test whether an instance of QVariant contains a data type that
1481     is compatible with the data type you are interested in, use
1482     canConvert().
1483 */
1484
1485 QVariant::Type QVariant::type() const
1486 {
1487     return d.type >= QMetaType::User ? UserType : static_cast<Type>(d.type);
1488 }
1489
1490 /*!
1491     Returns the storage type of the value stored in the variant. For
1492     non-user types, this is the same as type().
1493
1494     \sa type()
1495 */
1496
1497 int QVariant::userType() const
1498 {
1499     return d.type;
1500 }
1501
1502 /*!
1503     Assigns the value of the variant \a variant to this variant.
1504 */
1505 QVariant& QVariant::operator=(const QVariant &variant)
1506 {
1507     if (this == &variant)
1508         return *this;
1509
1510     clear();
1511     if (variant.d.is_shared) {
1512         variant.d.data.shared->ref.ref();
1513         d = variant.d;
1514     } else if (variant.d.type > Char) {
1515         d.type = variant.d.type;
1516         handlerManager[d.type]->construct(&d, variant.constData());
1517         d.is_null = variant.d.is_null;
1518     } else {
1519         d = variant.d;
1520     }
1521
1522     return *this;
1523 }
1524
1525 /*!
1526     \fn void QVariant::swap(QVariant &other)
1527     \since 4.8
1528
1529     Swaps variant \a other with this variant. This operation is very
1530     fast and never fails.
1531 */
1532
1533 /*!
1534     \fn void QVariant::detach()
1535
1536     \internal
1537 */
1538
1539 void QVariant::detach()
1540 {
1541     if (!d.is_shared || d.data.shared->ref.load() == 1)
1542         return;
1543
1544     Private dd;
1545     dd.type = d.type;
1546     handlerManager[d.type]->construct(&dd, constData());
1547     if (!d.data.shared->ref.deref())
1548         handlerManager[d.type]->clear(&d);
1549     d.data.shared = dd.data.shared;
1550 }
1551
1552 /*!
1553     \fn bool QVariant::isDetached() const
1554
1555     \internal
1556 */
1557
1558 // ### Qt 5: change typeName()(and froends= to return a QString. Suggestion from Harald.
1559 /*!
1560     Returns the name of the type stored in the variant. The returned
1561     strings describe the C++ datatype used to store the data: for
1562     example, "QFont", "QString", or "QVariantList". An Invalid
1563     variant returns 0.
1564 */
1565 const char *QVariant::typeName() const
1566 {
1567     return typeToName(Type(d.type));
1568 }
1569
1570 /*!
1571     Convert this variant to type Invalid and free up any resources
1572     used.
1573 */
1574 void QVariant::clear()
1575 {
1576     if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
1577         handlerManager[d.type]->clear(&d);
1578     d.type = Invalid;
1579     d.is_null = true;
1580     d.is_shared = false;
1581 }
1582
1583 /*!
1584     Converts the enum representation of the storage type, \a typ, to
1585     its string representation.
1586
1587     Returns a null pointer if the type is QVariant::Invalid or doesn't exist.
1588 */
1589 const char *QVariant::typeToName(Type typ)
1590 {
1591     if (typ == Invalid)
1592         return 0;
1593     if (typ == UserType)
1594         return "UserType";
1595
1596     return QMetaType::typeName(typ);
1597 }
1598
1599
1600 /*!
1601     Converts the string representation of the storage type given in \a
1602     name, to its enum representation.
1603
1604     If the string representation cannot be converted to any enum
1605     representation, the variant is set to \c Invalid.
1606 */
1607 QVariant::Type QVariant::nameToType(const char *name)
1608 {
1609     if (!name || !*name)
1610         return Invalid;
1611     if (strcmp(name, "Q3CString") == 0)
1612         return ByteArray;
1613     if (strcmp(name, "Q_LLONG") == 0)
1614         return LongLong;
1615     if (strcmp(name, "Q_ULLONG") == 0)
1616         return ULongLong;
1617     if (strcmp(name, "QIconSet") == 0)
1618         return Icon;
1619     if (strcmp(name, "UserType") == 0)
1620         return UserType;
1621
1622     int metaType = QMetaType::type(name);
1623     return metaType <= int(LastGuiType) ? QVariant::Type(metaType) : UserType;
1624 }
1625
1626 #ifndef QT_NO_DATASTREAM
1627 enum { MapFromThreeCount = 36 };
1628 static const ushort mapIdFromQt3ToCurrent[MapFromThreeCount] =
1629 {
1630     QVariant::Invalid,
1631     QVariant::Map,
1632     QVariant::List,
1633     QVariant::String,
1634     QVariant::StringList,
1635     QVariant::Font,
1636     QVariant::Pixmap,
1637     QVariant::Brush,
1638     QVariant::Rect,
1639     QVariant::Size,
1640     QVariant::Color,
1641     QVariant::Palette,
1642     63, // ColorGroup
1643     QVariant::Icon,
1644     QVariant::Point,
1645     QVariant::Image,
1646     QVariant::Int,
1647     QVariant::UInt,
1648     QVariant::Bool,
1649     QVariant::Double,
1650     QVariant::ByteArray,
1651     QVariant::Polygon,
1652     QVariant::Region,
1653     QVariant::Bitmap,
1654     QVariant::Cursor,
1655     QVariant::SizePolicy,
1656     QVariant::Date,
1657     QVariant::Time,
1658     QVariant::DateTime,
1659     QVariant::ByteArray,
1660     QVariant::BitArray,
1661     QVariant::KeySequence,
1662     QVariant::Pen,
1663     QVariant::LongLong,
1664     QVariant::ULongLong,
1665     QVariant::EasingCurve
1666 };
1667
1668 /*!
1669     Internal function for loading a variant from stream \a s. Use the
1670     stream operators instead.
1671
1672     \internal
1673 */
1674 void QVariant::load(QDataStream &s)
1675 {
1676     clear();
1677
1678     quint32 typeId;
1679     s >> typeId;
1680     if (s.version() < QDataStream::Qt_4_0) {
1681         if (typeId >= MapFromThreeCount)
1682             return;
1683         typeId = mapIdFromQt3ToCurrent[typeId];
1684     } else if (s.version() < QDataStream::Qt_5_0) {
1685         if (typeId >= 128 && typeId != QVariant::UserType) {
1686             // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
1687             // by moving all ids down by 97.
1688             typeId -= 97;
1689         } else if (typeId == 69 /* QIcon */) {
1690             // In Qt5 after modularization project this types where moved to a separate module (and ids were downgraded)
1691             typeId = QMetaType::QIcon;
1692         } else if (typeId == 75 /* QSizePolicy */) {
1693             typeId = QMetaType::QSizePolicy;
1694         } else if (typeId >= 70) {
1695             // and as a result this types recieved lower ids too
1696             if (typeId <= 74) { // QImage QPolygon QRegion QBitmap QCursor
1697                 typeId -=1;
1698             } else if (typeId <= 86) { // QKeySequence QPen QTextLength QTextFormat QMatrix QTransform QMatrix4x4 QVector2D QVector3D QVector4D QQuaternion
1699                 typeId -=2;
1700             }
1701         }
1702     }
1703
1704     qint8 is_null = false;
1705     if (s.version() >= QDataStream::Qt_4_2)
1706         s >> is_null;
1707     if (typeId == QVariant::UserType) {
1708         QByteArray name;
1709         s >> name;
1710         typeId = QMetaType::type(name);
1711         if (!typeId) {
1712             s.setStatus(QDataStream::ReadCorruptData);
1713             return;
1714         }
1715     }
1716     create(static_cast<int>(typeId), 0);
1717     d.is_null = is_null;
1718
1719     if (!isValid()) {
1720         // Since we wrote something, we should read something
1721         QString x;
1722         s >> x;
1723         d.is_null = true;
1724         return;
1725     }
1726
1727     // const cast is safe since we operate on a newly constructed variant
1728     if (!QMetaType::load(s, d.type, const_cast<void *>(constData()))) {
1729         s.setStatus(QDataStream::ReadCorruptData);
1730         qWarning("QVariant::load: unable to load type %d.", d.type);
1731     }
1732 }
1733
1734 /*!
1735     Internal function for saving a variant to the stream \a s. Use the
1736     stream operators instead.
1737
1738     \internal
1739 */
1740 void QVariant::save(QDataStream &s) const
1741 {
1742     quint32 typeId = type();
1743     if (s.version() < QDataStream::Qt_4_0) {
1744         int i;
1745         for (i = MapFromThreeCount - 1; i >= 0; i--) {
1746             if (mapIdFromQt3ToCurrent[i] == typeId) {
1747                 typeId = i;
1748                 break;
1749             }
1750         }
1751         if (i == -1) {
1752             s << QVariant();
1753             return;
1754         }
1755     } else if (s.version() < QDataStream::Qt_5_0) {
1756         if (typeId >= 128 - 97 && typeId <= LastCoreType) {
1757             // In Qt4 id == 128 was FirstExtCoreType. In Qt5 ExtCoreTypes set was merged to CoreTypes
1758             // by moving all ids down by 97.
1759             typeId += 97;
1760         } else if (typeId == QMetaType::QIcon) {
1761             // In Qt5 after modularization project this types where moved to a separate module (and ids were downgraded)
1762             typeId = 69;
1763         } else if (typeId == QMetaType::QSizePolicy) {
1764             typeId = 75;
1765         } else if (typeId >= QMetaType::QImage) {
1766             // and as a result this types recieved lower ids too
1767             if (typeId <= QMetaType::QCursor) {
1768                 typeId +=1;
1769             } else if (typeId <= QMetaType::QQuaternion) {
1770                 typeId +=2;
1771             }
1772         }
1773     }
1774     s << typeId;
1775     if (s.version() >= QDataStream::Qt_4_2)
1776         s << qint8(d.is_null);
1777     if (typeId == QVariant::UserType) {
1778         s << QMetaType::typeName(userType());
1779     }
1780
1781     if (!isValid()) {
1782         s << QString();
1783         return;
1784     }
1785
1786     if (!QMetaType::save(s, d.type, constData())) {
1787         qWarning("QVariant::save: unable to save type '%s' (type id: %d).\n", QMetaType::typeName(d.type), d.type);
1788         Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
1789     }
1790 }
1791
1792 /*!
1793     \since 4.4
1794
1795     Reads a variant \a p from the stream \a s.
1796
1797     \sa \link datastreamformat.html Format of the QDataStream
1798     operators \endlink
1799 */
1800 QDataStream& operator>>(QDataStream &s, QVariant &p)
1801 {
1802     p.load(s);
1803     return s;
1804 }
1805
1806 /*!
1807     Writes a variant \a p to the stream \a s.
1808
1809     \sa \link datastreamformat.html Format of the QDataStream
1810     operators \endlink
1811 */
1812 QDataStream& operator<<(QDataStream &s, const QVariant &p)
1813 {
1814     p.save(s);
1815     return s;
1816 }
1817
1818 /*!
1819     Reads a variant type \a p in enum representation from the stream \a s.
1820 */
1821 QDataStream& operator>>(QDataStream &s, QVariant::Type &p)
1822 {
1823     quint32 u;
1824     s >> u;
1825     p = (QVariant::Type)u;
1826
1827     return s;
1828 }
1829
1830 /*!
1831     Writes a variant type \a p to the stream \a s.
1832 */
1833 QDataStream& operator<<(QDataStream &s, const QVariant::Type p)
1834 {
1835     s << static_cast<quint32>(p);
1836
1837     return s;
1838 }
1839
1840 #endif //QT_NO_DATASTREAM
1841
1842 /*!
1843     \fn bool QVariant::isValid() const
1844
1845     Returns true if the storage type of this variant is not
1846     QVariant::Invalid; otherwise returns false.
1847 */
1848
1849 template <typename T>
1850 inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &handlerManager)
1851 {
1852     const QVariant::Type targetType = static_cast<const QVariant::Type>(qMetaTypeId<T>());
1853     if (d.type == targetType)
1854         return *v_cast<T>(&d);
1855
1856     T ret;
1857     handlerManager[d.type]->convert(&d, targetType, &ret, 0);
1858     return ret;
1859 }
1860
1861 /*!
1862     \fn QStringList QVariant::toStringList() const
1863
1864     Returns the variant as a QStringList if the variant has type()
1865     StringList, \l String, or \l List of a type that can be converted
1866     to QString; otherwise returns an empty list.
1867
1868     \sa canConvert(), convert()
1869 */
1870 QStringList QVariant::toStringList() const
1871 {
1872     return qVariantToHelper<QStringList>(d, handlerManager);
1873 }
1874
1875 /*!
1876     Returns the variant as a QString if the variant has type() \l
1877     String, \l Bool, \l ByteArray, \l Char, \l Date, \l DateTime, \l
1878     Double, \l Int, \l LongLong, \l StringList, \l Time, \l UInt, or
1879     \l ULongLong; otherwise returns an empty string.
1880
1881     \sa canConvert(), convert()
1882 */
1883 QString QVariant::toString() const
1884 {
1885     return qVariantToHelper<QString>(d, handlerManager);
1886 }
1887
1888 /*!
1889     Returns the variant as a QMap<QString, QVariant> if the variant
1890     has type() \l Map; otherwise returns an empty map.
1891
1892     \sa canConvert(), convert()
1893 */
1894 QVariantMap QVariant::toMap() const
1895 {
1896     return qVariantToHelper<QVariantMap>(d, handlerManager);
1897 }
1898
1899 /*!
1900     Returns the variant as a QHash<QString, QVariant> if the variant
1901     has type() \l Hash; otherwise returns an empty map.
1902
1903     \sa canConvert(), convert()
1904 */
1905 QVariantHash QVariant::toHash() const
1906 {
1907     return qVariantToHelper<QVariantHash>(d, handlerManager);
1908 }
1909
1910 /*!
1911     \fn QDate QVariant::toDate() const
1912
1913     Returns the variant as a QDate if the variant has type() \l Date,
1914     \l DateTime, or \l String; otherwise returns an invalid date.
1915
1916     If the type() is \l String, an invalid date will be returned if the
1917     string cannot be parsed as a Qt::ISODate format date.
1918
1919     \sa canConvert(), convert()
1920 */
1921 QDate QVariant::toDate() const
1922 {
1923     return qVariantToHelper<QDate>(d, handlerManager);
1924 }
1925
1926 /*!
1927     \fn QTime QVariant::toTime() const
1928
1929     Returns the variant as a QTime if the variant has type() \l Time,
1930     \l DateTime, or \l String; otherwise returns an invalid time.
1931
1932     If the type() is \l String, an invalid time will be returned if
1933     the string cannot be parsed as a Qt::ISODate format time.
1934
1935     \sa canConvert(), convert()
1936 */
1937 QTime QVariant::toTime() const
1938 {
1939     return qVariantToHelper<QTime>(d, handlerManager);
1940 }
1941
1942 /*!
1943     \fn QDateTime QVariant::toDateTime() const
1944
1945     Returns the variant as a QDateTime if the variant has type() \l
1946     DateTime, \l Date, or \l String; otherwise returns an invalid
1947     date/time.
1948
1949     If the type() is \l String, an invalid date/time will be returned
1950     if the string cannot be parsed as a Qt::ISODate format date/time.
1951
1952     \sa canConvert(), convert()
1953 */
1954 QDateTime QVariant::toDateTime() const
1955 {
1956     return qVariantToHelper<QDateTime>(d, handlerManager);
1957 }
1958
1959 /*!
1960     \since 4.7
1961     \fn QEasingCurve QVariant::toEasingCurve() const
1962
1963     Returns the variant as a QEasingCurve if the variant has type() \l
1964     EasingCurve; otherwise returns a default easing curve.
1965
1966     \sa canConvert(), convert()
1967 */
1968 #ifndef QT_BOOTSTRAPPED
1969 QEasingCurve QVariant::toEasingCurve() const
1970 {
1971     return qVariantToHelper<QEasingCurve>(d, handlerManager);
1972 }
1973 #endif
1974
1975 /*!
1976     \fn QByteArray QVariant::toByteArray() const
1977
1978     Returns the variant as a QByteArray if the variant has type() \l
1979     ByteArray or \l String (converted using QString::fromAscii());
1980     otherwise returns an empty byte array.
1981
1982     \sa canConvert(), convert()
1983 */
1984 QByteArray QVariant::toByteArray() const
1985 {
1986     return qVariantToHelper<QByteArray>(d, handlerManager);
1987 }
1988
1989 #ifndef QT_NO_GEOM_VARIANT
1990 /*!
1991     \fn QPoint QVariant::toPoint() const
1992
1993     Returns the variant as a QPoint if the variant has type()
1994     \l Point or \l PointF; otherwise returns a null QPoint.
1995
1996     \sa canConvert(), convert()
1997 */
1998 QPoint QVariant::toPoint() const
1999 {
2000     return qVariantToHelper<QPoint>(d, handlerManager);
2001 }
2002
2003 /*!
2004     \fn QRect QVariant::toRect() const
2005
2006     Returns the variant as a QRect if the variant has type() \l Rect;
2007     otherwise returns an invalid QRect.
2008
2009     \sa canConvert(), convert()
2010 */
2011 QRect QVariant::toRect() const
2012 {
2013     return qVariantToHelper<QRect>(d, handlerManager);
2014 }
2015
2016 /*!
2017     \fn QSize QVariant::toSize() const
2018
2019     Returns the variant as a QSize if the variant has type() \l Size;
2020     otherwise returns an invalid QSize.
2021
2022     \sa canConvert(), convert()
2023 */
2024 QSize QVariant::toSize() const
2025 {
2026     return qVariantToHelper<QSize>(d, handlerManager);
2027 }
2028
2029 /*!
2030     \fn QSizeF QVariant::toSizeF() const
2031
2032     Returns the variant as a QSizeF if the variant has type() \l
2033     SizeF; otherwise returns an invalid QSizeF.
2034
2035     \sa canConvert(), convert()
2036 */
2037 QSizeF QVariant::toSizeF() const
2038 {
2039     return qVariantToHelper<QSizeF>(d, handlerManager);
2040 }
2041
2042 /*!
2043     \fn QRectF QVariant::toRectF() const
2044
2045     Returns the variant as a QRectF if the variant has type() \l Rect
2046     or \l RectF; otherwise returns an invalid QRectF.
2047
2048     \sa canConvert(), convert()
2049 */
2050 QRectF QVariant::toRectF() const
2051 {
2052     return qVariantToHelper<QRectF>(d, handlerManager);
2053 }
2054
2055 /*!
2056     \fn QLineF QVariant::toLineF() const
2057
2058     Returns the variant as a QLineF if the variant has type() \l
2059     LineF; otherwise returns an invalid QLineF.
2060
2061     \sa canConvert(), convert()
2062 */
2063 QLineF QVariant::toLineF() const
2064 {
2065     return qVariantToHelper<QLineF>(d, handlerManager);
2066 }
2067
2068 /*!
2069     \fn QLine QVariant::toLine() const
2070
2071     Returns the variant as a QLine if the variant has type() \l Line;
2072     otherwise returns an invalid QLine.
2073
2074     \sa canConvert(), convert()
2075 */
2076 QLine QVariant::toLine() const
2077 {
2078     return qVariantToHelper<QLine>(d, handlerManager);
2079 }
2080
2081 /*!
2082     \fn QPointF QVariant::toPointF() const
2083
2084     Returns the variant as a QPointF if the variant has type() \l
2085     Point or \l PointF; otherwise returns a null QPointF.
2086
2087     \sa canConvert(), convert()
2088 */
2089 QPointF QVariant::toPointF() const
2090 {
2091     return qVariantToHelper<QPointF>(d, handlerManager);
2092 }
2093
2094 #endif // QT_NO_GEOM_VARIANT
2095
2096 /*!
2097     \fn QUrl QVariant::toUrl() const
2098
2099     Returns the variant as a QUrl if the variant has type()
2100     \l Url; otherwise returns an invalid QUrl.
2101
2102     \sa canConvert(), convert()
2103 */
2104 QUrl QVariant::toUrl() const
2105 {
2106     return qVariantToHelper<QUrl>(d, handlerManager);
2107 }
2108
2109 /*!
2110     \fn QLocale QVariant::toLocale() const
2111
2112     Returns the variant as a QLocale if the variant has type()
2113     \l Locale; otherwise returns an invalid QLocale.
2114
2115     \sa canConvert(), convert()
2116 */
2117 QLocale QVariant::toLocale() const
2118 {
2119     return qVariantToHelper<QLocale>(d, handlerManager);
2120 }
2121
2122 /*!
2123     \fn QRegExp QVariant::toRegExp() const
2124     \since 4.1
2125
2126     Returns the variant as a QRegExp if the variant has type() \l
2127     RegExp; otherwise returns an empty QRegExp.
2128
2129     \sa canConvert(), convert()
2130 */
2131 #ifndef QT_NO_REGEXP
2132 QRegExp QVariant::toRegExp() const
2133 {
2134     return qVariantToHelper<QRegExp>(d, handlerManager);
2135 }
2136 #endif
2137
2138 /*!
2139     \fn QChar QVariant::toChar() const
2140
2141     Returns the variant as a QChar if the variant has type() \l Char,
2142     \l Int, or \l UInt; otherwise returns an invalid QChar.
2143
2144     \sa canConvert(), convert()
2145 */
2146 QChar QVariant::toChar() const
2147 {
2148     return qVariantToHelper<QChar>(d, handlerManager);
2149 }
2150
2151 /*!
2152     Returns the variant as a QBitArray if the variant has type()
2153     \l BitArray; otherwise returns an empty bit array.
2154
2155     \sa canConvert(), convert()
2156 */
2157 QBitArray QVariant::toBitArray() const
2158 {
2159     return qVariantToHelper<QBitArray>(d, handlerManager);
2160 }
2161
2162 template <typename T>
2163 inline T qNumVariantToHelper(const QVariant::Private &d,
2164                              const HandlersManager &handlerManager, bool *ok, const T& val)
2165 {
2166     uint t = qMetaTypeId<T>();
2167     if (ok)
2168         *ok = true;
2169     if (d.type == t)
2170         return val;
2171
2172     T ret = 0;
2173     if (!handlerManager[d.type]->convert(&d, QVariant::Type(t), &ret, ok) && ok)
2174         *ok = false;
2175     return ret;
2176 }
2177
2178 /*!
2179     Returns the variant as an int if the variant has type() \l Int,
2180     \l Bool, \l ByteArray, \l Char, \l Double, \l LongLong, \l
2181     String, \l UInt, or \l ULongLong; otherwise returns 0.
2182
2183     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2184     converted to an int; otherwise \c{*}\a{ok} is set to false.
2185
2186     \bold{Warning:} If the value is convertible to a \l LongLong but is too
2187     large to be represented in an int, the resulting arithmetic overflow will
2188     not be reflected in \a ok. A simple workaround is to use QString::toInt().
2189     Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
2190
2191     \sa canConvert(), convert()
2192 */
2193 int QVariant::toInt(bool *ok) const
2194 {
2195     return qNumVariantToHelper<int>(d, handlerManager, ok, d.data.i);
2196 }
2197
2198 /*!
2199     Returns the variant as an unsigned int if the variant has type()
2200     \l UInt,  \l Bool, \l ByteArray, \l Char, \l Double, \l Int, \l
2201     LongLong, \l String, or \l ULongLong; otherwise returns 0.
2202
2203     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2204     converted to an unsigned int; otherwise \c{*}\a{ok} is set to false.
2205
2206     \bold{Warning:} If the value is convertible to a \l ULongLong but is too
2207     large to be represented in an unsigned int, the resulting arithmetic overflow will
2208     not be reflected in \a ok. A simple workaround is to use QString::toUInt().
2209     Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
2210
2211     \sa canConvert(), convert()
2212 */
2213 uint QVariant::toUInt(bool *ok) const
2214 {
2215     return qNumVariantToHelper<uint>(d, handlerManager, ok, d.data.u);
2216 }
2217
2218 /*!
2219     Returns the variant as a long long int if the variant has type()
2220     \l LongLong, \l Bool, \l ByteArray, \l Char, \l Double, \l Int,
2221     \l String, \l UInt, or \l ULongLong; otherwise returns 0.
2222
2223     If \a ok is non-null: \c{*}\c{ok} is set to true if the value could be
2224     converted to an int; otherwise \c{*}\c{ok} is set to false.
2225
2226     \sa canConvert(), convert()
2227 */
2228 qlonglong QVariant::toLongLong(bool *ok) const
2229 {
2230     return qNumVariantToHelper<qlonglong>(d, handlerManager, ok, d.data.ll);
2231 }
2232
2233 /*!
2234     Returns the variant as as an unsigned long long int if the
2235     variant has type() \l ULongLong, \l Bool, \l ByteArray, \l Char,
2236     \l Double, \l Int, \l LongLong, \l String, or \l UInt; otherwise
2237     returns 0.
2238
2239     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2240     converted to an int; otherwise \c{*}\a{ok} is set to false.
2241
2242     \sa canConvert(), convert()
2243 */
2244 qulonglong QVariant::toULongLong(bool *ok) const
2245 {
2246     return qNumVariantToHelper<qulonglong>(d, handlerManager, ok, d.data.ull);
2247 }
2248
2249 /*!
2250     Returns the variant as a bool if the variant has type() Bool.
2251
2252     Returns true if the variant has type() \l Bool, \l Char, \l Double,
2253     \l Int, \l LongLong, \l UInt, or \l ULongLong and the value is
2254     non-zero, or if the variant has type \l String or \l ByteArray and
2255     its lower-case content is not empty, "0" or "false"; otherwise
2256     returns false.
2257
2258     \sa canConvert(), convert()
2259 */
2260 bool QVariant::toBool() const
2261 {
2262     if (d.type == Bool)
2263         return d.data.b;
2264
2265     bool res = false;
2266     handlerManager[d.type]->convert(&d, Bool, &res, 0);
2267
2268     return res;
2269 }
2270
2271 /*!
2272     Returns the variant as a double if the variant has type() \l
2273     Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
2274     UInt, or \l ULongLong; otherwise returns 0.0.
2275
2276     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2277     converted to a double; otherwise \c{*}\a{ok} is set to false.
2278
2279     \sa canConvert(), convert()
2280 */
2281 double QVariant::toDouble(bool *ok) const
2282 {
2283     return qNumVariantToHelper<double>(d, handlerManager, ok, d.data.d);
2284 }
2285
2286 /*!
2287     Returns the variant as a float if the variant has type() \l
2288     Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
2289     UInt, or \l ULongLong; otherwise returns 0.0.
2290
2291     \since 4.6
2292
2293     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2294     converted to a double; otherwise \c{*}\a{ok} is set to false.
2295
2296     \sa canConvert(), convert()
2297 */
2298 float QVariant::toFloat(bool *ok) const
2299 {
2300     return qNumVariantToHelper<float>(d, handlerManager, ok, d.data.f);
2301 }
2302
2303 /*!
2304     Returns the variant as a qreal if the variant has type() \l
2305     Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
2306     UInt, or \l ULongLong; otherwise returns 0.0.
2307
2308     \since 4.6
2309
2310     If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2311     converted to a double; otherwise \c{*}\a{ok} is set to false.
2312
2313     \sa canConvert(), convert()
2314 */
2315 qreal QVariant::toReal(bool *ok) const
2316 {
2317     return qNumVariantToHelper<qreal>(d, handlerManager, ok, d.data.real);
2318 }
2319
2320 /*!
2321     Returns the variant as a QVariantList if the variant has type()
2322     \l List or \l StringList; otherwise returns an empty list.
2323
2324     \sa canConvert(), convert()
2325 */
2326 QVariantList QVariant::toList() const
2327 {
2328     return qVariantToHelper<QVariantList>(d, handlerManager);
2329 }
2330
2331
2332 static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
2333 {
2334 /*Invalid*/     0,
2335
2336 /*Bool*/          1 << QVariant::Double     | 1 << QVariant::Int        | 1 << QVariant::UInt
2337                 | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong  | 1 << QVariant::ByteArray
2338                 | 1 << QVariant::String     | 1 << QVariant::Char,
2339
2340 /*Int*/           1 << QVariant::UInt       | 1 << QVariant::String     | 1 << QVariant::Double
2341                 | 1 << QVariant::Bool       | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong
2342                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
2343
2344 /*UInt*/          1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::Double
2345                 | 1 << QVariant::Bool       | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong
2346                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
2347
2348 /*LLong*/         1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::Double
2349                 | 1 << QVariant::Bool       | 1 << QVariant::UInt       | 1 << QVariant::ULongLong
2350                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
2351
2352 /*ULlong*/        1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::Double
2353                 | 1 << QVariant::Bool       | 1 << QVariant::UInt       | 1 << QVariant::LongLong
2354                 | 1 << QVariant::Char       | 1 << QVariant::ByteArray,
2355
2356 /*double*/        1 << QVariant::Int        | 1 << QVariant::String     | 1 << QVariant::ULongLong
2357                 | 1 << QVariant::Bool       | 1 << QVariant::UInt       | 1 << QVariant::LongLong
2358                 | 1 << QVariant::ByteArray,
2359
2360 /*QChar*/         1 << QVariant::Int        | 1 << QVariant::UInt       | 1 << QVariant::LongLong
2361                 | 1 << QVariant::ULongLong,
2362
2363 /*QMap*/          0,
2364
2365 /*QList*/         1 << QVariant::StringList,
2366
2367 /*QString*/       1 << QVariant::StringList | 1 << QVariant::ByteArray  | 1 << QVariant::Int
2368                 | 1 << QVariant::UInt       | 1 << QVariant::Bool       | 1 << QVariant::Double
2369                 | 1 << QVariant::Date       | 1 << QVariant::Time       | 1 << QVariant::DateTime
2370                 | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong  | 1 << QVariant::Char
2371                 | 1 << QVariant::Url        | 1 << QVariant::Uuid,
2372
2373 /*QStringList*/   1 << QVariant::List       | 1 << QVariant::String,
2374
2375 /*QByteArray*/    1 << QVariant::String     | 1 << QVariant::Int        | 1 << QVariant::UInt | 1 << QVariant::Bool
2376                 | 1 << QVariant::Double     | 1 << QVariant::LongLong   | 1 << QVariant::ULongLong,
2377
2378 /*QBitArray*/     0,
2379
2380 /*QDate*/         1 << QVariant::String     | 1 << QVariant::DateTime,
2381
2382 /*QTime*/         1 << QVariant::String     | 1 << QVariant::DateTime,
2383
2384 /*QDateTime*/     1 << QVariant::String     | 1 << QVariant::Date,
2385
2386 /*QUrl*/          1 << QVariant::String,
2387
2388 /*QLocale*/       0,
2389
2390 /*QRect*/         1 << QVariant::RectF,
2391
2392 /*QRectF*/        1 << QVariant::Rect,
2393
2394 /*QSize*/         1 << QVariant::SizeF,
2395
2396 /*QSizeF*/        1 << QVariant::Size,
2397
2398 /*QLine*/         1 << QVariant::LineF,
2399
2400 /*QLineF*/        1 << QVariant::Line,
2401
2402 /*QPoint*/        1 << QVariant::PointF,
2403
2404 /*QPointF*/       1 << QVariant::Point,
2405
2406 /*QRegExp*/       0,
2407
2408 /*QHash*/         0,
2409
2410 /*QEasingCurve*/  0,
2411
2412 /*QUuid*/         1 << QVariant::String
2413 };
2414
2415 /*!
2416     Returns true if the variant's type can be cast to the requested
2417     type, \a t. Such casting is done automatically when calling the
2418     toInt(), toBool(), ... methods.
2419
2420     The following casts are done automatically:
2421
2422     \table
2423     \header \o Type \o Automatically Cast To
2424     \row \o \l Bool \o \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
2425     \row \o \l ByteArray \o \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
2426     \row \o \l Char \o \l Bool, \l Int, \l UInt, \l LongLong, \l ULongLong
2427     \row \o \l Color \o \l String
2428     \row \o \l Date \o \l DateTime, \l String
2429     \row \o \l DateTime \o \l Date, \l String, \l Time
2430     \row \o \l Double \o \l Bool, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
2431     \row \o \l Font \o \l String
2432     \row \o \l Int \o \l Bool, \l Char, \l Double, \l LongLong, \l String, \l UInt, \l ULongLong
2433     \row \o \l KeySequence \o \l Int, \l String
2434     \row \o \l List \o \l StringList (if the list's items can be converted to strings)
2435     \row \o \l LongLong \o \l Bool, \l ByteArray, \l Char, \l Double, \l Int, \l String, \l UInt, \l ULongLong
2436     \row \o \l Point \o PointF
2437     \row \o \l Rect \o RectF
2438     \row \o \l String \o \l Bool, \l ByteArray, \l Char, \l Color, \l Date, \l DateTime, \l Double,
2439                          \l Font, \l Int, \l KeySequence, \l LongLong, \l StringList, \l Time, \l UInt,
2440                          \l ULongLong
2441     \row \o \l StringList \o \l List, \l String (if the list contains exactly one item)
2442     \row \o \l Time \o \l String
2443     \row \o \l UInt \o \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l ULongLong
2444     \row \o \l ULongLong \o \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt
2445     \endtable
2446
2447     \sa convert()
2448 */
2449 bool QVariant::canConvert(Type t) const
2450 {
2451     // TODO Reimplement this function, currently it works but it is a historical mess.
2452     const uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type);
2453     if (uint(t) == uint(QMetaType::Float)) t = QVariant::Double;
2454
2455     if (currentType == uint(t))
2456         return true;
2457
2458     // FIXME It should be LastCoreType intead of Uuid
2459     if (currentType > QVariant::Uuid || t > QVariant::Uuid) {
2460         switch (uint(t)) {
2461         case QVariant::Int:
2462             return currentType == QVariant::KeySequence
2463                    || currentType == QMetaType::ULong
2464                    || currentType == QMetaType::Long
2465                    || currentType == QMetaType::UShort
2466                    || currentType == QMetaType::UChar
2467                    || currentType == QMetaType::Char
2468                    || currentType == QMetaType::Short;
2469         case QVariant::Image:
2470             return currentType == QVariant::Pixmap || currentType == QVariant::Bitmap;
2471         case QVariant::Pixmap:
2472             return currentType == QVariant::Image || currentType == QVariant::Bitmap
2473                               || currentType == QVariant::Brush;
2474         case QVariant::Bitmap:
2475             return currentType == QVariant::Pixmap || currentType == QVariant::Image;
2476         case QVariant::ByteArray:
2477             return currentType == QVariant::Color;
2478         case QVariant::String:
2479             return currentType == QVariant::KeySequence || currentType == QVariant::Font
2480                               || currentType == QVariant::Color;
2481         case QVariant::KeySequence:
2482             return currentType == QVariant::String || currentType == QVariant::Int;
2483         case QVariant::Font:
2484             return currentType == QVariant::String;
2485         case QVariant::Color:
2486             return currentType == QVariant::String || currentType == QVariant::ByteArray
2487                               || currentType == QVariant::Brush;
2488         case QVariant::Brush:
2489             return currentType == QVariant::Color || currentType == QVariant::Pixmap;
2490         case QMetaType::Long:
2491         case QMetaType::Char:
2492         case QMetaType::UChar:
2493         case QMetaType::ULong:
2494         case QMetaType::Short:
2495         case QMetaType::UShort:
2496             return qCanConvertMatrix[QVariant::Int] & (1 << currentType) || currentType == QVariant::Int;
2497         default:
2498             return false;
2499         }
2500     }
2501
2502     if(t == String && currentType == StringList)
2503         return v_cast<QStringList>(&d)->count() == 1;
2504     else
2505         return qCanConvertMatrix[t] & (1 << currentType);
2506 }
2507
2508 /*!
2509     Casts the variant to the requested type, \a t. If the cast cannot be
2510     done, the variant is cleared. Returns true if the current type of
2511     the variant was successfully cast; otherwise returns false.
2512
2513     \warning For historical reasons, converting a null QVariant results
2514     in a null value of the desired type (e.g., an empty string for
2515     QString) and a result of false.
2516
2517     \sa canConvert(), clear()
2518 */
2519
2520 bool QVariant::convert(Type t)
2521 {
2522     if (d.type == uint(t))
2523         return true;
2524
2525     QVariant oldValue = *this;
2526
2527     clear();
2528     if (!oldValue.canConvert(t))
2529         return false;
2530
2531     create(t, 0);
2532     if (oldValue.isNull())
2533         return false;
2534
2535     bool isOk = true;
2536     if (!handlerManager[d.type]->convert(&oldValue.d, t, data(), &isOk))
2537         isOk = false;
2538     d.is_null = !isOk;
2539     return isOk;
2540 }
2541
2542 /*!
2543   \fn convert(const int type, void *ptr) const
2544   \internal
2545   Created for qvariant_cast() usage
2546 */
2547 bool QVariant::convert(const int type, void *ptr) const
2548 {
2549     Q_ASSERT(type < int(QMetaType::User));
2550     return handlerManager[type]->convert(&d, QVariant::Type(type), ptr, 0);
2551 }
2552
2553
2554 /*!
2555     \fn bool operator==(const QVariant &v1, const QVariant &v2)
2556
2557     \relates QVariant
2558
2559     Returns true if \a v1 and \a v2 are equal; otherwise returns false.
2560
2561     \warning This function doesn't support custom types registered
2562     with qRegisterMetaType().
2563 */
2564 /*!
2565     \fn bool operator!=(const QVariant &v1, const QVariant &v2)
2566
2567     \relates QVariant
2568
2569     Returns false if \a v1 and \a v2 are equal; otherwise returns true.
2570
2571     \warning This function doesn't support custom types registered
2572     with qRegisterMetaType().
2573 */
2574
2575 /*! \fn bool QVariant::operator==(const QVariant &v) const
2576
2577     Compares this QVariant with \a v and returns true if they are
2578     equal; otherwise returns false.
2579
2580     In the case of custom types, their equalness operators are not called.
2581     Instead the values' addresses are compared.
2582 */
2583
2584 /*!
2585     \fn bool QVariant::operator!=(const QVariant &v) const
2586
2587     Compares this QVariant with \a v and returns true if they are not
2588     equal; otherwise returns false.
2589
2590     \warning This function doesn't support custom types registered
2591     with qRegisterMetaType().
2592 */
2593
2594 static bool qIsNumericType(uint tp)
2595 {
2596     return (tp >= QVariant::Bool && tp <= QVariant::Double)
2597            || (tp >= QMetaType::Long && tp <= QMetaType::Float);
2598 }
2599
2600 static bool qIsFloatingPoint(uint tp)
2601 {
2602     return tp == QVariant::Double || tp == QMetaType::Float;
2603 }
2604
2605 /*! \internal
2606  */
2607 bool QVariant::cmp(const QVariant &v) const
2608 {
2609     QVariant v2 = v;
2610     if (d.type != v2.d.type) {
2611         if (qIsNumericType(d.type) && qIsNumericType(v.d.type)) {
2612             if (qIsFloatingPoint(d.type) || qIsFloatingPoint(v.d.type))
2613                 return qFuzzyCompare(toReal(), v.toReal());
2614             else
2615                 return toLongLong() == v.toLongLong();
2616         }
2617         if (!v2.canConvert(Type(d.type)) || !v2.convert(Type(d.type)))
2618             return false;
2619     }
2620     return handlerManager[d.type]->compare(&d, &v2.d);
2621 }
2622
2623 /*! \internal
2624  */
2625
2626 const void *QVariant::constData() const
2627 {
2628     return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr);
2629 }
2630
2631 /*!
2632     \fn const void* QVariant::data() const
2633
2634     \internal
2635 */
2636
2637 /*! \internal */
2638 void* QVariant::data()
2639 {
2640     detach();
2641     return const_cast<void *>(constData());
2642 }
2643
2644
2645 /*!
2646   Returns true if this is a NULL variant, false otherwise.
2647 */
2648 bool QVariant::isNull() const
2649 {
2650     return handlerManager[d.type]->isNull(&d);
2651 }
2652
2653 #ifndef QT_NO_DEBUG_STREAM
2654 QDebug operator<<(QDebug dbg, const QVariant &v)
2655 {
2656 #ifndef Q_BROKEN_DEBUG_STREAM
2657     dbg.nospace() << "QVariant(" << QMetaType::typeName(v.userType()) << ", ";
2658     handlerManager[v.d.type]->debugStream(dbg, v);
2659     dbg.nospace() << ')';
2660     return dbg.space();
2661 #else
2662     qWarning("This compiler doesn't support streaming QVariant to QDebug");
2663     return dbg;
2664     Q_UNUSED(v);
2665 #endif
2666 }
2667
2668 QDebug operator<<(QDebug dbg, const QVariant::Type p)
2669 {
2670 #ifndef Q_BROKEN_DEBUG_STREAM
2671     dbg.nospace() << "QVariant::" << QMetaType::typeName(p);
2672     return dbg.space();
2673 #else
2674     qWarning("This compiler doesn't support streaming QVariant::Type to QDebug");
2675     return dbg;
2676     Q_UNUSED(p);
2677 #endif
2678 }
2679 #endif
2680
2681
2682 /*! \fn void QVariant::setValue(const T &value)
2683
2684     Stores a copy of \a value. If \c{T} is a type that QVariant
2685     doesn't support, QMetaType is used to store the value. A compile
2686     error will occur if QMetaType doesn't handle the type.
2687
2688     Example:
2689
2690     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 4
2691
2692     \sa value(), fromValue(), canConvert()
2693  */
2694
2695 /*! \fn T QVariant::value() const
2696
2697     Returns the stored value converted to the template type \c{T}.
2698     Call canConvert() to find out whether a type can be converted.
2699     If the value cannot be converted, \l{default-constructed value}
2700     will be returned.
2701
2702     If the type \c{T} is supported by QVariant, this function behaves
2703     exactly as toString(), toInt() etc.
2704
2705     Example:
2706
2707     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 5
2708
2709     \sa setValue(), fromValue(), canConvert()
2710 */
2711
2712 /*! \fn bool QVariant::canConvert() const
2713
2714     Returns true if the variant can be converted to the template type \c{T},
2715     otherwise false.
2716
2717     Example:
2718
2719     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 6
2720
2721     \sa convert()
2722 */
2723
2724 /*! \fn static QVariant QVariant::fromValue(const T &value)
2725
2726     Returns a QVariant containing a copy of \a value. Behaves
2727     exactly like setValue() otherwise.
2728
2729     Example:
2730
2731     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 7
2732
2733     \note If you are working with custom types, you should use
2734     the Q_DECLARE_METATYPE() macro to register your custom type.
2735
2736     \sa setValue(), value()
2737 */
2738
2739 /*!
2740     \fn QVariant qVariantFromValue(const T &value)
2741     \relates QVariant
2742     \obsolete
2743
2744     Returns a variant containing a copy of the given \a value
2745     with template type \c{T}.
2746
2747     This function is equivalent to QVariant::fromValue(\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     For example, a QObject pointer can be stored in a variant with the
2754     following code:
2755
2756     \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 8
2757
2758     \sa QVariant::fromValue()
2759 */
2760
2761 /*! \fn void qVariantSetValue(QVariant &variant, const T &value)
2762     \relates QVariant
2763     \obsolete
2764
2765     Sets the contents of the given \a variant to a copy of the
2766     \a value with the specified template type \c{T}.
2767
2768     This function is equivalent to QVariant::setValue(\a value).
2769
2770     \note This function was provided as a workaround for MSVC 6
2771     which did not support member template functions. It is advised
2772     to use the other form in new code.
2773
2774     \sa QVariant::setValue()
2775 */
2776
2777 /*!
2778     \fn T qvariant_cast(const QVariant &value)
2779     \relates QVariant
2780
2781     Returns the given \a value converted to the template type \c{T}.
2782
2783     This function is equivalent to QVariant::value().
2784
2785     \sa QVariant::value()
2786 */
2787
2788 /*! \fn T qVariantValue(const QVariant &value)
2789     \relates QVariant
2790     \obsolete
2791
2792     Returns the given \a value converted to the template type \c{T}.
2793
2794     This function is equivalent to
2795     \l{QVariant::value()}{QVariant::value}<T>(\a value).
2796
2797     \note This function was provided as a workaround for MSVC 6
2798     which did not support member template functions. It is advised
2799     to use the other form in new code.
2800
2801     \sa QVariant::value(), qvariant_cast()
2802 */
2803
2804 /*! \fn bool qVariantCanConvert(const QVariant &value)
2805     \relates QVariant
2806     \obsolete
2807
2808     Returns true if the given \a value can be converted to the
2809     template type specified; otherwise returns false.
2810
2811     This function is equivalent to QVariant::canConvert(\a value).
2812
2813     \note This function was provided as a workaround for MSVC 6
2814     which did not support member template functions. It is advised
2815     to use the other form in new code.
2816
2817     \sa QVariant::canConvert()
2818 */
2819
2820 /*!
2821     \typedef QVariantList
2822     \relates QVariant
2823
2824     Synonym for QList<QVariant>.
2825 */
2826
2827 /*!
2828     \typedef QVariantMap
2829     \relates QVariant
2830
2831     Synonym for QMap<QString, QVariant>.
2832 */
2833
2834 /*!
2835     \typedef QVariantHash
2836     \relates QVariant
2837     \since 4.5
2838
2839     Synonym for QHash<QString, QVariant>.
2840 */
2841
2842 /*!
2843     \typedef QVariant::DataPtr
2844     \internal
2845 */
2846
2847 /*!
2848     \fn DataPtr &QVariant::data_ptr()
2849     \internal
2850 */
2851
2852 QT_END_NAMESPACE