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