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 ®Exp)
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 ®Exp) { 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