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)
318 QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << static_cast<const char*>(0);
321 void tst_QMetaType::typeName()
323 QFETCH(QMetaType::Type, aType);
324 QFETCH(QString, aTypeName);
326 QCOMPARE(QString::fromLatin1(QMetaType::typeName(aType)), aTypeName);
329 #define FOR_EACH_PRIMITIVE_METATYPE(F) \
330 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
331 QT_FOR_EACH_STATIC_CORE_POINTER(F) \
333 #define FOR_EACH_COMPLEX_CORE_METATYPE(F) \
334 QT_FOR_EACH_STATIC_CORE_CLASS(F)
336 #define FOR_EACH_CORE_METATYPE(F) \
337 FOR_EACH_PRIMITIVE_METATYPE(F) \
338 FOR_EACH_COMPLEX_CORE_METATYPE(F) \
341 struct MetaEnumToType {};
343 #define DEFINE_META_ENUM_TO_TYPE(MetaTypeName, MetaTypeId, RealType) \
345 struct MetaEnumToType<QMetaType::MetaTypeName> { \
346 typedef RealType Type; \
348 FOR_EACH_CORE_METATYPE(DEFINE_META_ENUM_TO_TYPE)
349 #undef DEFINE_META_ENUM_TO_TYPE
352 struct DefaultValueFactory
354 typedef typename MetaEnumToType<ID>::Type Type;
355 static Type *create() { return new Type; }
359 struct DefaultValueFactory<QMetaType::Void>
361 typedef MetaEnumToType<QMetaType::Void>::Type Type;
362 static Type *create() { return 0; }
366 struct DefaultValueTraits
368 // By default we assume that a default-constructed value (new T) is
369 // initialized; e.g. QCOMPARE(*(new T), *(new T)) should succeed
370 enum { IsInitialized = true };
373 #define DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS(MetaTypeName, MetaTypeId, RealType) \
374 template<> struct DefaultValueTraits<QMetaType::MetaTypeName> { \
375 enum { IsInitialized = false }; \
377 // Primitive types (int et al) aren't initialized
378 FOR_EACH_PRIMITIVE_METATYPE(DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS)
379 #undef DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS
382 struct TestValueFactory {};
384 template<> struct TestValueFactory<QMetaType::Void> {
385 static void *create() { return 0; }
388 template<> struct TestValueFactory<QMetaType::QString> {
389 static QString *create() { return new QString(QString::fromLatin1("QString")); }
391 template<> struct TestValueFactory<QMetaType::Int> {
392 static int *create() { return new int(0x12345678); }
394 template<> struct TestValueFactory<QMetaType::UInt> {
395 static uint *create() { return new uint(0x12345678); }
397 template<> struct TestValueFactory<QMetaType::Bool> {
398 static bool *create() { return new bool(true); }
400 template<> struct TestValueFactory<QMetaType::Double> {
401 static double *create() { return new double(3.14); }
403 template<> struct TestValueFactory<QMetaType::QByteArray> {
404 static QByteArray *create() { return new QByteArray(QByteArray("QByteArray")); }
406 template<> struct TestValueFactory<QMetaType::QChar> {
407 static QChar *create() { return new QChar(QChar('q')); }
409 template<> struct TestValueFactory<QMetaType::Long> {
410 static long *create() { return new long(0x12345678); }
412 template<> struct TestValueFactory<QMetaType::Short> {
413 static short *create() { return new short(0x1234); }
415 template<> struct TestValueFactory<QMetaType::Char> {
416 static char *create() { return new char('c'); }
418 template<> struct TestValueFactory<QMetaType::ULong> {
419 static ulong *create() { return new ulong(0x12345678); }
421 template<> struct TestValueFactory<QMetaType::UShort> {
422 static ushort *create() { return new ushort(0x1234); }
424 template<> struct TestValueFactory<QMetaType::UChar> {
425 static uchar *create() { return new uchar('u'); }
427 template<> struct TestValueFactory<QMetaType::Float> {
428 static float *create() { return new float(3.14); }
430 template<> struct TestValueFactory<QMetaType::QObjectStar> {
431 static QObject * *create() { return new QObject *(0); }
433 template<> struct TestValueFactory<QMetaType::QWidgetStar> {
434 static QWidget * *create() { return new QWidget *(0); }
436 template<> struct TestValueFactory<QMetaType::VoidStar> {
437 static void * *create() { return new void *(0); }
439 template<> struct TestValueFactory<QMetaType::LongLong> {
440 static qlonglong *create() { return new qlonglong(0x12345678); }
442 template<> struct TestValueFactory<QMetaType::ULongLong> {
443 static qulonglong *create() { return new qulonglong(0x12345678); }
445 template<> struct TestValueFactory<QMetaType::QStringList> {
446 static QStringList *create() { return new QStringList(QStringList() << "Q" << "t"); }
448 template<> struct TestValueFactory<QMetaType::QBitArray> {
449 static QBitArray *create() { return new QBitArray(QBitArray(256, true)); }
451 template<> struct TestValueFactory<QMetaType::QDate> {
452 static QDate *create() { return new QDate(QDate::currentDate()); }
454 template<> struct TestValueFactory<QMetaType::QTime> {
455 static QTime *create() { return new QTime(QTime::currentTime()); }
457 template<> struct TestValueFactory<QMetaType::QDateTime> {
458 static QDateTime *create() { return new QDateTime(QDateTime::currentDateTime()); }
460 template<> struct TestValueFactory<QMetaType::QUrl> {
461 static QUrl *create() { return new QUrl("http://www.example.org"); }
463 template<> struct TestValueFactory<QMetaType::QLocale> {
464 static QLocale *create() { return new QLocale(QLocale::c()); }
466 template<> struct TestValueFactory<QMetaType::QRect> {
467 static QRect *create() { return new QRect(10, 20, 30, 40); }
469 template<> struct TestValueFactory<QMetaType::QRectF> {
470 static QRectF *create() { return new QRectF(10, 20, 30, 40); }
472 template<> struct TestValueFactory<QMetaType::QSize> {
473 static QSize *create() { return new QSize(10, 20); }
475 template<> struct TestValueFactory<QMetaType::QSizeF> {
476 static QSizeF *create() { return new QSizeF(10, 20); }
478 template<> struct TestValueFactory<QMetaType::QLine> {
479 static QLine *create() { return new QLine(10, 20, 30, 40); }
481 template<> struct TestValueFactory<QMetaType::QLineF> {
482 static QLineF *create() { return new QLineF(10, 20, 30, 40); }
484 template<> struct TestValueFactory<QMetaType::QPoint> {
485 static QPoint *create() { return new QPoint(10, 20); }
487 template<> struct TestValueFactory<QMetaType::QPointF> {
488 static QPointF *create() { return new QPointF(10, 20); }
490 template<> struct TestValueFactory<QMetaType::QEasingCurve> {
491 static QEasingCurve *create() { return new QEasingCurve(QEasingCurve::InOutElastic); }
493 template<> struct TestValueFactory<QMetaType::QUuid> {
494 static QUuid *create() { return new QUuid(); }
496 template<> struct TestValueFactory<QMetaType::QModelIndex> {
497 static QModelIndex *create() { return new QModelIndex(); }
499 template<> struct TestValueFactory<QMetaType::QRegExp> {
500 static QRegExp *create()
503 return new QRegExp("A*");
509 template<> struct TestValueFactory<QMetaType::QVariant> {
510 static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
513 void tst_QMetaType::create_data()
515 QTest::addColumn<QMetaType::Type>("type");
516 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
517 QTest::newRow(QMetaType::typeName(QMetaType::MetaTypeName)) << QMetaType::MetaTypeName;
518 FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
519 #undef ADD_METATYPE_TEST_ROW
523 static void testCreateHelper()
525 typedef typename MetaEnumToType<ID>::Type Type;
527 void *actual1 = QMetaType::create(ID);
528 void *actual2 = info.create();
529 if (DefaultValueTraits<ID>::IsInitialized) {
530 Type *expected = DefaultValueFactory<ID>::create();
531 QCOMPARE(*static_cast<Type *>(actual1), *expected);
532 QCOMPARE(*static_cast<Type *>(actual2), *expected);
535 QMetaType::destroy(ID, actual1);
536 info.destroy(actual2);
540 void testCreateHelper<QMetaType::Void>()
542 typedef MetaEnumToType<QMetaType::Void>::Type Type;
543 void *actual = QMetaType::create(QMetaType::Void);
544 if (DefaultValueTraits<QMetaType::Void>::IsInitialized) {
545 QVERIFY(DefaultValueFactory<QMetaType::Void>::create());
547 QMetaType::destroy(QMetaType::Void, actual);
551 typedef void (*TypeTestFunction)();
553 void tst_QMetaType::create()
555 struct TypeTestFunctionGetter
557 static TypeTestFunction get(int type)
560 #define RETURN_CREATE_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
561 case QMetaType::MetaTypeName: \
562 return testCreateHelper<QMetaType::MetaTypeName>;
563 FOR_EACH_CORE_METATYPE(RETURN_CREATE_FUNCTION)
564 #undef RETURN_CREATE_FUNCTION
570 QFETCH(QMetaType::Type, type);
571 TypeTestFunctionGetter::get(type)();
575 static void testCreateCopyHelper()
577 typedef typename MetaEnumToType<ID>::Type Type;
578 Type *expected = TestValueFactory<ID>::create();
580 void *actual1 = QMetaType::create(ID, expected);
581 void *actual2 = info.create(expected);
582 QCOMPARE(*static_cast<Type *>(actual1), *expected);
583 QCOMPARE(*static_cast<Type *>(actual2), *expected);
584 QMetaType::destroy(ID, actual1);
585 info.destroy(actual2);
590 void testCreateCopyHelper<QMetaType::Void>()
592 typedef MetaEnumToType<QMetaType::Void>::Type Type;
593 Type *expected = TestValueFactory<QMetaType::Void>::create();
594 void *actual = QMetaType::create(QMetaType::Void, expected);
595 QCOMPARE(static_cast<Type *>(actual), expected);
596 QMetaType::destroy(QMetaType::Void, actual);
599 void tst_QMetaType::createCopy_data()
604 void tst_QMetaType::createCopy()
606 struct TypeTestFunctionGetter
608 static TypeTestFunction get(int type)
611 #define RETURN_CREATE_COPY_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
612 case QMetaType::MetaTypeName: \
613 return testCreateCopyHelper<QMetaType::MetaTypeName>;
614 FOR_EACH_CORE_METATYPE(RETURN_CREATE_COPY_FUNCTION)
615 #undef RETURN_CREATE_COPY_FUNCTION
621 QFETCH(QMetaType::Type, type);
622 TypeTestFunctionGetter::get(type)();
625 void tst_QMetaType::sizeOf_data()
627 QTest::addColumn<QMetaType::Type>("type");
628 QTest::addColumn<int>("size");
630 QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << 0;
631 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
632 QTest::newRow(#RealType) << QMetaType::MetaTypeName << int(QTypeInfo<RealType>::sizeOf);
633 FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
634 #undef ADD_METATYPE_TEST_ROW
637 void tst_QMetaType::sizeOf()
639 QFETCH(QMetaType::Type, type);
641 QCOMPARE(QMetaType::sizeOf(type), size);
644 void tst_QMetaType::sizeOfStaticLess_data()
649 void tst_QMetaType::sizeOfStaticLess()
651 QFETCH(QMetaType::Type, type);
653 QCOMPARE(QMetaType(type).sizeOf(), size);
656 struct CustomMovable {};
658 Q_DECLARE_TYPEINFO(CustomMovable, Q_MOVABLE_TYPE);
660 Q_DECLARE_METATYPE(CustomMovable);
662 class CustomObject : public QObject
666 CustomObject(QObject *parent = 0)
672 Q_DECLARE_METATYPE(CustomObject*);
674 struct SecondBase {};
676 class CustomMultiInheritanceObject : public QObject, SecondBase
680 CustomMultiInheritanceObject(QObject *parent = 0)
686 Q_DECLARE_METATYPE(CustomMultiInheritanceObject*);
688 void tst_QMetaType::flags_data()
690 QTest::addColumn<int>("type");
691 QTest::addColumn<bool>("isMovable");
692 QTest::addColumn<bool>("isComplex");
693 QTest::addColumn<bool>("isPointerToQObject");
695 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
696 QTest::newRow(#RealType) << MetaTypeId << bool(!QTypeInfo<RealType>::isStatic) << bool(QTypeInfo<RealType>::isComplex) << bool(QtPrivate::IsPointerToTypeDerivedFromQObject<RealType>::Value);
697 QT_FOR_EACH_STATIC_CORE_CLASS(ADD_METATYPE_TEST_ROW)
698 QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(ADD_METATYPE_TEST_ROW)
699 QT_FOR_EACH_STATIC_CORE_POINTER(ADD_METATYPE_TEST_ROW)
700 #undef ADD_METATYPE_TEST_ROW
701 QTest::newRow("TestSpace::Foo") << ::qMetaTypeId<TestSpace::Foo>() << false << true << false;
702 QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << false << true << false;
703 QTest::newRow("CustomMovable") << ::qMetaTypeId<CustomMovable>() << true << true << false;
704 QTest::newRow("CustomObject*") << ::qMetaTypeId<CustomObject*>() << true << false << true;
705 QTest::newRow("CustomMultiInheritanceObject*") << ::qMetaTypeId<CustomMultiInheritanceObject*>() << true << false << true;
708 void tst_QMetaType::flags()
711 QFETCH(bool, isMovable);
712 QFETCH(bool, isComplex);
713 QFETCH(bool, isPointerToQObject);
715 QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsConstruction), isComplex);
716 QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsDestruction), isComplex);
717 QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::MovableType), isMovable);
718 QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::PointerToQObject), isPointerToQObject);
721 void tst_QMetaType::flagsStaticLess_data()
726 void tst_QMetaType::flagsStaticLess()
729 QFETCH(bool, isMovable);
730 QFETCH(bool, isComplex);
732 int flags = QMetaType(type).flags();
733 QCOMPARE(bool(flags & QMetaType::NeedsConstruction), isComplex);
734 QCOMPARE(bool(flags & QMetaType::NeedsDestruction), isComplex);
735 QCOMPARE(bool(flags & QMetaType::MovableType), isMovable);
738 void tst_QMetaType::construct_data()
745 struct RoundToNextHighestPowerOfTwo
749 enum { V2 = V1 | (V1 >> 1) };
750 enum { V3 = V2 | (V2 >> 2) };
751 enum { V4 = V3 | (V3 >> 4) };
752 enum { V5 = V4 | (V4 >> 8) };
753 enum { V6 = V5 | (V5 >> 16) };
755 enum { Value = V6 + 1 };
763 enum { Value = Q_ALIGNOF(T) };
765 enum { Value = RoundToNextHighestPowerOfTwo<sizeof(T)>::Value };
770 static void testConstructHelper()
772 typedef typename MetaEnumToType<ID>::Type Type;
774 int size = info.sizeOf();
775 void *storage1 = qMallocAligned(size, TypeAlignment<Type>::Value);
776 void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0);
777 void *storage2 = qMallocAligned(size, TypeAlignment<Type>::Value);
778 void *actual2 = info.construct(storage2, /*copy=*/0);
779 QCOMPARE(actual1, storage1);
780 QCOMPARE(actual2, storage2);
781 if (DefaultValueTraits<ID>::IsInitialized) {
782 Type *expected = DefaultValueFactory<ID>::create();
783 QCOMPARE(*static_cast<Type *>(actual1), *expected);
784 QCOMPARE(*static_cast<Type *>(actual2), *expected);
787 QMetaType::destruct(ID, actual1);
788 qFreeAligned(storage1);
789 info.destruct(actual2);
790 qFreeAligned(storage2);
792 QVERIFY(QMetaType::construct(ID, 0, /*copy=*/0) == 0);
793 QMetaType::destruct(ID, 0);
795 QVERIFY(info.construct(0, /*copy=*/0) == 0);
800 void testConstructHelper<QMetaType::Void>()
802 typedef MetaEnumToType<QMetaType::Void>::Type Type;
803 /*int size = */ QMetaType::sizeOf(QMetaType::Void);
805 void *actual = QMetaType::construct(QMetaType::Void, storage, /*copy=*/0);
806 QCOMPARE(actual, storage);
807 if (DefaultValueTraits<QMetaType::Void>::IsInitialized) {
808 /*Type *expected = */ DefaultValueFactory<QMetaType::Void>::create();
810 QMetaType::destruct(QMetaType::Void, actual);
811 qFreeAligned(storage);
813 QVERIFY(QMetaType::construct(QMetaType::Void, 0, /*copy=*/0) == 0);
814 QMetaType::destruct(QMetaType::Void, 0);
817 void tst_QMetaType::construct()
819 struct TypeTestFunctionGetter
821 static TypeTestFunction get(int type)
824 #define RETURN_CONSTRUCT_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
825 case QMetaType::MetaTypeName: \
826 return testConstructHelper<QMetaType::MetaTypeName>;
827 FOR_EACH_CORE_METATYPE(RETURN_CONSTRUCT_FUNCTION)
828 #undef RETURN_CONSTRUCT_FUNCTION
834 QFETCH(QMetaType::Type, type);
835 TypeTestFunctionGetter::get(type)();
839 static void testConstructCopyHelper()
841 typedef typename MetaEnumToType<ID>::Type Type;
842 Type *expected = TestValueFactory<ID>::create();
844 int size = QMetaType::sizeOf(ID);
845 QCOMPARE(info.sizeOf(), size);
846 void *storage1 = qMallocAligned(size, TypeAlignment<Type>::Value);
847 void *actual1 = QMetaType::construct(ID, storage1, expected);
848 void *storage2 = qMallocAligned(size, TypeAlignment<Type>::Value);
849 void *actual2 = info.construct(storage2, expected);
850 QCOMPARE(actual1, storage1);
851 QCOMPARE(actual2, storage2);
852 QCOMPARE(*static_cast<Type *>(actual1), *expected);
853 QCOMPARE(*static_cast<Type *>(actual2), *expected);
854 QMetaType::destruct(ID, actual1);
855 qFreeAligned(storage1);
856 info.destruct(actual2);
857 qFreeAligned(storage2);
859 QVERIFY(QMetaType::construct(ID, 0, expected) == 0);
860 QVERIFY(info.construct(0, expected) == 0);
866 void testConstructCopyHelper<QMetaType::Void>()
868 typedef MetaEnumToType<QMetaType::Void>::Type Type;
869 Type *expected = TestValueFactory<QMetaType::Void>::create();
870 /* int size = */QMetaType::sizeOf(QMetaType::Void);
872 void *actual = QMetaType::construct(QMetaType::Void, storage, expected);
873 QCOMPARE(actual, storage);
874 QMetaType::destruct(QMetaType::Void, actual);
875 qFreeAligned(storage);
877 QVERIFY(QMetaType::construct(QMetaType::Void, 0, expected) == 0);
880 void tst_QMetaType::constructCopy_data()
885 void tst_QMetaType::constructCopy()
887 struct TypeTestFunctionGetter
889 static TypeTestFunction get(int type)
892 #define RETURN_CONSTRUCT_COPY_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
893 case QMetaType::MetaTypeName: \
894 return testConstructCopyHelper<QMetaType::MetaTypeName>;
895 FOR_EACH_CORE_METATYPE(RETURN_CONSTRUCT_COPY_FUNCTION)
896 #undef RETURN_CONSTRUCT_COPY_FUNCTION
902 QFETCH(QMetaType::Type, type);
903 TypeTestFunctionGetter::get(type)();
906 typedef QString CustomString;
907 Q_DECLARE_METATYPE(CustomString) //this line is useless
909 void tst_QMetaType::typedefs()
911 QCOMPARE(QMetaType::type("long long"), int(QMetaType::LongLong));
912 QCOMPARE(QMetaType::type("unsigned long long"), int(QMetaType::ULongLong));
913 QCOMPARE(QMetaType::type("qint8"), int(QMetaType::Char));
914 QCOMPARE(QMetaType::type("quint8"), int(QMetaType::UChar));
915 QCOMPARE(QMetaType::type("qint16"), int(QMetaType::Short));
916 QCOMPARE(QMetaType::type("quint16"), int(QMetaType::UShort));
917 QCOMPARE(QMetaType::type("qint32"), int(QMetaType::Int));
918 QCOMPARE(QMetaType::type("quint32"), int(QMetaType::UInt));
919 QCOMPARE(QMetaType::type("qint64"), int(QMetaType::LongLong));
920 QCOMPARE(QMetaType::type("quint64"), int(QMetaType::ULongLong));
922 // make sure the qreal typeId is the type id of the type it's defined to
923 QCOMPARE(QMetaType::type("qreal"), ::qMetaTypeId<qreal>());
925 qRegisterMetaType<CustomString>("CustomString");
926 QCOMPARE(QMetaType::type("CustomString"), ::qMetaTypeId<CustomString>());
928 typedef Whity<double> WhityDouble;
929 qRegisterMetaType<WhityDouble>("WhityDouble");
930 QCOMPARE(QMetaType::type("WhityDouble"), ::qMetaTypeId<WhityDouble>());
933 void tst_QMetaType::registerType()
936 QCOMPARE(qRegisterMetaType<QString>("QString"), int(QMetaType::QString));
937 QCOMPARE(qRegisterMetaType<QString>("QString"), int(QMetaType::QString));
940 int fooId = qRegisterMetaType<TestSpace::Foo>("TestSpace::Foo");
941 QVERIFY(fooId >= int(QMetaType::User));
942 QCOMPARE(qRegisterMetaType<TestSpace::Foo>("TestSpace::Foo"), fooId);
944 int movableId = qRegisterMetaType<CustomMovable>("CustomMovable");
945 QVERIFY(movableId >= int(QMetaType::User));
946 QCOMPARE(qRegisterMetaType<CustomMovable>("CustomMovable"), movableId);
949 typedef QString MyString;
951 QCOMPARE(qRegisterMetaType<MyString>("MyString"), int(QMetaType::QString));
952 QCOMPARE(qRegisterMetaType<MyString>("MyString"), int(QMetaType::QString));
954 QCOMPARE(QMetaType::type("MyString"), int(QMetaType::QString));
956 // Alias to custom type
957 typedef CustomMovable MyMovable;
958 typedef TestSpace::Foo MyFoo;
960 QCOMPARE(qRegisterMetaType<MyMovable>("MyMovable"), movableId);
961 QCOMPARE(qRegisterMetaType<MyMovable>("MyMovable"), movableId);
963 QCOMPARE(QMetaType::type("MyMovable"), movableId);
965 QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId);
966 QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId);
968 QCOMPARE(QMetaType::type("MyFoo"), fooId);
971 class IsRegisteredDummyType { };
973 void tst_QMetaType::isRegistered_data()
975 QTest::addColumn<int>("typeId");
976 QTest::addColumn<bool>("registered");
978 // predefined/custom types
979 QTest::newRow("QMetaType::Void") << int(QMetaType::Void) << true;
980 QTest::newRow("QMetaType::Int") << int(QMetaType::Int) << true;
982 int dummyTypeId = qRegisterMetaType<IsRegisteredDummyType>("IsRegisteredDummyType");
984 QTest::newRow("IsRegisteredDummyType") << dummyTypeId << true;
987 QTest::newRow("-1") << -1 << false;
988 QTest::newRow("-42") << -42 << false;
989 QTest::newRow("IsRegisteredDummyType + 1") << (dummyTypeId + 1) << false;
990 QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << false;
993 void tst_QMetaType::isRegistered()
996 QFETCH(bool, registered);
997 QCOMPARE(QMetaType::isRegistered(typeId), registered);
1000 void tst_QMetaType::isRegisteredStaticLess_data()
1002 isRegistered_data();
1005 void tst_QMetaType::isRegisteredStaticLess()
1007 QFETCH(int, typeId);
1008 QFETCH(bool, registered);
1009 QCOMPARE(QMetaType(typeId).isRegistered(), registered);
1012 void tst_QMetaType::registerStreamBuiltin()
1015 qRegisterMetaTypeStreamOperators<QString>("QString");
1016 qRegisterMetaTypeStreamOperators<QVariant>("QVariant");
1019 Q_DECLARE_METATYPE(QSharedPointer<QObject>)
1021 void tst_QMetaType::automaticTemplateRegistration()
1026 QVERIFY(QVariant::fromValue(intList).value<QList<int> >().first() == 42);
1027 QVector<QList<int> > vectorList;
1028 vectorList << intList;
1029 QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<int> > >().first().first() == 42);
1033 QList<QByteArray> bytearrayList;
1034 bytearrayList << QByteArray("foo");
1035 QVERIFY(QVariant::fromValue(bytearrayList).value<QList<QByteArray> >().first() == QByteArray("foo"));
1036 QVector<QList<QByteArray> > vectorList;
1037 vectorList << bytearrayList;
1038 QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QByteArray> > >().first().first() == QByteArray("foo"));
1041 QCOMPARE(::qMetaTypeId<QVariantList>(), (int)QMetaType::QVariantList);
1042 QCOMPARE(::qMetaTypeId<QList<QVariant> >(), (int)QMetaType::QVariantList);
1045 QList<QVariant> variantList;
1047 QVERIFY(QVariant::fromValue(variantList).value<QList<QVariant> >().first() == 42);
1048 QVector<QList<QVariant> > vectorList;
1049 vectorList << variantList;
1050 QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QVariant> > >().first().first() == 42);
1054 QList<QSharedPointer<QObject> > sharedPointerList;
1055 QObject *testObject = new QObject;
1056 sharedPointerList << QSharedPointer<QObject>(testObject);
1057 QVERIFY(QVariant::fromValue(sharedPointerList).value<QList<QSharedPointer<QObject> > >().first() == testObject);
1058 QVector<QList<QSharedPointer<QObject> > > vectorList;
1059 vectorList << sharedPointerList;
1060 QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QSharedPointer<QObject> > > >().first().first() == testObject);
1064 // Compile-time test, it should be possible to register function pointer types
1067 typedef Undefined (*UndefinedFunction0)();
1068 typedef Undefined (*UndefinedFunction1)(Undefined);
1069 typedef Undefined (*UndefinedFunction2)(Undefined, Undefined);
1070 typedef Undefined (*UndefinedFunction3)(Undefined, Undefined, Undefined);
1072 Q_DECLARE_METATYPE(UndefinedFunction0);
1073 Q_DECLARE_METATYPE(UndefinedFunction1);
1074 Q_DECLARE_METATYPE(UndefinedFunction2);
1075 Q_DECLARE_METATYPE(UndefinedFunction3);
1077 QTEST_MAIN(tst_QMetaType)
1078 #include "tst_qmetatype.moc"