1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #include <QtTest/QtTest>
50 Q_DECLARE_METATYPE(QMetaType::Type)
52 class tst_QMetaType: public QObject
55 Q_PROPERTY(QList<QVariant> prop READ prop WRITE setProp)
58 tst_QMetaType() { propList << 42 << "Hello"; }
60 QList<QVariant> prop() const { return propList; }
61 void setProp(const QList<QVariant> &list) { propList = list; }
64 QList<QVariant> propList;
72 void normalizedTypes();
77 void createCopy_data();
81 void sizeOfStaticLess_data();
82 void sizeOfStaticLess();
85 void flagsStaticLess_data();
86 void flagsStaticLess();
87 void construct_data();
89 void constructCopy_data();
93 void isRegistered_data();
95 void isRegisteredStaticLess_data();
96 void isRegisteredStaticLess();
97 void registerStreamBuiltin();
98 void automaticTemplateRegistration();
101 struct Foo { int i; };
103 void tst_QMetaType::defined()
105 QCOMPARE(int(QMetaTypeId2<QString>::Defined), 1);
106 QCOMPARE(int(QMetaTypeId2<Foo>::Defined), 0);
107 QCOMPARE(int(QMetaTypeId2<void*>::Defined), 1);
108 QCOMPARE(int(QMetaTypeId2<int*>::Defined), 0);
116 if (!QMetaType::isRegistered(qRegisterMetaType<Foo>("Foo"))) {
117 qWarning("%s: re-entrancy test failed", Q_FUNC_INFO);
123 static int failureCount;
126 int Bar::failureCount = 0;
128 class MetaTypeTorturer: public QThread
137 for (int i = 0; i < 1000; ++i) {
138 const QByteArray name = QString("Bar%1_%2").arg(i).arg((size_t)QThread::currentThreadId()).toLatin1();
139 const char *nm = name.constData();
140 int tp = qRegisterMetaType<Bar>(nm);
145 if (!info.isValid()) {
147 qWarning() << "Wrong typeInfo returned for" << tp;
149 if (!info.isRegistered()) {
151 qWarning() << name << "is not a registered metatype";
153 if (QMetaType::typeFlags(tp) != (QMetaType::NeedsConstruction | QMetaType::NeedsDestruction)) {
155 qWarning() << "Wrong typeInfo returned for" << tp;
157 if (!QMetaType::isRegistered(tp)) {
159 qWarning() << name << "is not a registered metatype";
161 if (QMetaType::type(nm) != tp) {
163 qWarning() << "Wrong metatype returned for" << name;
165 if (QMetaType::typeName(tp) != name) {
167 qWarning() << "Wrong typeName returned for" << tp;
169 void *buf1 = QMetaType::create(tp, 0);
170 void *buf2 = QMetaType::create(tp, buf1);
171 void *buf3 = info.create(tp, 0);
172 void *buf4 = info.create(tp, buf1);
174 QMetaType::construct(tp, space, 0);
175 QMetaType::destruct(tp, space);
176 QMetaType::construct(tp, space, buf1);
177 QMetaType::destruct(tp, space);
179 info.construct(space, 0);
180 info.destruct(space);
181 info.construct(space, buf1);
182 info.destruct(space);
186 qWarning() << "Null buffer returned by QMetaType::create(tp, 0)";
190 qWarning() << "Null buffer returned by QMetaType::create(tp, buf)";
194 qWarning() << "Null buffer returned by info.create(tp, 0)";
198 qWarning() << "Null buffer returned by infocreate(tp, buf)";
200 QMetaType::destroy(tp, buf1);
201 QMetaType::destroy(tp, buf2);
208 MetaTypeTorturer() : failureCount(0) { }
212 void tst_QMetaType::threadSafety()
226 QCOMPARE(t1.failureCount, 0);
227 QCOMPARE(t2.failureCount, 0);
228 QCOMPARE(t3.failureCount, 0);
229 QCOMPARE(Bar::failureCount, 0);
234 struct Foo { double d; };
237 Q_DECLARE_METATYPE(TestSpace::Foo)
239 void tst_QMetaType::namespaces()
241 TestSpace::Foo nf = { 11.12 };
242 QVariant v = qVariantFromValue(nf);
243 QCOMPARE(qvariant_cast<TestSpace::Foo>(v).d, 11.12);
246 void tst_QMetaType::qMetaTypeId()
248 QCOMPARE(::qMetaTypeId<QString>(), int(QMetaType::QString));
249 QCOMPARE(::qMetaTypeId<int>(), int(QMetaType::Int));
250 QCOMPARE(::qMetaTypeId<TestSpace::Foo>(), QMetaType::type("TestSpace::Foo"));
252 QCOMPARE(::qMetaTypeId<char>(), QMetaType::type("char"));
253 QCOMPARE(::qMetaTypeId<uchar>(), QMetaType::type("unsigned char"));
254 QCOMPARE(::qMetaTypeId<signed char>(), QMetaType::type("signed char"));
255 QCOMPARE(::qMetaTypeId<qint8>(), QMetaType::type("qint8"));
258 void tst_QMetaType::properties()
260 qRegisterMetaType<QList<QVariant> >("QList<QVariant>");
262 QVariant v = property("prop");
264 QCOMPARE(v.typeName(), "QVariantList");
266 QList<QVariant> values = v.toList();
267 QCOMPARE(values.count(), 2);
268 QCOMPARE(values.at(0).toInt(), 42);
270 values << 43 << "world";
272 QVERIFY(setProperty("prop", values));
273 v = property("prop");
274 QCOMPARE(v.toList().count(), 4);
277 template <typename T>
278 struct Whity { T t; };
280 Q_DECLARE_METATYPE( Whity < int > )
281 Q_DECLARE_METATYPE(Whity<double>)
283 void tst_QMetaType::normalizedTypes()
285 int WhityIntId = ::qMetaTypeId<Whity<int> >();
286 int WhityDoubleId = ::qMetaTypeId<Whity<double> >();
288 QCOMPARE(QMetaType::type("Whity<int>"), WhityIntId);
289 QCOMPARE(QMetaType::type(" Whity < int > "), WhityIntId);
290 QCOMPARE(QMetaType::type("Whity<int >"), WhityIntId);
292 QCOMPARE(QMetaType::type("Whity<double>"), WhityDoubleId);
293 QCOMPARE(QMetaType::type(" Whity< double > "), WhityDoubleId);
294 QCOMPARE(QMetaType::type("Whity<double >"), WhityDoubleId);
296 QCOMPARE(qRegisterMetaType<Whity<int> >(" Whity < int > "), WhityIntId);
297 QCOMPARE(qRegisterMetaType<Whity<int> >("Whity<int>"), WhityIntId);
298 QCOMPARE(qRegisterMetaType<Whity<int> >("Whity<int > "), WhityIntId);
300 QCOMPARE(qRegisterMetaType<Whity<double> >(" Whity < double > "), WhityDoubleId);
301 QCOMPARE(qRegisterMetaType<Whity<double> >("Whity<double>"), WhityDoubleId);
302 QCOMPARE(qRegisterMetaType<Whity<double> >("Whity<double > "), WhityDoubleId);
305 #define TYPENAME_DATA(MetaTypeName, MetaTypeId, RealType)\
306 QTest::newRow(#RealType) << QMetaType::MetaTypeName << #RealType;
308 #define TYPENAME_DATA_ALIAS(MetaTypeName, MetaTypeId, AliasType, RealTypeString)\
309 QTest::newRow(RealTypeString) << QMetaType::MetaTypeName << #AliasType;
311 void tst_QMetaType::typeName_data()
313 QTest::addColumn<QMetaType::Type>("aType");
314 QTest::addColumn<QString>("aTypeName");
316 QT_FOR_EACH_STATIC_TYPE(TYPENAME_DATA)
317 QT_FOR_EACH_STATIC_ALIAS_TYPE(TYPENAME_DATA_ALIAS)
320 void tst_QMetaType::typeName()
322 QFETCH(QMetaType::Type, aType);
323 QFETCH(QString, aTypeName);
325 QCOMPARE(QString::fromLatin1(QMetaType::typeName(aType)), aTypeName);
328 #define FOR_EACH_PRIMITIVE_METATYPE(F) \
329 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
330 QT_FOR_EACH_STATIC_CORE_POINTER(F) \
332 #define FOR_EACH_COMPLEX_CORE_METATYPE(F) \
333 QT_FOR_EACH_STATIC_CORE_CLASS(F)
335 #define FOR_EACH_CORE_METATYPE(F) \
336 FOR_EACH_PRIMITIVE_METATYPE(F) \
337 FOR_EACH_COMPLEX_CORE_METATYPE(F) \
340 struct MetaEnumToType {};
342 #define DEFINE_META_ENUM_TO_TYPE(MetaTypeName, MetaTypeId, RealType) \
344 struct MetaEnumToType<QMetaType::MetaTypeName> { \
345 typedef RealType Type; \
347 FOR_EACH_CORE_METATYPE(DEFINE_META_ENUM_TO_TYPE)
348 #undef DEFINE_META_ENUM_TO_TYPE
351 struct DefaultValueFactory
353 typedef typename MetaEnumToType<ID>::Type Type;
354 static Type *create() { return new Type; }
358 struct DefaultValueFactory<QMetaType::Void>
360 typedef MetaEnumToType<QMetaType::Void>::Type Type;
361 static Type *create() { return 0; }
365 struct DefaultValueTraits
367 // By default we assume that a default-constructed value (new T) is
368 // initialized; e.g. QCOMPARE(*(new T), *(new T)) should succeed
369 enum { IsInitialized = true };
372 #define DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS(MetaTypeName, MetaTypeId, RealType) \
373 template<> struct DefaultValueTraits<QMetaType::MetaTypeName> { \
374 enum { IsInitialized = false }; \
376 // Primitive types (int et al) aren't initialized
377 FOR_EACH_PRIMITIVE_METATYPE(DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS)
378 #undef DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS
381 struct TestValueFactory {};
383 template<> struct TestValueFactory<QMetaType::Void> {
384 static void *create() { return 0; }
387 template<> struct TestValueFactory<QMetaType::QString> {
388 static QString *create() { return new QString(QString::fromLatin1("QString")); }
390 template<> struct TestValueFactory<QMetaType::Int> {
391 static int *create() { return new int(0x12345678); }
393 template<> struct TestValueFactory<QMetaType::UInt> {
394 static uint *create() { return new uint(0x12345678); }
396 template<> struct TestValueFactory<QMetaType::Bool> {
397 static bool *create() { return new bool(true); }
399 template<> struct TestValueFactory<QMetaType::Double> {
400 static double *create() { return new double(3.14); }
402 template<> struct TestValueFactory<QMetaType::QByteArray> {
403 static QByteArray *create() { return new QByteArray(QByteArray("QByteArray")); }
405 template<> struct TestValueFactory<QMetaType::QChar> {
406 static QChar *create() { return new QChar(QChar('q')); }
408 template<> struct TestValueFactory<QMetaType::Long> {
409 static long *create() { return new long(0x12345678); }
411 template<> struct TestValueFactory<QMetaType::Short> {
412 static short *create() { return new short(0x1234); }
414 template<> struct TestValueFactory<QMetaType::Char> {
415 static char *create() { return new char('c'); }
417 template<> struct TestValueFactory<QMetaType::ULong> {
418 static ulong *create() { return new ulong(0x12345678); }
420 template<> struct TestValueFactory<QMetaType::UShort> {
421 static ushort *create() { return new ushort(0x1234); }
423 template<> struct TestValueFactory<QMetaType::UChar> {
424 static uchar *create() { return new uchar('u'); }
426 template<> struct TestValueFactory<QMetaType::Float> {
427 static float *create() { return new float(3.14); }
429 template<> struct TestValueFactory<QMetaType::QObjectStar> {
430 static QObject * *create() { return new QObject *(0); }
432 template<> struct TestValueFactory<QMetaType::QWidgetStar> {
433 static QWidget * *create() { return new QWidget *(0); }
435 template<> struct TestValueFactory<QMetaType::VoidStar> {
436 static void * *create() { return new void *(0); }
438 template<> struct TestValueFactory<QMetaType::LongLong> {
439 static qlonglong *create() { return new qlonglong(0x12345678); }
441 template<> struct TestValueFactory<QMetaType::ULongLong> {
442 static qulonglong *create() { return new qulonglong(0x12345678); }
444 template<> struct TestValueFactory<QMetaType::QStringList> {
445 static QStringList *create() { return new QStringList(QStringList() << "Q" << "t"); }
447 template<> struct TestValueFactory<QMetaType::QBitArray> {
448 static QBitArray *create() { return new QBitArray(QBitArray(256, true)); }
450 template<> struct TestValueFactory<QMetaType::QDate> {
451 static QDate *create() { return new QDate(QDate::currentDate()); }
453 template<> struct TestValueFactory<QMetaType::QTime> {
454 static QTime *create() { return new QTime(QTime::currentTime()); }
456 template<> struct TestValueFactory<QMetaType::QDateTime> {
457 static QDateTime *create() { return new QDateTime(QDateTime::currentDateTime()); }
459 template<> struct TestValueFactory<QMetaType::QUrl> {
460 static QUrl *create() { return new QUrl("http://www.example.org"); }
462 template<> struct TestValueFactory<QMetaType::QLocale> {
463 static QLocale *create() { return new QLocale(QLocale::c()); }
465 template<> struct TestValueFactory<QMetaType::QRect> {
466 static QRect *create() { return new QRect(10, 20, 30, 40); }
468 template<> struct TestValueFactory<QMetaType::QRectF> {
469 static QRectF *create() { return new QRectF(10, 20, 30, 40); }
471 template<> struct TestValueFactory<QMetaType::QSize> {
472 static QSize *create() { return new QSize(10, 20); }
474 template<> struct TestValueFactory<QMetaType::QSizeF> {
475 static QSizeF *create() { return new QSizeF(10, 20); }
477 template<> struct TestValueFactory<QMetaType::QLine> {
478 static QLine *create() { return new QLine(10, 20, 30, 40); }
480 template<> struct TestValueFactory<QMetaType::QLineF> {
481 static QLineF *create() { return new QLineF(10, 20, 30, 40); }
483 template<> struct TestValueFactory<QMetaType::QPoint> {
484 static QPoint *create() { return new QPoint(10, 20); }
486 template<> struct TestValueFactory<QMetaType::QPointF> {
487 static QPointF *create() { return new QPointF(10, 20); }
489 template<> struct TestValueFactory<QMetaType::QEasingCurve> {
490 static QEasingCurve *create() { return new QEasingCurve(QEasingCurve::InOutElastic); }
492 template<> struct TestValueFactory<QMetaType::QUuid> {
493 static QUuid *create() { return new QUuid(); }
495 template<> struct TestValueFactory<QMetaType::QModelIndex> {
496 static QModelIndex *create() { return new QModelIndex(); }
498 template<> struct TestValueFactory<QMetaType::QRegExp> {
499 static QRegExp *create()
502 return new QRegExp("A*");
508 template<> struct TestValueFactory<QMetaType::QVariant> {
509 static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
512 void tst_QMetaType::create_data()
514 QTest::addColumn<QMetaType::Type>("type");
515 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
516 QTest::newRow(QMetaType::typeName(QMetaType::MetaTypeName)) << QMetaType::MetaTypeName;
517 FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
518 #undef ADD_METATYPE_TEST_ROW
522 static void testCreateHelper()
524 typedef typename MetaEnumToType<ID>::Type Type;
526 void *actual1 = QMetaType::create(ID);
527 void *actual2 = info.create();
528 if (DefaultValueTraits<ID>::IsInitialized) {
529 Type *expected = DefaultValueFactory<ID>::create();
530 QCOMPARE(*static_cast<Type *>(actual1), *expected);
531 QCOMPARE(*static_cast<Type *>(actual2), *expected);
534 QMetaType::destroy(ID, actual1);
535 info.destroy(actual2);
539 void testCreateHelper<QMetaType::Void>()
541 typedef MetaEnumToType<QMetaType::Void>::Type Type;
542 void *actual = QMetaType::create(QMetaType::Void);
543 if (DefaultValueTraits<QMetaType::Void>::IsInitialized) {
544 QVERIFY(DefaultValueFactory<QMetaType::Void>::create());
546 QMetaType::destroy(QMetaType::Void, actual);
550 typedef void (*TypeTestFunction)();
552 void tst_QMetaType::create()
554 struct TypeTestFunctionGetter
556 static TypeTestFunction get(int type)
559 #define RETURN_CREATE_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
560 case QMetaType::MetaTypeName: \
561 return testCreateHelper<QMetaType::MetaTypeName>;
562 FOR_EACH_CORE_METATYPE(RETURN_CREATE_FUNCTION)
563 #undef RETURN_CREATE_FUNCTION
569 QFETCH(QMetaType::Type, type);
570 TypeTestFunctionGetter::get(type)();
574 static void testCreateCopyHelper()
576 typedef typename MetaEnumToType<ID>::Type Type;
577 Type *expected = TestValueFactory<ID>::create();
579 void *actual1 = QMetaType::create(ID, expected);
580 void *actual2 = info.create(expected);
581 QCOMPARE(*static_cast<Type *>(actual1), *expected);
582 QCOMPARE(*static_cast<Type *>(actual2), *expected);
583 QMetaType::destroy(ID, actual1);
584 info.destroy(actual2);
589 void testCreateCopyHelper<QMetaType::Void>()
591 typedef MetaEnumToType<QMetaType::Void>::Type Type;
592 Type *expected = TestValueFactory<QMetaType::Void>::create();
593 void *actual = QMetaType::create(QMetaType::Void, expected);
594 QCOMPARE(static_cast<Type *>(actual), expected);
595 QMetaType::destroy(QMetaType::Void, actual);
598 void tst_QMetaType::createCopy_data()
603 void tst_QMetaType::createCopy()
605 struct TypeTestFunctionGetter
607 static TypeTestFunction get(int type)
610 #define RETURN_CREATE_COPY_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
611 case QMetaType::MetaTypeName: \
612 return testCreateCopyHelper<QMetaType::MetaTypeName>;
613 FOR_EACH_CORE_METATYPE(RETURN_CREATE_COPY_FUNCTION)
614 #undef RETURN_CREATE_COPY_FUNCTION
620 QFETCH(QMetaType::Type, type);
621 TypeTestFunctionGetter::get(type)();
624 void tst_QMetaType::sizeOf_data()
626 QTest::addColumn<QMetaType::Type>("type");
627 QTest::addColumn<int>("size");
628 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
629 QTest::newRow(#RealType) << QMetaType::MetaTypeName << int(QTypeInfo<RealType>::sizeOf);
630 FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
631 #undef ADD_METATYPE_TEST_ROW
634 void tst_QMetaType::sizeOf()
636 QFETCH(QMetaType::Type, type);
638 QCOMPARE(QMetaType::sizeOf(type), size);
641 void tst_QMetaType::sizeOfStaticLess_data()
646 void tst_QMetaType::sizeOfStaticLess()
648 QFETCH(QMetaType::Type, type);
650 QCOMPARE(QMetaType(type).sizeOf(), size);
653 struct CustomMovable {};
655 Q_DECLARE_TYPEINFO(CustomMovable, Q_MOVABLE_TYPE);
657 Q_DECLARE_METATYPE(CustomMovable);
659 class CustomObject : public QObject
663 CustomObject(QObject *parent = 0)
669 Q_DECLARE_METATYPE(CustomObject*);
671 struct SecondBase {};
673 class CustomMultiInheritanceObject : public QObject, SecondBase
677 CustomMultiInheritanceObject(QObject *parent = 0)
683 Q_DECLARE_METATYPE(CustomMultiInheritanceObject*);
685 void tst_QMetaType::flags_data()
687 QTest::addColumn<int>("type");
688 QTest::addColumn<bool>("isMovable");
689 QTest::addColumn<bool>("isComplex");
690 QTest::addColumn<bool>("isPointerToQObject");
692 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
693 QTest::newRow(#RealType) << MetaTypeId << bool(!QTypeInfo<RealType>::isStatic) << bool(QTypeInfo<RealType>::isComplex) << bool(QtPrivate::IsPointerToTypeDerivedFromQObject<RealType>::Value);
694 QT_FOR_EACH_STATIC_CORE_CLASS(ADD_METATYPE_TEST_ROW)
695 QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(ADD_METATYPE_TEST_ROW)
696 QT_FOR_EACH_STATIC_CORE_POINTER(ADD_METATYPE_TEST_ROW)
697 #undef ADD_METATYPE_TEST_ROW
698 QTest::newRow("TestSpace::Foo") << ::qMetaTypeId<TestSpace::Foo>() << false << true << false;
699 QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << false << true << false;
700 QTest::newRow("CustomMovable") << ::qMetaTypeId<CustomMovable>() << true << true << false;
701 QTest::newRow("CustomObject*") << ::qMetaTypeId<CustomObject*>() << true << false << true;
702 QTest::newRow("CustomMultiInheritanceObject*") << ::qMetaTypeId<CustomMultiInheritanceObject*>() << true << false << true;
705 void tst_QMetaType::flags()
708 QFETCH(bool, isMovable);
709 QFETCH(bool, isComplex);
710 QFETCH(bool, isPointerToQObject);
712 QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsConstruction), isComplex);
713 QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsDestruction), isComplex);
714 QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::MovableType), isMovable);
715 QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::PointerToQObject), isPointerToQObject);
718 void tst_QMetaType::flagsStaticLess_data()
723 void tst_QMetaType::flagsStaticLess()
726 QFETCH(bool, isMovable);
727 QFETCH(bool, isComplex);
729 int flags = QMetaType(type).flags();
730 QCOMPARE(bool(flags & QMetaType::NeedsConstruction), isComplex);
731 QCOMPARE(bool(flags & QMetaType::NeedsDestruction), isComplex);
732 QCOMPARE(bool(flags & QMetaType::MovableType), isMovable);
735 void tst_QMetaType::construct_data()
742 struct RoundToNextHighestPowerOfTwo
746 enum { V2 = V1 | (V1 >> 1) };
747 enum { V3 = V2 | (V2 >> 2) };
748 enum { V4 = V3 | (V3 >> 4) };
749 enum { V5 = V4 | (V4 >> 8) };
750 enum { V6 = V5 | (V5 >> 16) };
752 enum { Value = V6 + 1 };
760 enum { Value = Q_ALIGNOF(T) };
762 enum { Value = RoundToNextHighestPowerOfTwo<sizeof(T)>::Value };
767 static void testConstructHelper()
769 typedef typename MetaEnumToType<ID>::Type Type;
771 int size = info.sizeOf();
772 void *storage1 = qMallocAligned(size, TypeAlignment<Type>::Value);
773 void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0);
774 void *storage2 = qMallocAligned(size, TypeAlignment<Type>::Value);
775 void *actual2 = info.construct(storage2, /*copy=*/0);
776 QCOMPARE(actual1, storage1);
777 QCOMPARE(actual2, storage2);
778 if (DefaultValueTraits<ID>::IsInitialized) {
779 Type *expected = DefaultValueFactory<ID>::create();
780 QCOMPARE(*static_cast<Type *>(actual1), *expected);
781 QCOMPARE(*static_cast<Type *>(actual2), *expected);
784 QMetaType::destruct(ID, actual1);
785 qFreeAligned(storage1);
786 info.destruct(actual2);
787 qFreeAligned(storage2);
789 QVERIFY(QMetaType::construct(ID, 0, /*copy=*/0) == 0);
790 QMetaType::destruct(ID, 0);
792 QVERIFY(info.construct(0, /*copy=*/0) == 0);
797 void testConstructHelper<QMetaType::Void>()
799 typedef MetaEnumToType<QMetaType::Void>::Type Type;
800 /*int size = */ QMetaType::sizeOf(QMetaType::Void);
802 void *actual = QMetaType::construct(QMetaType::Void, storage, /*copy=*/0);
803 QCOMPARE(actual, storage);
804 if (DefaultValueTraits<QMetaType::Void>::IsInitialized) {
805 /*Type *expected = */ DefaultValueFactory<QMetaType::Void>::create();
807 QMetaType::destruct(QMetaType::Void, actual);
808 qFreeAligned(storage);
810 QVERIFY(QMetaType::construct(QMetaType::Void, 0, /*copy=*/0) == 0);
811 QMetaType::destruct(QMetaType::Void, 0);
814 void tst_QMetaType::construct()
816 struct TypeTestFunctionGetter
818 static TypeTestFunction get(int type)
821 #define RETURN_CONSTRUCT_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
822 case QMetaType::MetaTypeName: \
823 return testConstructHelper<QMetaType::MetaTypeName>;
824 FOR_EACH_CORE_METATYPE(RETURN_CONSTRUCT_FUNCTION)
825 #undef RETURN_CONSTRUCT_FUNCTION
831 QFETCH(QMetaType::Type, type);
832 TypeTestFunctionGetter::get(type)();
836 static void testConstructCopyHelper()
838 typedef typename MetaEnumToType<ID>::Type Type;
839 Type *expected = TestValueFactory<ID>::create();
841 int size = QMetaType::sizeOf(ID);
842 QCOMPARE(info.sizeOf(), size);
843 void *storage1 = qMallocAligned(size, TypeAlignment<Type>::Value);
844 void *actual1 = QMetaType::construct(ID, storage1, expected);
845 void *storage2 = qMallocAligned(size, TypeAlignment<Type>::Value);
846 void *actual2 = info.construct(storage2, expected);
847 QCOMPARE(actual1, storage1);
848 QCOMPARE(actual2, storage2);
849 QCOMPARE(*static_cast<Type *>(actual1), *expected);
850 QCOMPARE(*static_cast<Type *>(actual2), *expected);
851 QMetaType::destruct(ID, actual1);
852 qFreeAligned(storage1);
853 info.destruct(actual2);
854 qFreeAligned(storage2);
856 QVERIFY(QMetaType::construct(ID, 0, expected) == 0);
857 QVERIFY(info.construct(0, expected) == 0);
863 void testConstructCopyHelper<QMetaType::Void>()
865 typedef MetaEnumToType<QMetaType::Void>::Type Type;
866 Type *expected = TestValueFactory<QMetaType::Void>::create();
867 /* int size = */QMetaType::sizeOf(QMetaType::Void);
869 void *actual = QMetaType::construct(QMetaType::Void, storage, expected);
870 QCOMPARE(actual, storage);
871 QMetaType::destruct(QMetaType::Void, actual);
872 qFreeAligned(storage);
874 QVERIFY(QMetaType::construct(QMetaType::Void, 0, expected) == 0);
877 void tst_QMetaType::constructCopy_data()
882 void tst_QMetaType::constructCopy()
884 struct TypeTestFunctionGetter
886 static TypeTestFunction get(int type)
889 #define RETURN_CONSTRUCT_COPY_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
890 case QMetaType::MetaTypeName: \
891 return testConstructCopyHelper<QMetaType::MetaTypeName>;
892 FOR_EACH_CORE_METATYPE(RETURN_CONSTRUCT_COPY_FUNCTION)
893 #undef RETURN_CONSTRUCT_COPY_FUNCTION
899 QFETCH(QMetaType::Type, type);
900 TypeTestFunctionGetter::get(type)();
903 typedef QString CustomString;
904 Q_DECLARE_METATYPE(CustomString) //this line is useless
906 void tst_QMetaType::typedefs()
908 QCOMPARE(QMetaType::type("long long"), int(QMetaType::LongLong));
909 QCOMPARE(QMetaType::type("unsigned long long"), int(QMetaType::ULongLong));
910 QCOMPARE(QMetaType::type("qint8"), int(QMetaType::Char));
911 QCOMPARE(QMetaType::type("quint8"), int(QMetaType::UChar));
912 QCOMPARE(QMetaType::type("qint16"), int(QMetaType::Short));
913 QCOMPARE(QMetaType::type("quint16"), int(QMetaType::UShort));
914 QCOMPARE(QMetaType::type("qint32"), int(QMetaType::Int));
915 QCOMPARE(QMetaType::type("quint32"), int(QMetaType::UInt));
916 QCOMPARE(QMetaType::type("qint64"), int(QMetaType::LongLong));
917 QCOMPARE(QMetaType::type("quint64"), int(QMetaType::ULongLong));
919 // make sure the qreal typeId is the type id of the type it's defined to
920 QCOMPARE(QMetaType::type("qreal"), ::qMetaTypeId<qreal>());
922 qRegisterMetaType<CustomString>("CustomString");
923 QCOMPARE(QMetaType::type("CustomString"), ::qMetaTypeId<CustomString>());
925 typedef Whity<double> WhityDouble;
926 qRegisterMetaType<WhityDouble>("WhityDouble");
927 QCOMPARE(QMetaType::type("WhityDouble"), ::qMetaTypeId<WhityDouble>());
930 void tst_QMetaType::registerType()
933 QCOMPARE(qRegisterMetaType<QString>("QString"), int(QMetaType::QString));
934 QCOMPARE(qRegisterMetaType<QString>("QString"), int(QMetaType::QString));
937 int fooId = qRegisterMetaType<TestSpace::Foo>("TestSpace::Foo");
938 QVERIFY(fooId >= int(QMetaType::User));
939 QCOMPARE(qRegisterMetaType<TestSpace::Foo>("TestSpace::Foo"), fooId);
941 int movableId = qRegisterMetaType<CustomMovable>("CustomMovable");
942 QVERIFY(movableId >= int(QMetaType::User));
943 QCOMPARE(qRegisterMetaType<CustomMovable>("CustomMovable"), movableId);
946 typedef QString MyString;
948 QCOMPARE(qRegisterMetaType<MyString>("MyString"), int(QMetaType::QString));
949 QCOMPARE(qRegisterMetaType<MyString>("MyString"), int(QMetaType::QString));
951 QCOMPARE(QMetaType::type("MyString"), int(QMetaType::QString));
953 // Alias to custom type
954 typedef CustomMovable MyMovable;
955 typedef TestSpace::Foo MyFoo;
957 QCOMPARE(qRegisterMetaType<MyMovable>("MyMovable"), movableId);
958 QCOMPARE(qRegisterMetaType<MyMovable>("MyMovable"), movableId);
960 QCOMPARE(QMetaType::type("MyMovable"), movableId);
962 QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId);
963 QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId);
965 QCOMPARE(QMetaType::type("MyFoo"), fooId);
968 class IsRegisteredDummyType { };
970 void tst_QMetaType::isRegistered_data()
972 QTest::addColumn<int>("typeId");
973 QTest::addColumn<bool>("registered");
975 // predefined/custom types
976 QTest::newRow("QMetaType::Void") << int(QMetaType::Void) << true;
977 QTest::newRow("QMetaType::Int") << int(QMetaType::Int) << true;
979 int dummyTypeId = qRegisterMetaType<IsRegisteredDummyType>("IsRegisteredDummyType");
981 QTest::newRow("IsRegisteredDummyType") << dummyTypeId << true;
984 QTest::newRow("-1") << -1 << false;
985 QTest::newRow("-42") << -42 << false;
986 QTest::newRow("IsRegisteredDummyType + 1") << (dummyTypeId + 1) << false;
989 void tst_QMetaType::isRegistered()
992 QFETCH(bool, registered);
993 QCOMPARE(QMetaType::isRegistered(typeId), registered);
996 void tst_QMetaType::isRegisteredStaticLess_data()
1001 void tst_QMetaType::isRegisteredStaticLess()
1003 QFETCH(int, typeId);
1004 QFETCH(bool, registered);
1005 QCOMPARE(QMetaType(typeId).isRegistered(), registered);
1008 void tst_QMetaType::registerStreamBuiltin()
1011 qRegisterMetaTypeStreamOperators<QString>("QString");
1012 qRegisterMetaTypeStreamOperators<QVariant>("QVariant");
1015 Q_DECLARE_METATYPE(QSharedPointer<QObject>)
1017 void tst_QMetaType::automaticTemplateRegistration()
1022 QVERIFY(QVariant::fromValue(intList).value<QList<int> >().first() == 42);
1023 QVector<QList<int> > vectorList;
1024 vectorList << intList;
1025 QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<int> > >().first().first() == 42);
1029 QList<QByteArray> bytearrayList;
1030 bytearrayList << QByteArray("foo");
1031 QVERIFY(QVariant::fromValue(bytearrayList).value<QList<QByteArray> >().first() == QByteArray("foo"));
1032 QVector<QList<QByteArray> > vectorList;
1033 vectorList << bytearrayList;
1034 QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QByteArray> > >().first().first() == QByteArray("foo"));
1037 QCOMPARE(::qMetaTypeId<QVariantList>(), (int)QMetaType::QVariantList);
1038 QCOMPARE(::qMetaTypeId<QList<QVariant> >(), (int)QMetaType::QVariantList);
1041 QList<QVariant> variantList;
1043 QVERIFY(QVariant::fromValue(variantList).value<QList<QVariant> >().first() == 42);
1044 QVector<QList<QVariant> > vectorList;
1045 vectorList << variantList;
1046 QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QVariant> > >().first().first() == 42);
1050 QList<QSharedPointer<QObject> > sharedPointerList;
1051 QObject *testObject = new QObject;
1052 sharedPointerList << QSharedPointer<QObject>(testObject);
1053 QVERIFY(QVariant::fromValue(sharedPointerList).value<QList<QSharedPointer<QObject> > >().first() == testObject);
1054 QVector<QList<QSharedPointer<QObject> > > vectorList;
1055 vectorList << sharedPointerList;
1056 QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QSharedPointer<QObject> > > >().first().first() == testObject);
1060 // Compile-time test, it should be possible to register function pointer types
1063 typedef Undefined (*UndefinedFunction0)();
1064 typedef Undefined (*UndefinedFunction1)(Undefined);
1065 typedef Undefined (*UndefinedFunction2)(Undefined, Undefined);
1066 typedef Undefined (*UndefinedFunction3)(Undefined, Undefined, Undefined);
1068 Q_DECLARE_METATYPE(UndefinedFunction0);
1069 Q_DECLARE_METATYPE(UndefinedFunction1);
1070 Q_DECLARE_METATYPE(UndefinedFunction2);
1071 Q_DECLARE_METATYPE(UndefinedFunction3);
1073 QTEST_MAIN(tst_QMetaType)
1074 #include "tst_qmetatype.moc"