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