QtBase  v6.3.1
tst_qmetatype.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #include "tst_qmetatype.h"
30 
31 #include <QtCore/private/qmetaobjectbuilder_p.h>
32 
33 #ifdef Q_OS_LINUX
34 # include <pthread.h>
35 #endif
36 
37 #include <algorithm>
38 #include <memory>
39 #include <vector>
40 
43 
44 namespace CheckTypeTraits
45 {
47 {
48  int x;
49 };
52 
53 // basic types
54 static_assert(QTypeTraits::has_operator_equal_v<bool>);
55 static_assert(QTypeTraits::has_operator_less_than_v<bool>);
56 static_assert(QTypeTraits::has_operator_equal_v<int>);
57 static_assert(QTypeTraits::has_operator_less_than_v<int>);
58 static_assert(QTypeTraits::has_operator_equal_v<double>);
59 static_assert(QTypeTraits::has_operator_less_than_v<double>);
60 
61 // no comparison operators
62 static_assert(!QTypeTraits::has_operator_equal_v<NoOperators>);
63 static_assert(!QTypeTraits::has_operator_less_than_v<NoOperators>);
64 
65 // standard Qt types
66 static_assert(QTypeTraits::has_operator_equal_v<QString>);
67 static_assert(QTypeTraits::has_operator_less_than_v<QString>);
68 static_assert(QTypeTraits::has_operator_equal_v<QVariant>);
69 static_assert(!QTypeTraits::has_operator_less_than_v<QVariant>);
70 
71 // QList
72 static_assert(QTypeTraits::has_operator_equal_v<QStringList>);
73 static_assert(QTypeTraits::has_operator_less_than_v<QStringList>);
78 
79 // QPair
84 
85 // QMap
90 
91 // QHash
96 
97 // QSharedPointer
99 // smart pointer equality doesn't depend on T
101 
102 // std::vector
103 static_assert(QTypeTraits::has_operator_equal_v<std::vector<QString>>);
104 static_assert(QTypeTraits::has_operator_less_than_v<std::vector<QString>>);
105 static_assert(!QTypeTraits::has_operator_equal_v<std::vector<NoOperators>>);
106 static_assert(!QTypeTraits::has_operator_less_than_v<std::vector<NoOperators>>);
107 static_assert(QTypeTraits::has_operator_equal_v<std::vector<QVariant>>);
108 static_assert(!QTypeTraits::has_operator_less_than_v<std::vector<QVariant>>);
109 
110 // std::pair
111 static_assert(QTypeTraits::has_operator_equal_v<std::pair<int, QString>>);
112 static_assert(QTypeTraits::has_operator_less_than_v<std::pair<int, QString>>);
113 static_assert(!QTypeTraits::has_operator_equal_v<std::pair<int, NoOperators>>);
114 static_assert(!QTypeTraits::has_operator_less_than_v<std::pair<int, NoOperators>>);
115 
116 // std::tuple
117 static_assert(QTypeTraits::has_operator_equal_v<std::tuple<int, QString, double>>);
118 static_assert(QTypeTraits::has_operator_less_than_v<std::tuple<int, QString, double>>);
119 static_assert(!QTypeTraits::has_operator_equal_v<std::tuple<int, QString, NoOperators>>);
120 static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, QString, NoOperators>>);
121 
122 // std::map
123 static_assert(QTypeTraits::has_operator_equal_v<std::map<int, QString>>);
124 static_assert(QTypeTraits::has_operator_less_than_v<std::map<int, QString>>);
125 static_assert(!QTypeTraits::has_operator_equal_v<std::map<int, NoOperators>>);
126 static_assert(!QTypeTraits::has_operator_less_than_v<std::map<int, NoOperators>>);
127 
128 // std::optional
129 static_assert(QTypeTraits::has_operator_equal_v<std::optional<QString>>);
130 static_assert(QTypeTraits::has_operator_less_than_v<std::optional<QString>>);
131 static_assert(!QTypeTraits::has_operator_equal_v<std::optional<NoOperators>>);
132 static_assert(!QTypeTraits::has_operator_less_than_v<std::optional<NoOperators>>);
133 
134 // nested types
135 static_assert(QTypeTraits::has_operator_equal_v<Nested>);
136 static_assert(!QTypeTraits::has_operator_less_than_v<Nested>);
137 static_assert(QTypeTraits::has_operator_equal_v<std::tuple<int, Nested>>);
138 static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, Nested>>);
139 static_assert(QTypeTraits::has_operator_equal_v<std::tuple<int, Nested>>);
140 static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, Nested>>);
141 
142 static_assert(QTypeTraits::has_operator_equal_v<Nested2>);
143 static_assert(!QTypeTraits::has_operator_less_than_v<Nested2>);
144 static_assert(QTypeTraits::has_operator_equal_v<std::tuple<int, Nested2>>);
145 static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, Nested2>>);
146 static_assert(QTypeTraits::has_operator_equal_v<std::tuple<int, Nested2>>);
147 static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, Nested2>>);
148 
149 }
150 
152 {
153  int m_typeId = -1;
155  virtual void *constructor(int typeId, void *where, const void *copy) = 0;
156  virtual void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) = 0;
157  virtual void saveOperator(QDataStream & out) const = 0;
158  virtual void loadOperator(QDataStream &in) = 0;
159  virtual ~BaseGenericType() {}
160 };
161 
163 {
164  void *constructor(int typeId, void *where, const void *copy) override
165  {
166  GenericGadgetType *ret = where ? new(where) GenericGadgetType : new GenericGadgetType;
167  ret->m_typeId = typeId;
168  if (copy) {
169  Q_ASSERT(ret->m_typeId == reinterpret_cast<const GenericGadgetType*>(copy)->m_typeId);
170  *ret = *reinterpret_cast<const GenericGadgetType*>(copy);
171  } else {
172  ret->properties = properties;
173  }
174  return ret;
175  }
176 
177  void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) override
178  {
179  if (_c == QMetaObject::ReadProperty) {
180  if (_id < properties.size()) {
181  const auto &prop = properties.at(_id);
182  prop.metaType().destruct(_a[0]);
183  prop.metaType().construct(_a[0], prop.constData());
184  }
185  } else if (_c == QMetaObject::WriteProperty) {
186  if (_id < properties.size()) {
187  auto & prop = properties[_id];
188  prop = QVariant(prop.metaType(), _a[0]);
189  }
190  }
191  }
192 
193  void saveOperator(QDataStream & out) const override
194  {
195  for (const auto &prop : properties)
196  out << prop;
197  }
198 
199  void loadOperator(QDataStream &in) override
200  {
201  for (auto &prop : properties)
202  in >> prop;
203  }
205 };
206 
208 {
209  // BaseGenericType interface
210  void *constructor(int typeId, void *where, const void *copy) override
211  {
212  GenericPODType *ret = where ? new(where) GenericPODType : new GenericPODType;
213  ret->m_typeId = typeId;
214  if (copy) {
215  Q_ASSERT(ret->m_typeId == reinterpret_cast<const GenericPODType*>(copy)->m_typeId);
216  *ret = *reinterpret_cast<const GenericPODType*>(copy);
217  } else {
218  ret->podData = podData;
219  }
220  return ret;
221  }
222 
223  void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) override
224  {
225  Q_UNUSED(_c);
226  Q_UNUSED(_id);
227  Q_UNUSED(_a);
228  Q_ASSERT(false);
229  }
230 
231  void saveOperator(QDataStream &out) const override
232  {
233  out << podData;
234  }
235  void loadOperator(QDataStream &in) override
236  {
237  in >> podData;
238  }
240 };
241 
242 // The order of the next two statics matters!
243 //
244 // need to use shared_ptr, for its template ctor, since QMetaTypeInterface isn't polymorphic,
245 // but the test derives from it
246 static std::vector<std::shared_ptr<QtPrivate::QMetaTypeInterface>> s_metaTypeInterfaces;
247 
248 using RegisteredType = QPair<std::shared_ptr<BaseGenericType>, std::shared_ptr<QMetaObject>>;
249 static QHash<int, RegisteredType> s_managedTypes;
250 
251 static void GadgetsStaticMetacallFunction(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
252 {
253  reinterpret_cast<BaseGenericType*>(_o)->staticMetacallFunction(_c, _id, _a);
254 }
255 
256 static void GadgetTypedDestructor(int typeId, void *ptr)
257 {
258  QCOMPARE(typeId, reinterpret_cast<BaseGenericType*>(ptr)->m_typeId);
259  reinterpret_cast<BaseGenericType*>(ptr)->~BaseGenericType();
260 }
261 
262 static void *GadgetTypedConstructor(int type, void *where, const void *copy)
263 {
264  auto it = s_managedTypes.find(type);
265  if (it == s_managedTypes.end())
266  return nullptr; // crash the test
267  return it->first->constructor(type, where, copy);
268 }
269 
270 static void GadgetSaveOperator(const QtPrivate::QMetaTypeInterface *, QDataStream & out, const void *data)
271 {
272  reinterpret_cast<const BaseGenericType *>(data)->saveOperator(out);
273 }
274 
275 static void GadgetLoadOperator(const QtPrivate::QMetaTypeInterface *, QDataStream &in, void *data)
276 {
277  reinterpret_cast<BaseGenericType *>(data)->loadOperator(in);
278 }
279 
280 struct Foo { int i; };
281 
282 
283 class CustomQObject : public QObject
284 {
285  Q_OBJECT
286 public:
288  : QObject(parent)
289  {
290  }
291  enum CustomQEnum { Val1, Val2 };
293 };
295  Q_GADGET
296 };
298  Q_GADGET
299 public:
301 };
302 
304 class GadgetDerived : public CustomGadget {};
305 
306 // cannot use Q_GADGET due to moc limitations but wants to behave like
307 // a Q_GADGET in Qml land
308 template<typename T>
310 
313 
314 void tst_QMetaType::registerGadget(const char *name, const QList<GadgetPropertyType> &gadgetProperties)
315 {
316  QMetaObjectBuilder gadgetBuilder;
317  gadgetBuilder.setClassName(name);
318  MetaObjectFlags metaObjectflags = DynamicMetaObject | PropertyAccessInStaticMetaCall;
319  gadgetBuilder.setFlags(metaObjectflags);
320  auto dynamicGadgetProperties = std::make_shared<GenericGadgetType>();
321  for (const auto &prop : gadgetProperties) {
322  int propertyType = QMetaType::fromName(prop.type).id();
323  dynamicGadgetProperties->properties.push_back(QVariant(QMetaType(propertyType)));
324  auto dynamicPropery = gadgetBuilder.addProperty(prop.name, prop.type);
325  dynamicPropery.setWritable(true);
326  dynamicPropery.setReadable(true);
327  }
328  auto meta = gadgetBuilder.toMetaObject();
329  meta->d.static_metacall = &GadgetsStaticMetacallFunction;
330  meta->d.superdata = nullptr;
332  struct TypeInfo : public QtPrivate::QMetaTypeInterface
333  {
334  QMetaObject *mo;
335  };
336 
337  auto typeInfo = s_metaTypeInterfaces.emplace_back(new TypeInfo {
338  {
339  0, alignof(GenericGadgetType), sizeof(GenericGadgetType), uint(flags), 0,
340  [](const QtPrivate::QMetaTypeInterface *self) -> const QMetaObject * {
341  return reinterpret_cast<const TypeInfo *>(self)->mo;
342  },
343  name,
344  [](const QtPrivate::QMetaTypeInterface *self, void *where) { GadgetTypedConstructor(self->typeId, where, nullptr); },
345  [](const QtPrivate::QMetaTypeInterface *self, void *where, const void *copy) { GadgetTypedConstructor(self->typeId, where, copy); },
346  [](const QtPrivate::QMetaTypeInterface *self, void *where, void *copy) { GadgetTypedConstructor(self->typeId, where, copy); },
347  [](const QtPrivate::QMetaTypeInterface *self, void *ptr) { GadgetTypedDestructor(self->typeId, ptr); },
348  nullptr,
349  nullptr,
350  nullptr,
351  GadgetSaveOperator,
352  GadgetLoadOperator,
353  nullptr
354  },
355  meta
356  }).get();
357  QMetaType gadgetMetaType(typeInfo);
358  dynamicGadgetProperties->m_metatype = gadgetMetaType;
359  int gadgetTypeId = QMetaType(typeInfo).id();
360  QVERIFY(gadgetTypeId > 0);
361  s_managedTypes[gadgetTypeId] = qMakePair(dynamicGadgetProperties, std::shared_ptr<QMetaObject>{meta, [](QMetaObject *ptr){ ::free(ptr); }});
362 }
363 
364 void tst_QMetaType::defined()
365 {
380 
381  // registered with Q_DECLARE_METATYPE
384 }
385 
386 struct Bar
387 {
388  Bar()
389  {
390  // check re-entrancy
391  if (!QMetaType::isRegistered(qRegisterMetaType<Foo>("Foo"))) {
392  qWarning("%s: re-entrancy test failed", Q_FUNC_INFO);
393  ++failureCount;
394  }
395  }
396  ~Bar() {}
397 
398 public:
399  static int failureCount;
400 };
401 
402 int Bar::failureCount = 0;
403 
405 {
406  Q_OBJECT
407 protected:
408  void run() override
409  {
410  Bar space[1];
411  space[0].~Bar();
412 
413  const QByteArray postFix = '_'
414  + QByteArray::number(reinterpret_cast<quintptr>(QThread::currentThreadId()));
415 
416  for (int i = 0; i < 1000; ++i) {
417  const QByteArray name = "Bar" + QByteArray::number(i) + postFix;
418  const char *nm = name.constData();
419  int tp = qRegisterMetaType<Bar>(nm);
420 #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
421  pthread_yield();
422 #endif
423  QMetaType info(tp);
424  if (!info.isValid()) {
425  ++failureCount;
426  qWarning() << "Wrong typeInfo returned for" << tp;
427  }
428  if (!info.isRegistered()) {
429  ++failureCount;
430  qWarning() << name << "is not a registered metatype";
431  }
432  if (QMetaType::typeFlags(tp) != (QMetaType::NeedsConstruction | QMetaType::NeedsDestruction)) {
433  ++failureCount;
434  qWarning() << "Wrong typeInfo returned for" << tp;
435  }
436  if (!QMetaType::isRegistered(tp)) {
437  ++failureCount;
438  qWarning() << name << "is not a registered metatype";
439  }
440  if (QMetaType::type(nm) != tp) {
441  ++failureCount;
442  qWarning() << "Wrong metatype returned for" << name;
443  }
444  void *buf1 = QMetaType::create(tp, 0);
445  void *buf2 = QMetaType::create(tp, buf1);
446  void *buf3 = info.create(tp, 0);
447  void *buf4 = info.create(tp, buf1);
448 
449  QMetaType::construct(tp, space, 0);
450  QMetaType::destruct(tp, space);
451  QMetaType::construct(tp, space, buf1);
452  QMetaType::destruct(tp, space);
453 
454  info.construct(space, 0);
455  info.destruct(space);
456  info.construct(space, buf1);
457  info.destruct(space);
458 
459  if (!buf1) {
460  ++failureCount;
461  qWarning() << "Null buffer returned by QMetaType::create(tp, 0)";
462  }
463  if (!buf2) {
464  ++failureCount;
465  qWarning() << "Null buffer returned by QMetaType::create(tp, buf)";
466  }
467  if (!buf3) {
468  ++failureCount;
469  qWarning() << "Null buffer returned by info.create(tp, 0)";
470  }
471  if (!buf4) {
472  ++failureCount;
473  qWarning() << "Null buffer returned by infocreate(tp, buf)";
474  }
475  QMetaType::destroy(tp, buf1);
476  QMetaType::destroy(tp, buf2);
477  info.destroy(buf3);
478  info.destroy(buf4);
479  }
480  new (space) Bar;
481  }
482 public:
485 };
486 
487 void tst_QMetaType::threadSafety()
488 {
492 
493  t1.start();
494  t2.start();
495  t3.start();
496 
497  QVERIFY(t1.wait());
498  QVERIFY(t2.wait());
499  QVERIFY(t3.wait());
500 
501  QCOMPARE(t1.failureCount, 0);
502  QCOMPARE(t2.failureCount, 0);
503  QCOMPARE(t3.failureCount, 0);
505 }
506 
507 namespace TestSpace
508 {
509  struct Foo { double d; public: ~Foo() {} };
510  struct QungTfu {};
511 }
513 
514 #define ADD_TESTSPACE(F) TestSpace::F
516 
517 void tst_QMetaType::namespaces()
518 {
519  TestSpace::Foo nf = { 11.12 };
521  QCOMPARE(qvariant_cast<TestSpace::Foo>(v).d, 11.12);
522 
523  int qungTfuId = qRegisterMetaType<ADD_TESTSPACE(QungTfu)>();
524  QCOMPARE(QMetaType::typeName(qungTfuId), "TestSpace::QungTfu");
525 }
526 
527 void tst_QMetaType::id()
528 {
530  QCOMPARE(QMetaType(::qMetaTypeId<TestSpace::Foo>()).id(), ::qMetaTypeId<TestSpace::Foo>());
531  QCOMPARE(QMetaType::fromType<TestSpace::Foo>().id(), ::qMetaTypeId<TestSpace::Foo>());
532 }
533 
534 void tst_QMetaType::qMetaTypeId()
535 {
536  QCOMPARE(::qMetaTypeId<QString>(), int(QMetaType::QString));
537  QCOMPARE(::qMetaTypeId<int>(), int(QMetaType::Int));
538  QCOMPARE(::qMetaTypeId<TestSpace::Foo>(), QMetaType::type("TestSpace::Foo"));
539 
540  QCOMPARE(::qMetaTypeId<char>(), QMetaType::type("char"));
541  QCOMPARE(::qMetaTypeId<uchar>(), QMetaType::type("unsigned char"));
542  QCOMPARE(::qMetaTypeId<signed char>(), QMetaType::type("signed char"));
543  QVERIFY(::qMetaTypeId<signed char>() != ::qMetaTypeId<char>());
544  QCOMPARE(::qMetaTypeId<qint8>(), QMetaType::type("qint8"));
545 }
546 
547 void tst_QMetaType::properties()
548 {
549  qRegisterMetaType<QList<QVariant> >("QList<QVariant>");
550 
551  QVariant v = property("prop");
552 
553  QCOMPARE(v.typeName(), "QVariantList");
554 
556  QCOMPARE(values.count(), 2);
557  QCOMPARE(values.at(0).toInt(), 42);
558 
559  values << 43 << "world";
560 
561  QVERIFY(setProperty("prop", values));
562  v = property("prop");
563  QCOMPARE(v.toList().count(), 4);
564 }
565 
566 void tst_QMetaType::normalizedTypes()
567 {
568  int WhityIntId = ::qMetaTypeId<Whity<int> >();
569  int WhityDoubleId = ::qMetaTypeId<Whity<double> >();
570 
571  QCOMPARE(QMetaType::type("Whity<int>"), WhityIntId);
572  QCOMPARE(QMetaType::type(" Whity < int > "), WhityIntId);
573  QCOMPARE(QMetaType::type("Whity<int >"), WhityIntId);
574 
575  QCOMPARE(QMetaType::type("Whity<double>"), WhityDoubleId);
576  QCOMPARE(QMetaType::type(" Whity< double > "), WhityDoubleId);
577  QCOMPARE(QMetaType::type("Whity<double >"), WhityDoubleId);
578 
579  QCOMPARE(qRegisterMetaType<Whity<int> >(" Whity < int > "), WhityIntId);
580  QCOMPARE(qRegisterMetaType<Whity<int> >("Whity<int>"), WhityIntId);
581  QCOMPARE(qRegisterMetaType<Whity<int> >("Whity<int > "), WhityIntId);
582 
583  QCOMPARE(qRegisterMetaType<Whity<double> >(" Whity < double > "), WhityDoubleId);
584  QCOMPARE(qRegisterMetaType<Whity<double> >("Whity<double>"), WhityDoubleId);
585  QCOMPARE(qRegisterMetaType<Whity<double> >("Whity<double > "), WhityDoubleId);
586 }
587 
588 #define TYPENAME_DATA(MetaTypeName, MetaTypeId, RealType)\
589  QTest::newRow(#RealType) << int(QMetaType::MetaTypeName) << #RealType;
590 
591 void tst_QMetaType::typeName_data()
592 {
593  QTest::addColumn<int>("aType");
594  QTest::addColumn<QString>("aTypeName");
595 
597  QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << static_cast<const char*>(0);
598  QTest::newRow("QMetaType::User-1") << (int(QMetaType::User) - 1) << static_cast<const char *>(nullptr);
599  QTest::newRow("QMetaType::FirstWidgetsType-1") << (int(QMetaType::FirstWidgetsType) - 1) << static_cast<const char *>(nullptr);
600 
601  QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << QString::fromLatin1("Whity<double>");
602  QTest::newRow("Whity<int>") << ::qMetaTypeId<Whity<int> >() << QString::fromLatin1("Whity<int>");
603  QTest::newRow("Testspace::Foo") << ::qMetaTypeId<TestSpace::Foo>() << QString::fromLatin1("TestSpace::Foo");
604 
605  QTest::newRow("-1") << -1 << QString();
606  QTest::newRow("-124125534") << -124125534 << QString();
607  QTest::newRow("124125534") << 124125534 << QString();
608 
609  // automatic registration
610  QTest::newRow("QHash<int,int>") << ::qMetaTypeId<QHash<int, int>>() << QString::fromLatin1("QHash<int,int>");
611  QTest::newRow("QMap<int,int>") << ::qMetaTypeId<QMap<int, int>>() << QString::fromLatin1("QMap<int,int>");
612  QTest::newRow("QList<QMap<int,int>>") << ::qMetaTypeId<QList<QMap<int, int>>>() << QString::fromLatin1("QList<QMap<int,int>>");
613 
614  // automatic registration with automatic QList to QList aliasing
615  QTest::newRow("QList<int>") << ::qMetaTypeId<QList<int>>() << QString::fromLatin1("QList<int>");
616  QTest::newRow("QList<QList<int>>") << ::qMetaTypeId<QList<QList<int>>>() << QString::fromLatin1("QList<QList<int>>");
617 
618  QTest::newRow("CustomQObject*") << ::qMetaTypeId<CustomQObject*>() << QString::fromLatin1("CustomQObject*");
619  QTest::newRow("CustomGadget") << ::qMetaTypeId<CustomGadget>() << QString::fromLatin1("CustomGadget");
620  QTest::newRow("CustomGadget*") << ::qMetaTypeId<CustomGadget*>() << QString::fromLatin1("CustomGadget*");
621  QTest::newRow("CustomQObject::CustomQEnum") << ::qMetaTypeId<CustomQObject::CustomQEnum>() << QString::fromLatin1("CustomQObject::CustomQEnum");
622  QTest::newRow("Qt::ArrowType") << ::qMetaTypeId<Qt::ArrowType>() << QString::fromLatin1("Qt::ArrowType");
623 
624  // template instance class derived from Q_GADGET enabled class
625  QTest::newRow("GadgetDerivedAndTyped<int>") << ::qMetaTypeId<GadgetDerivedAndTyped<int>>() << QString::fromLatin1("GadgetDerivedAndTyped<int>");
626  QTest::newRow("GadgetDerivedAndTyped<int>*") << ::qMetaTypeId<GadgetDerivedAndTyped<int>*>() << QString::fromLatin1("GadgetDerivedAndTyped<int>*");
627 }
628 
629 void tst_QMetaType::typeName()
630 {
631  QFETCH(int, aType);
632  QFETCH(QString, aTypeName);
633 
634  if (aType >= QMetaType::FirstWidgetsType)
635  QSKIP("The test doesn't link against QtWidgets.");
636 
637  const char *rawname = QMetaType::typeName(aType);
638  QString name = QString::fromLatin1(rawname);
639 
640  QCOMPARE(name, aTypeName);
641  QCOMPARE(name.toLatin1(), QMetaObject::normalizedType(name.toLatin1().constData()));
642  QCOMPARE(rawname == nullptr, aTypeName.isNull());
643 
644  QMetaType mt(aType);
645  if (mt.isValid()) { // Gui type are not valid
646  QCOMPARE(QString::fromLatin1(QMetaType(aType).name()), aTypeName);
647  }
648 
649 }
650 
651 void tst_QMetaType::type_data()
652 {
653  QTest::addColumn<int>("aType");
654  QTest::addColumn<QByteArray>("aTypeName");
655 
656 #define TST_QMETATYPE_TYPE_DATA(MetaTypeName, MetaTypeId, RealType)\
657  QTest::newRow(#RealType) << int(QMetaType::MetaTypeName) << QByteArray( #RealType );
658 #define TST_QMETATYPE_TYPE_DATA_ALIAS(MetaTypeName, MetaTypeId, AliasType, RealTypeString)\
659  QTest::newRow(RealTypeString) << int(QMetaType::MetaTypeName) << QByteArray( #AliasType );
660 
661  QTest::newRow("empty") << int(QMetaType::UnknownType) << QByteArray();
662 
665 
666 #undef TST_QMETATYPE_TYPE_DATA
667 #undef TST_METATYPE_TYPE_DATA_ALIAS
668 }
669 
670 void tst_QMetaType::type()
671 {
672  QFETCH(int, aType);
673  QFETCH(QByteArray, aTypeName);
674 
675  if (aType >= QMetaType::FirstWidgetsType)
676  QSKIP("The test doesn't link against QtWidgets.");
677  // QMetaType::type(QByteArray)
678  QCOMPARE(QMetaType::type(aTypeName), aType);
679  // QMetaType::type(const char *)
680  QCOMPARE(QMetaType::type(aTypeName.constData()), aType);
681 }
682 
683 void tst_QMetaType::type_fromSubString_data()
684 {
685  QTest::addColumn<int>("offset");
686  QTest::addColumn<int>("size");
687  QTest::addColumn<int>("expectedType");
688 
689  // The test string is defined in the test function below
690  QTest::newRow("int") << 0 << 3 << int(QMetaType::Int);
691  QTest::newRow("boo") << 3 << 3 << 0;
692  QTest::newRow("bool") << 3 << 4 << int(QMetaType::Bool);
693  QTest::newRow("intbool") << 0 << 7 << 0;
694  QTest::newRow("QMetaType::Type") << 7 << 15 << ::qMetaTypeId<QMetaType::Type>();
695  QTest::newRow("double") << 22 << 6 << int(QMetaType::Double);
696 }
697 
698 void tst_QMetaType::type_fromSubString()
699 {
700  static const char *types = "intboolQMetaType::Typedoublexxx";
701  QFETCH(int, offset);
702  QFETCH(int, size);
703  QFETCH(int, expectedType);
705  QCOMPARE(QMetaType::type(ba), expectedType);
706 }
707 
708 namespace {
709  template <typename T>
710  struct static_assert_trigger {
711  static_assert(( QMetaTypeId2<T>::IsBuiltIn ));
712  enum { value = true };
713  };
714 }
715 
716 #define CHECK_BUILTIN(MetaTypeName, MetaTypeId, RealType) static_assert_trigger< RealType >::value &&
717 static_assert(( FOR_EACH_CORE_METATYPE(CHECK_BUILTIN) true ));
718 #undef CHECK_BUILTIN
719 static_assert(( QMetaTypeId2<QList<QVariant> >::IsBuiltIn));
720 static_assert(( QMetaTypeId2<QMap<QString,QVariant> >::IsBuiltIn));
721 static_assert(( QMetaTypeId2<QObject*>::IsBuiltIn));
722 static_assert((!QMetaTypeId2<tst_QMetaType*>::IsBuiltIn)); // QObject subclass
723 static_assert((!QMetaTypeId2<QList<int> >::IsBuiltIn));
724 static_assert((!QMetaTypeId2<QMap<int,int> >::IsBuiltIn));
726 
727 void tst_QMetaType::create_data()
728 {
729  QTest::addColumn<int>("type");
730 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
731  QTest::newRow(QMetaType::typeName(QMetaType::MetaTypeName)) << int(QMetaType::MetaTypeName);
733 #undef ADD_METATYPE_TEST_ROW
734 }
735 
736 template<int ID>
737 static void testCreateHelper()
738 {
739  typedef typename MetaEnumToType<ID>::Type Type;
740  QMetaType info(ID);
741  void *actual1 = QMetaType::create(ID);
742  void *actual2 = info.create();
745  QCOMPARE(*static_cast<Type *>(actual1), *expected);
746  QCOMPARE(*static_cast<Type *>(actual2), *expected);
747  delete expected;
748  }
749  QMetaType::destroy(ID, actual1);
750  info.destroy(actual2);
751 }
752 
753 template<>
754 void testCreateHelper<QMetaType::Void>()
755 {
756  void *actual = QMetaType::create(QMetaType::Void);
759  }
760  QMetaType::destroy(QMetaType::Void, actual);
761 }
762 
763 
764 typedef void (*TypeTestFunction)();
765 
766 void tst_QMetaType::create()
767 {
768  struct TypeTestFunctionGetter
769  {
770  static TypeTestFunction get(int type)
771  {
772  switch (type) {
773 #define RETURN_CREATE_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
774  case QMetaType::MetaTypeName: \
775  return testCreateHelper<QMetaType::MetaTypeName>;
777 #undef RETURN_CREATE_FUNCTION
778  }
779  return 0;
780  }
781  };
782 
783  QFETCH(int, type);
785 }
786 
787 template<int ID>
788 static void testCreateCopyHelper()
789 {
790  typedef typename MetaEnumToType<ID>::Type Type;
791  Type *expected = TestValueFactory<ID>::create();
792  QMetaType info(ID);
793  void *actual1 = QMetaType::create(ID, expected);
794  void *actual2 = info.create(expected);
795  QCOMPARE(*static_cast<Type *>(actual1), *expected);
796  QCOMPARE(*static_cast<Type *>(actual2), *expected);
797  QMetaType::destroy(ID, actual1);
798  info.destroy(actual2);
799  delete expected;
800 }
801 
802 template<>
803 void testCreateCopyHelper<QMetaType::Void>()
804 {
807  void *actual = QMetaType::create(QMetaType::Void, expected);
808  QCOMPARE(static_cast<Type *>(actual), expected);
809  QMetaType::destroy(QMetaType::Void, actual);
810 }
811 
812 void tst_QMetaType::createCopy_data()
813 {
814  create_data();
815 }
816 
817 void tst_QMetaType::createCopy()
818 {
819  struct TypeTestFunctionGetter
820  {
821  static TypeTestFunction get(int type)
822  {
823  switch (type) {
824 #define RETURN_CREATE_COPY_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
825  case QMetaType::MetaTypeName: \
826  return testCreateCopyHelper<QMetaType::MetaTypeName>;
828 #undef RETURN_CREATE_COPY_FUNCTION
829  }
830  return 0;
831  }
832  };
833 
834  QFETCH(int, type);
836 }
837 
838 template<typename T>
839 constexpr size_t getSize = sizeof(T);
840 template<>
841 constexpr size_t getSize<void> = 0;
842 
843 void tst_QMetaType::sizeOf_data()
844 {
845  QTest::addColumn<int>("type");
846  QTest::addColumn<size_t>("size");
847 
848  QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << size_t(0);
849 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
850  QTest::newRow(#RealType) << int(QMetaType::MetaTypeName) << getSize<RealType>;
852 #undef ADD_METATYPE_TEST_ROW
853 
854  QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << sizeof(Whity<double>);
855  QTest::newRow("Whity<int>") << ::qMetaTypeId<Whity<int> >() << sizeof(Whity<int>);
856  QTest::newRow("Testspace::Foo") << ::qMetaTypeId<TestSpace::Foo>() << sizeof(TestSpace::Foo);
857 
858  QTest::newRow("-1") << -1 << size_t(0);
859  QTest::newRow("-124125534") << -124125534 << size_t(0);
860  QTest::newRow("124125534") << 124125534 << size_t(0);
861 }
862 
863 void tst_QMetaType::sizeOf()
864 {
865  QFETCH(int, type);
866  QFETCH(size_t, size);
867  QCOMPARE(size_t(QMetaType::sizeOf(type)), size);
868 }
869 
870 void tst_QMetaType::sizeOfStaticLess_data()
871 {
872  sizeOf_data();
873 }
874 
875 void tst_QMetaType::sizeOfStaticLess()
876 {
877  QFETCH(int, type);
878  QFETCH(size_t, size);
879  QCOMPARE(size_t(QMetaType(type).sizeOf()), size);
880 }
881 
882 template <typename T>
884 {
885  if constexpr (std::is_same_v<T, void>)
886  return 0;
887  else
888  return alignof(T);
889 }
890 
891 void tst_QMetaType::alignOf_data()
892 {
893  QTest::addColumn<int>("type");
894  QTest::addColumn<size_t>("size");
895 
896  QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << size_t(0);
897 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
898  QTest::newRow(#RealType) << int(QMetaType::MetaTypeName) << size_t(getAlignOf<RealType>());
900 #undef ADD_METATYPE_TEST_ROW
901 
902  QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << alignof(Whity<double>);
903  QTest::newRow("Whity<int>") << ::qMetaTypeId<Whity<int> >() << alignof(Whity<int>);
904  QTest::newRow("Testspace::Foo") << ::qMetaTypeId<TestSpace::Foo>() << alignof(TestSpace::Foo);
905 
906  QTest::newRow("-1") << -1 << size_t(0);
907  QTest::newRow("-124125534") << -124125534 << size_t(0);
908  QTest::newRow("124125534") << 124125534 << size_t(0);
909 }
910 
911 void tst_QMetaType::alignOf()
912 {
913  QFETCH(int, type);
914  QFETCH(size_t, size);
915  QCOMPARE(size_t(QMetaType(type).alignOf()), size);
916 }
917 
918 class CustomObject : public QObject
919 {
920  Q_OBJECT
921 public:
923  : QObject(parent)
924  {
925 
926  }
927 };
929 
930 struct SecondBase {};
931 
933 {
934  Q_OBJECT
935 public:
937  : QObject(parent)
938  {
939 
940  }
941 };
943 
944 class C { Q_DECL_UNUSED_MEMBER char _[4]; public: C() = default; C(const C&) {} };
945 class M { Q_DECL_UNUSED_MEMBER char _[4]; public: M() {} };
946 class P { Q_DECL_UNUSED_MEMBER char _[4]; };
947 
949 #if defined(Q_CC_GNU) && Q_CC_GNU < 501
952 #endif
954 
955 // avoid the comma:
965 
975 
978 
979 void tst_QMetaType::flags_data()
980 {
981  QTest::addColumn<int>("type");
982  QTest::addColumn<bool>("isMovable");
983  QTest::addColumn<bool>("isComplex");
984  QTest::addColumn<bool>("isPointerToQObject");
985  QTest::addColumn<bool>("isEnum");
986  QTest::addColumn<bool>("isQmlList");
987 
988 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
989  QTest::newRow(#RealType) << MetaTypeId \
990  << bool(QTypeInfo<RealType>::isRelocatable) \
991  << bool(QTypeInfo<RealType>::isComplex) \
992  << bool(QtPrivate::IsPointerToTypeDerivedFromQObject<RealType>::Value) \
993  << bool(std::is_enum<RealType>::value) \
994  << false;
998 #undef ADD_METATYPE_TEST_ROW
999  QTest::newRow("TestSpace::Foo") << ::qMetaTypeId<TestSpace::Foo>() << false << true << false << false << false;
1000  QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << true << true << false << false << false;
1001  QTest::newRow("CustomMovable") << ::qMetaTypeId<CustomMovable>() << true << true << false << false << false;
1002  QTest::newRow("CustomObject*") << ::qMetaTypeId<CustomObject*>() << true << false << true << false << false;
1003  QTest::newRow("CustomMultiInheritanceObject*") << ::qMetaTypeId<CustomMultiInheritanceObject*>() << true << false << true << false << false;
1004  QTest::newRow("QPair<C,C>") << ::qMetaTypeId<QPair<C,C> >() << false << true << false << false << false;
1005  QTest::newRow("QPair<C,M>") << ::qMetaTypeId<QPair<C,M> >() << false << true << false << false << false;
1006  QTest::newRow("QPair<C,P>") << ::qMetaTypeId<QPair<C,P> >() << false << true << false << false << false;
1007  QTest::newRow("QPair<M,C>") << ::qMetaTypeId<QPair<M,C> >() << false << true << false << false << false;
1008  QTest::newRow("QPair<M,M>") << ::qMetaTypeId<QPair<M,M> >() << true << true << false << false << false;
1009  QTest::newRow("QPair<M,P>") << ::qMetaTypeId<QPair<M,P> >() << true << true << false << false << false;
1010  QTest::newRow("QPair<P,C>") << ::qMetaTypeId<QPair<P,C> >() << false << true << false << false << false;
1011  QTest::newRow("QPair<P,M>") << ::qMetaTypeId<QPair<P,M> >() << true << true << false << false << false;
1012  QTest::newRow("QPair<P,P>") << ::qMetaTypeId<QPair<P,P> >() << true << false << false << false << false;
1013  QTest::newRow("FlagsDataEnum") << ::qMetaTypeId<FlagsDataEnum>() << true << false << false << true << false;
1014 
1015  // invalid ids.
1016  QTest::newRow("-1") << -1 << false << false << false << false << false;
1017  QTest::newRow("-124125534") << -124125534 << false << false << false << false << false;
1018  QTest::newRow("124125534") << 124125534 << false << false << false << false << false;
1019 }
1020 
1021 void tst_QMetaType::flags()
1022 {
1023  QFETCH(int, type);
1024  QFETCH(bool, isMovable);
1025  QFETCH(bool, isComplex);
1026  QFETCH(bool, isPointerToQObject);
1027  QFETCH(bool, isEnum);
1028  QFETCH(bool, isQmlList);
1029 
1030  QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsConstruction), isComplex);
1031  QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsDestruction), isComplex);
1032  QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::RelocatableType), isMovable);
1033  QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::PointerToQObject), isPointerToQObject);
1034  QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::IsEnumeration), isEnum);
1035  QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::IsQmlList), isQmlList);
1036 }
1037 
1038 void tst_QMetaType::flagsStaticLess_data()
1039 {
1040  flags_data();
1041 }
1042 
1043 void tst_QMetaType::flagsStaticLess()
1044 {
1045  QFETCH(int, type);
1046  QFETCH(bool, isMovable);
1047  QFETCH(bool, isComplex);
1048 
1049  int flags = QMetaType(type).flags();
1050  QCOMPARE(bool(flags & QMetaType::NeedsConstruction), isComplex);
1051  QCOMPARE(bool(flags & QMetaType::NeedsDestruction), isComplex);
1052  QCOMPARE(bool(flags & QMetaType::RelocatableType), isMovable);
1053 }
1054 
1055 void tst_QMetaType::flagsBinaryCompatibility6_0_data()
1056 {
1057 // Changing traits of a built-in type is illegal from BC point of view.
1058 // Traits are saved in code of an application and in the Qt library which means
1059 // that there may be a mismatch.
1060 // The test is loading data generated by this code:
1061 //
1062 // QList<quint32> buffer;
1063 // buffer.reserve(2 * QMetaType::User);
1064 // for (quint32 i = 0; i < QMetaType::LastCoreType; ++i) {
1065 // if (QMetaType::isRegistered(i)) {
1066 // buffer.append(i);
1067 // buffer.append(quint32(QMetaType::typeFlags(i)));
1068 // }
1069 // }
1070 // QFile file("/tmp/typeFlags.bin");
1071 // file.open(QIODevice::WriteOnly);
1072 // QDataStream ds(&file);
1073 // ds << buffer;
1074 // file.close();
1075 
1076  QTest::addColumn<quint32>("id");
1077  QTest::addColumn<quint32>("flags");
1078 
1079  QFile file(QFINDTESTDATA("typeFlags.bin"));
1082  QDataStream ds(&file);
1083  ds >> buffer;
1084 
1085  for (int i = 0; i < buffer.size(); i+=2) {
1086  const quint32 id = buffer.at(i);
1087  const quint32 flags = buffer.at(i + 1);
1088  if (id > QMetaType::LastCoreType)
1089  continue; // We do not link against QtGui, so we do longer consider such type as registered
1090  QVERIFY2(QMetaType::isRegistered(id), "A type could not be removed in BC way");
1091  QTest::newRow(QMetaType::typeName(id)) << id << flags;
1092  }
1093 }
1094 
1095 void tst_QMetaType::flagsBinaryCompatibility6_0()
1096 {
1097  QFETCH(quint32, id);
1098  QFETCH(quint32, flags);
1099 
1100  const auto currentFlags = QMetaType::typeFlags(id);
1101  auto expectedFlags = QMetaType::TypeFlags(flags);
1102  if (!(currentFlags.testFlag(QMetaType::NeedsConstruction) && currentFlags.testFlag(QMetaType::NeedsDestruction))) {
1103  if (expectedFlags.testFlag(QMetaType::NeedsConstruction) && expectedFlags.testFlag(QMetaType::NeedsDestruction)) {
1104  // If type changed from RELOCATABLE to trivial, that's fine
1105  expectedFlags.setFlag(QMetaType::NeedsConstruction, false);
1106  expectedFlags.setFlag(QMetaType::NeedsDestruction, false);
1107  }
1108  }
1109  quint32 mask_5_0 = 0x1fb; // Only compare the values that were already defined in 5.0
1110 
1111  QCOMPARE(quint32(currentFlags) & mask_5_0, quint32(expectedFlags) & mask_5_0);
1112 }
1113 
1114 void tst_QMetaType::construct_data()
1115 {
1116  create_data();
1117 }
1118 
1119 template<int ID>
1120 static void testConstructHelper()
1121 {
1122  typedef typename MetaEnumToType<ID>::Type Type;
1123  QMetaType info(ID);
1124  int size = info.sizeOf();
1125  void *storage1 = qMallocAligned(size, alignof(Type));
1126  void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0);
1127  void *storage2 = qMallocAligned(size, alignof(Type));
1128  void *actual2 = info.construct(storage2, /*copy=*/0);
1129  QCOMPARE(actual1, storage1);
1130  QCOMPARE(actual2, storage2);
1132  Type *expected = DefaultValueFactory<ID>::create();
1133  QCOMPARE(*static_cast<Type *>(actual1), *expected);
1134  QCOMPARE(*static_cast<Type *>(actual2), *expected);
1135  delete expected;
1136  }
1137  QMetaType::destruct(ID, actual1);
1138  qFreeAligned(storage1);
1139  info.destruct(actual2);
1140  qFreeAligned(storage2);
1141 
1142  QVERIFY(QMetaType::construct(ID, 0, /*copy=*/0) == 0);
1143  QMetaType::destruct(ID, 0);
1144 
1145  QVERIFY(info.construct(0, /*copy=*/0) == 0);
1146  info.destruct(0);
1147 }
1148 
1149 template<>
1150 void testConstructHelper<QMetaType::Void>()
1151 {
1152  /*int size = */ QMetaType::sizeOf(QMetaType::Void);
1153  void *storage = 0;
1154  void *actual = QMetaType::construct(QMetaType::Void, storage, /*copy=*/0);
1155  QCOMPARE(actual, storage);
1158  }
1159  QMetaType::destruct(QMetaType::Void, actual);
1161 
1162  QVERIFY(QMetaType::construct(QMetaType::Void, 0, /*copy=*/0) == 0);
1163  QMetaType::destruct(QMetaType::Void, 0);
1164 }
1165 
1166 void tst_QMetaType::construct()
1167 {
1168  struct TypeTestFunctionGetter
1169  {
1170  static TypeTestFunction get(int type)
1171  {
1172  switch (type) {
1173 #define RETURN_CONSTRUCT_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
1174  case QMetaType::MetaTypeName: \
1175  return testConstructHelper<QMetaType::MetaTypeName>;
1177 #undef RETURN_CONSTRUCT_FUNCTION
1178  }
1179  return 0;
1180  }
1181  };
1182 
1183  QFETCH(int, type);
1185 }
1186 
1187 void tst_QMetaType::typedConstruct()
1188 {
1189  auto testMetaObjectWriteOnGadget = [](QVariant &gadget, const QList<GadgetPropertyType> &properties)
1190  {
1191  auto metaObject = QMetaType::metaObjectForType(gadget.userType());
1192  QVERIFY(metaObject != nullptr);
1193  QCOMPARE(metaObject->methodCount(), 0);
1194  QCOMPARE(metaObject->propertyCount(), properties.size());
1195  for (int i = 0; i < metaObject->propertyCount(); ++i) {
1196  auto prop = metaObject->property(i);
1197  QCOMPARE(properties[i].name, prop.name());
1198  QCOMPARE(properties[i].type, prop.typeName());
1199  prop.writeOnGadget(gadget.data(), properties[i].testData);
1200  }
1201  };
1202 
1203  auto testMetaObjectReadOnGadget = [](QVariant gadget, const QList<GadgetPropertyType> &properties)
1204  {
1205  auto metaObject = QMetaType::metaObjectForType(gadget.userType());
1206  QVERIFY(metaObject != nullptr);
1207  QCOMPARE(metaObject->methodCount(), 0);
1208  QCOMPARE(metaObject->propertyCount(), properties.size());
1209  for (int i = 0; i < metaObject->propertyCount(); ++i) {
1210  auto prop = metaObject->property(i);
1211  QCOMPARE(properties[i].name, prop.name());
1212  QCOMPARE(properties[i].type, prop.typeName());
1213  if (!QMetaType::typeFlags(prop.userType()).testFlag(QMetaType::IsGadget))
1214  QCOMPARE(properties[i].testData, prop.readOnGadget(gadget.constData()));
1215  }
1216  };
1217 
1218  QList<GadgetPropertyType> dynamicGadget1 = {
1219  {"int", "int_prop", 34526},
1220  {"float", "float_prop", 1.23f},
1221  {"QString", "string_prop", QString{"Test QString"}}
1222  };
1223  registerGadget("DynamicGadget1", dynamicGadget1);
1224 
1225  QVariant testGadget1(QMetaType(QMetaType::type("DynamicGadget1")));
1226  testMetaObjectWriteOnGadget(testGadget1, dynamicGadget1);
1227  testMetaObjectReadOnGadget(testGadget1, dynamicGadget1);
1228 
1229 
1230  QList<GadgetPropertyType> dynamicGadget2 = {
1231  {"int", "int_prop", 512},
1232  {"double", "double_prop", 4.56},
1233  {"QString", "string_prop", QString{"Another String"}},
1234  {"DynamicGadget1", "dynamicGadget1_prop", testGadget1}
1235  };
1236  registerGadget("DynamicGadget2", dynamicGadget2);
1237  QVariant testGadget2(QMetaType(QMetaType::type("DynamicGadget2")));
1238  testMetaObjectWriteOnGadget(testGadget2, dynamicGadget2);
1239  testMetaObjectReadOnGadget(testGadget2, dynamicGadget2);
1240  auto g2mo = QMetaType::metaObjectForType(testGadget2.userType());
1241  auto dynamicGadget1_prop = g2mo->property(g2mo->indexOfProperty("dynamicGadget1_prop"));
1242  testMetaObjectReadOnGadget(dynamicGadget1_prop.readOnGadget(testGadget2.constData()), dynamicGadget1);
1243 
1244 
1245  // Register POD
1246  const QByteArray myPodTesData = "My POD test data";
1247  const char podTypeName[] = "DynamicPOD";
1248  auto dynamicGadgetProperties = std::make_shared<GenericPODType>();
1249  dynamicGadgetProperties->podData = myPodTesData;
1251  using TypeInfo = QtPrivate::QMetaTypeInterface;
1252  auto typeInfo = s_metaTypeInterfaces.emplace_back(new TypeInfo {
1253  0, alignof(GenericGadgetType), sizeof(GenericGadgetType), uint(flags), 0, nullptr, podTypeName,
1254  [](const TypeInfo *self, void *where) { GadgetTypedConstructor(self->typeId, where, nullptr); },
1255  [](const TypeInfo *self, void *where, const void *copy) { GadgetTypedConstructor(self->typeId, where, copy); },
1256  [](const TypeInfo *self, void *where, void *copy) { GadgetTypedConstructor(self->typeId, where, copy); },
1257  [](const TypeInfo *self, void *ptr) { GadgetTypedDestructor(self->typeId, ptr); },
1258  nullptr,
1259  nullptr,
1260  nullptr,
1261  GadgetSaveOperator,
1262  GadgetLoadOperator,
1263  nullptr
1264  }).get();
1265  QMetaType metatype(typeInfo);
1266  dynamicGadgetProperties->m_metatype = metatype;
1267  int podTypeId = metatype.id();
1268  QVERIFY(podTypeId > 0);
1269  s_managedTypes[podTypeId] = qMakePair(dynamicGadgetProperties, std::shared_ptr<QMetaObject>{});
1270 
1271  // Test POD
1272  QCOMPARE(podTypeId, QMetaType::type(podTypeName));
1273  QVariant podVariant{QMetaType(podTypeId)};
1274  QCOMPARE(myPodTesData, static_cast<const GenericPODType *>(reinterpret_cast<const BaseGenericType *>(podVariant.constData()))->podData);
1275 
1276  QVariant podVariant1{podVariant};
1277  podVariant1.detach(); // Test stream operators
1278  static_cast<GenericPODType *>(reinterpret_cast<BaseGenericType *>(podVariant.data()))->podData.clear();
1279  QCOMPARE(myPodTesData, static_cast<const GenericPODType *>(reinterpret_cast<const BaseGenericType *>(podVariant1.constData()))->podData);
1280 }
1281 
1282 template<int ID>
1283 static void testConstructCopyHelper()
1284 {
1285  typedef typename MetaEnumToType<ID>::Type Type;
1286  Type *expected = TestValueFactory<ID>::create();
1287  QMetaType info(ID);
1288  int size = QMetaType::sizeOf(ID);
1289  QCOMPARE(info.sizeOf(), size);
1290  void *storage1 = qMallocAligned(size, alignof(Type));
1291  void *actual1 = QMetaType::construct(ID, storage1, expected);
1292  void *storage2 = qMallocAligned(size, alignof(Type));
1293  void *actual2 = info.construct(storage2, expected);
1294  QCOMPARE(actual1, storage1);
1295  QCOMPARE(actual2, storage2);
1296  QCOMPARE(*static_cast<Type *>(actual1), *expected);
1297  QCOMPARE(*static_cast<Type *>(actual2), *expected);
1298  QMetaType::destruct(ID, actual1);
1299  qFreeAligned(storage1);
1300  info.destruct(actual2);
1301  qFreeAligned(storage2);
1302 
1303  QVERIFY(QMetaType::construct(ID, 0, expected) == 0);
1304  QVERIFY(info.construct(0, expected) == 0);
1305 
1306  delete expected;
1307 }
1308 
1309 template<>
1310 void testConstructCopyHelper<QMetaType::Void>()
1311 {
1314  /* int size = */QMetaType::sizeOf(QMetaType::Void);
1315  void *storage = 0;
1316  void *actual = QMetaType::construct(QMetaType::Void, storage, expected);
1317  QCOMPARE(actual, storage);
1318  QMetaType::destruct(QMetaType::Void, actual);
1320 
1321  QVERIFY(QMetaType::construct(QMetaType::Void, 0, expected) == 0);
1322 }
1323 
1324 void tst_QMetaType::constructCopy_data()
1325 {
1326  create_data();
1327 }
1328 
1329 void tst_QMetaType::constructCopy()
1330 {
1331  struct TypeTestFunctionGetter
1332  {
1333  static TypeTestFunction get(int type)
1334  {
1335  switch (type) {
1336 #define RETURN_CONSTRUCT_COPY_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
1337  case QMetaType::MetaTypeName: \
1338  return testConstructCopyHelper<QMetaType::MetaTypeName>;
1340 #undef RETURN_CONSTRUCT_COPY_FUNCTION
1341  }
1342  return 0;
1343  }
1344  };
1345 
1346  QFETCH(int, type);
1348 }
1349 
1350 void tst_QMetaType::selfCompare_data()
1351 {
1352  qRegisterMetaType<QPartialOrdering>();
1353  QTest::addColumn<int>("type");
1354  QTest::addColumn<QPartialOrdering>("order");
1355 
1356  auto orderingFor = [](QMetaType::Type t) {
1357  if (t == QMetaType::UnknownType || t == QMetaType::Void)
1360  };
1361 
1362  QTest::newRow("unknown-type") << int(QMetaType::UnknownType) << orderingFor(QMetaType::UnknownType);
1363 
1364 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
1365  QTest::newRow(QMetaType::typeName(QMetaType::MetaTypeName)) << int(QMetaType::MetaTypeName) << orderingFor(QMetaType::MetaTypeName);
1367 #undef ADD_METATYPE_TEST_ROW
1368 }
1369 
1370 void tst_QMetaType::selfCompare()
1371 {
1372  QFETCH(int, type);
1374 
1375  QMetaType t(type);
1376  void *v1 = t.create(nullptr);
1377  void *v2 = t.create(nullptr);
1378  auto scope = qScopeGuard([=] {
1379  t.destroy(v1);
1380  t.destroy(v2);
1381  });
1382 
1383  // all these types have an equality comparator
1385 
1386  if (t.iface() && t.iface()->lessThan)
1387  QCOMPARE(t.compare(v1, v2), order);
1388 
1389  // for the primitive types, do a memcmp() too
1390  switch (type) {
1391  default:
1392  break;
1393 
1394 #define ADD_METATYPE_CASE(MetaTypeName, MetaTypeId, RealType) \
1395  case QMetaType::MetaTypeName:
1397 #undef ADD_METATYPE_CASE
1398  QCOMPARE(memcmp(v1, v2, t.sizeOf()), 0);
1399  }
1400 }
1401 
1403 Q_DECLARE_METATYPE(CustomString) //this line is useless
1404 
1405 void tst_QMetaType::typedefs()
1406 {
1407  QCOMPARE(QMetaType::type("long long"), int(QMetaType::LongLong));
1408  QCOMPARE(QMetaType::type("unsigned long long"), int(QMetaType::ULongLong));
1409  QCOMPARE(QMetaType::type("qint8"), int(QMetaType::SChar));
1410  QCOMPARE(QMetaType::type("quint8"), int(QMetaType::UChar));
1411  QCOMPARE(QMetaType::type("qint16"), int(QMetaType::Short));
1412  QCOMPARE(QMetaType::type("quint16"), int(QMetaType::UShort));
1413  QCOMPARE(QMetaType::type("qint32"), int(QMetaType::Int));
1414  QCOMPARE(QMetaType::type("quint32"), int(QMetaType::UInt));
1415  QCOMPARE(QMetaType::type("qint64"), int(QMetaType::LongLong));
1416  QCOMPARE(QMetaType::type("quint64"), int(QMetaType::ULongLong));
1417 
1418  // make sure the qreal typeId is the type id of the type it's defined to
1419  QCOMPARE(QMetaType::type("qreal"), ::qMetaTypeId<qreal>());
1420 
1421  qRegisterMetaType<CustomString>("CustomString");
1422  QCOMPARE(QMetaType::type("CustomString"), ::qMetaTypeId<CustomString>());
1423 
1424  typedef Whity<double> WhityDouble;
1425  qRegisterMetaType<WhityDouble>("WhityDouble");
1426  QCOMPARE(QMetaType::type("WhityDouble"), ::qMetaTypeId<WhityDouble>());
1427 }
1428 
1429 void tst_QMetaType::registerType()
1430 {
1431  // Built-in
1432  QCOMPARE(qRegisterMetaType<QString>("QString"), int(QMetaType::QString));
1433  QCOMPARE(qRegisterMetaType<QString>("QString"), int(QMetaType::QString));
1434 
1435  // Custom
1436  int fooId = qRegisterMetaType<TestSpace::Foo>("TestSpace::Foo");
1437  QVERIFY(fooId >= int(QMetaType::User));
1438  QCOMPARE(qRegisterMetaType<TestSpace::Foo>("TestSpace::Foo"), fooId);
1439 
1440  int movableId = qRegisterMetaType<CustomMovable>("CustomMovable");
1441  QVERIFY(movableId >= int(QMetaType::User));
1442  QCOMPARE(qRegisterMetaType<CustomMovable>("CustomMovable"), movableId);
1443 
1444  // Alias to built-in
1445  typedef QString MyString;
1446 
1447  QCOMPARE(qRegisterMetaType<MyString>("MyString"), int(QMetaType::QString));
1448  QCOMPARE(qRegisterMetaType<MyString>("MyString"), int(QMetaType::QString));
1449 
1450  QCOMPARE(QMetaType::type("MyString"), int(QMetaType::QString));
1451 
1452  // Alias to custom type
1453  typedef CustomMovable MyMovable;
1454  typedef TestSpace::Foo MyFoo;
1455 
1456  QCOMPARE(qRegisterMetaType<MyMovable>("MyMovable"), movableId);
1457  QCOMPARE(qRegisterMetaType<MyMovable>("MyMovable"), movableId);
1458 
1459  QCOMPARE(QMetaType::type("MyMovable"), movableId);
1460 
1461  QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId);
1462  QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId);
1463 
1464  QCOMPARE(QMetaType::type("MyFoo"), fooId);
1465 }
1466 
1468 
1469 void tst_QMetaType::isRegistered_data()
1470 {
1471  QTest::addColumn<int>("typeId");
1472  QTest::addColumn<bool>("registered");
1473 
1474  // predefined/custom types
1475  QTest::newRow("QMetaType::Void") << int(QMetaType::Void) << true;
1476  QTest::newRow("QMetaType::Int") << int(QMetaType::Int) << true;
1477 
1478  int dummyTypeId = qRegisterMetaType<IsRegisteredDummyType>("IsRegisteredDummyType");
1479 
1480  QTest::newRow("IsRegisteredDummyType") << dummyTypeId << true;
1481 
1482  // unknown types
1483  QTest::newRow("-1") << -1 << false;
1484  QTest::newRow("-42") << -42 << false;
1485  QTest::newRow("IsRegisteredDummyType + 1") << (dummyTypeId + 1) << false;
1486  QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << false;
1487 }
1488 
1489 void tst_QMetaType::isRegistered()
1490 {
1491  QFETCH(int, typeId);
1492  QFETCH(bool, registered);
1493  QCOMPARE(QMetaType::isRegistered(typeId), registered);
1494 }
1495 
1497 struct isEnumTest_Struct0 { enum A{}; };
1498 
1501 
1504 
1505 void tst_QMetaType::isEnum()
1506 {
1507  int type0 = qRegisterMetaType<int>("int");
1508  QVERIFY((QMetaType::typeFlags(type0) & QMetaType::IsEnumeration) == 0);
1509 
1510  int type1 = qRegisterMetaType<isEnumTest_Enum0>("isEnumTest_Enum0");
1511  QVERIFY((QMetaType::typeFlags(type1) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration);
1512 
1513  int type2 = qRegisterMetaType<isEnumTest_Struct0>("isEnumTest_Struct0");
1514  QVERIFY((QMetaType::typeFlags(type2) & QMetaType::IsEnumeration) == 0);
1515 
1516  int type3 = qRegisterMetaType<isEnumTest_Enum0 *>("isEnumTest_Enum0 *");
1517  QVERIFY((QMetaType::typeFlags(type3) & QMetaType::IsEnumeration) == 0);
1518 
1519  int type4 = qRegisterMetaType<isEnumTest_Struct0::A>("isEnumTest_Struct0::A");
1520  QVERIFY((QMetaType::typeFlags(type4) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration);
1521 
1522  int type5 = ::qMetaTypeId<isEnumTest_Struct1>();
1523  QVERIFY((QMetaType::typeFlags(type5) & QMetaType::IsEnumeration) == 0);
1524 
1525  int type6 = ::qMetaTypeId<isEnumTest_Enum1>();
1526  QVERIFY((QMetaType::typeFlags(type6) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration);
1527 }
1528 
1529 void tst_QMetaType::isRegisteredStaticLess_data()
1530 {
1531  isRegistered_data();
1532 }
1533 
1534 void tst_QMetaType::isRegisteredStaticLess()
1535 {
1536  QFETCH(int, typeId);
1537  QFETCH(bool, registered);
1538  QCOMPARE(QMetaType(typeId).isRegistered(), registered);
1539 }
1540 
1543 typedef QMap<int, uint> IntUIntMap;
1545 typedef QPair<int, uint> IntUIntPair;
1547 
1549 {
1550  CustomComparable(int i_ = 0) :i(i_) { }
1551  bool operator==(const CustomComparable &other) const
1552  {
1553  return i == other.i;
1554  }
1555  int i;
1556 };
1557 
1559 
1566 
1567 typedef QHash<int, int> IntIntHash;
1568 typedef int NaturalNumber;
1570 {
1571  Q_OBJECT
1572  Q_PROPERTY(IntIntHash someHash READ someHash CONSTANT)
1573  Q_PROPERTY(NaturalNumber someInt READ someInt CONSTANT)
1574 public:
1576  : QObject(parent), m_int(42)
1577  {
1578  m_hash.insert(4, 2);
1579  }
1580 
1582  {
1583  return m_hash;
1584  }
1585 
1586  int someInt() const
1587  {
1588  return m_int;
1589  }
1590 
1591 private:
1592  QHash<int,int> m_hash;
1593  int m_int;
1594 };
1595 
1596 class MyObject : public QObject
1597 {
1598  Q_OBJECT
1599 public:
1601  : QObject(parent)
1602  {
1603  }
1604 };
1607 
1608 void tst_QMetaType::automaticTemplateRegistration_1()
1609 {
1610 #define TEST_SEQUENTIAL_CONTAINER(CONTAINER, VALUE_TYPE) \
1611  { \
1612  CONTAINER<VALUE_TYPE> innerContainer; \
1613  innerContainer.push_back(42); \
1614  QVERIFY(*QVariant::fromValue(innerContainer).value<CONTAINER<VALUE_TYPE> >().begin() == 42); \
1615  QList<CONTAINER<VALUE_TYPE> > outerContainer; \
1616  outerContainer << innerContainer; \
1617  QVERIFY(*QVariant::fromValue(outerContainer).value<QList<CONTAINER<VALUE_TYPE> > >().first().begin() == 42); \
1618  }
1619 
1623 
1624  {
1625  std::vector<bool> vecbool;
1626  vecbool.push_back(true);
1627  vecbool.push_back(false);
1628  vecbool.push_back(true);
1629  QVERIFY(QVariant::fromValue(vecbool).value<std::vector<bool>>().front() == true);
1630  QList<std::vector<bool>> vectorList;
1631  vectorList << vecbool;
1632  QVERIFY(QVariant::fromValue(vectorList).value<QList<std::vector<bool>>>().first().front() == true);
1633  }
1634 
1635  {
1636  QList<unsigned> unsignedList;
1637  unsignedList << 123;
1638  QVERIFY(QVariant::fromValue(unsignedList).value<QList<unsigned>>().first() == 123);
1639  QList<QList<unsigned>> vectorList;
1640  vectorList << unsignedList;
1641  QVERIFY(QVariant::fromValue(vectorList).value<QList<QList<unsigned>>>().first().first() == 123);
1642  }
1643 
1644  QCOMPARE(::qMetaTypeId<QVariantList>(), (int)QMetaType::QVariantList);
1645  QCOMPARE(::qMetaTypeId<QList<QVariant> >(), (int)QMetaType::QVariantList);
1646 
1650 
1651  {
1652  QList<QSharedPointer<QObject> > sharedPointerList;
1653  QObject *testObject = new QObject;
1654  sharedPointerList << QSharedPointer<QObject>(testObject);
1657  vectorList << sharedPointerList;
1659  }
1660  {
1661  IntIntHash intIntHash;
1662  intIntHash.insert(4, 2);
1663  QCOMPARE(QVariant::fromValue(intIntHash).value<IntIntHash>().value(4), 2);
1664 
1665  AutoMetaTypeObject amto;
1666 
1667  qRegisterMetaType<QHash<int, int> >("IntIntHash");
1668  QVariant hashVariant = amto.property("someHash");
1669  QCOMPARE(hashVariant.value<IntIntHash>().value(4), 2);
1670 
1671  qRegisterMetaType<int>("NaturalNumber");
1672  QVariant intVariant = amto.property("someInt");
1673  QCOMPARE(intVariant.value<NaturalNumber>(), 42);
1674  }
1675  {
1676  IntUIntHash intUIntHash;
1677  intUIntHash.insert(4, 2);
1678  QCOMPARE(QVariant::fromValue(intUIntHash).value<IntUIntHash>().value(4), (uint)2);
1679  }
1680  {
1681  IntComparableHash intComparableHash;
1683  intComparableHash.insert(4, m);
1684  QCOMPARE(QVariant::fromValue(intComparableHash).value<IntComparableHash>().value(4), m);
1685  }
1686  {
1687  QVariantHash variantHash;
1688  variantHash.insert(QStringLiteral("4"), 2);
1690  }
1691  {
1692  typedef QMap<int, int> IntIntMap;
1693  IntIntMap intIntMap;
1694  intIntMap.insert(4, 2);
1695  QCOMPARE(QVariant::fromValue(intIntMap).value<IntIntMap>().value(4), 2);
1696  }
1697  {
1698  IntUIntMap intUIntMap;
1699  intUIntMap.insert(4, 2);
1701  }
1702  {
1703  IntComparableMap intComparableMap;
1705  intComparableMap.insert(4, m);
1706  QCOMPARE(QVariant::fromValue(intComparableMap).value<IntComparableMap>().value(4), m);
1707  }
1708  {
1709  QVariantMap variantMap;
1710  variantMap.insert(QStringLiteral("4"), 2);
1712  }
1713  {
1714  typedef std::map<int, int> IntIntMap;
1715  IntIntMap intIntMap;
1716  intIntMap[4] = 2;
1717  QCOMPARE(QVariant::fromValue(intIntMap).value<IntIntMap>()[4], 2);
1718  }
1719  {
1720  typedef std::map<int, uint> StdIntUIntMap;
1721  StdIntUIntMap intUIntMap;
1722  intUIntMap[4] = 2;
1723  QCOMPARE(QVariant::fromValue(intUIntMap).value<StdIntUIntMap>()[4], (uint)2);
1724  }
1725  {
1726  typedef std::map<int, CustomObject*> StdMapIntCustomObject ;
1727  StdMapIntCustomObject intComparableMap;
1728  CustomObject *o = nullptr;
1729  intComparableMap[4] = o;
1731  }
1732  {
1733  typedef std::map<QString, QVariant> StdMapStringVariant;
1734  StdMapStringVariant variantMap;
1735  variantMap[QStringLiteral("4")] = 2;
1737  }
1738  {
1739  typedef QPair<int, int> IntIntPair;
1740  IntIntPair intIntPair = qMakePair(4, 2);
1742  QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().second, 2);
1743  }
1744  {
1745  IntUIntPair intUIntPair = qMakePair(4, 2u);
1747  QCOMPARE(QVariant::fromValue(intUIntPair).value<IntUIntPair>().second, (uint)2);
1748  }
1749  {
1751  IntComparablePair intComparablePair = qMakePair(4, m);
1753  QCOMPARE(QVariant::fromValue(intComparablePair).value<IntComparablePair>().second, m);
1754  }
1755  {
1756  typedef std::pair<int, int> IntIntPair;
1757  IntIntPair intIntPair = std::make_pair(4, 2);
1759  QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().second, 2);
1760  }
1761  {
1762  typedef std::pair<int, uint> StdIntUIntPair;
1763  StdIntUIntPair intUIntPair = std::make_pair<int, uint>(4, 2);
1765  QCOMPARE(QVariant::fromValue(intUIntPair).value<StdIntUIntPair>().second, (uint)2);
1766  }
1767  {
1768  typedef std::pair<int, CustomQObject*> StdIntComparablePair;
1769  CustomQObject *o = nullptr;
1770  StdIntComparablePair intComparablePair = std::make_pair(4, o);
1772  QCOMPARE(QVariant::fromValue(intComparablePair).value<StdIntComparablePair>().second, o);
1773  }
1774  {
1775  typedef QHash<int, UnregisteredType> IntUnregisteredTypeHash;
1776  QVERIFY(qRegisterMetaType<IntUnregisteredTypeHash>("IntUnregisteredTypeHash") > 0);
1777  }
1778  {
1779  typedef QList<UnregisteredType> UnregisteredTypeList;
1780  QVERIFY(qRegisterMetaType<UnregisteredTypeList>("UnregisteredTypeList") > 0);
1781  }
1782 
1783 
1784  REGISTER_TYPEDEF(QHash, int, uint)
1785  REGISTER_TYPEDEF(QMap, int, uint)
1786  REGISTER_TYPEDEF(QPair, int, uint)
1787 
1790  )
1791 
1794  CREATE_AND_VERIFY_CONTAINER(QList, const void*)
1796  CREATE_AND_VERIFY_CONTAINER(std::pair, void*, void*)
1797  CREATE_AND_VERIFY_CONTAINER(QHash, void*, void*)
1798  CREATE_AND_VERIFY_CONTAINER(QHash, const void*, const void*)
1799 
1800 #define TEST_OWNING_SMARTPOINTER(SMARTPOINTER, ELEMENT_TYPE, FLAG_TEST, FROMVARIANTFUNCTION) \
1801  { \
1802  SMARTPOINTER < ELEMENT_TYPE > sp(new ELEMENT_TYPE); \
1803  sp.data()->setObjectName("Test name"); \
1804  QVariant v = QVariant::fromValue(sp); \
1805  QCOMPARE(v.typeName(), #SMARTPOINTER "<" #ELEMENT_TYPE ">"); \
1806  QVERIFY(QMetaType::typeFlags(::qMetaTypeId<SMARTPOINTER < ELEMENT_TYPE > >()) & QMetaType::FLAG_TEST); \
1807  SMARTPOINTER < QObject > extractedPtr = FROMVARIANTFUNCTION<QObject>(v); \
1808  QCOMPARE(extractedPtr.data()->objectName(), sp.data()->objectName()); \
1809  }
1810 
1815 #undef TEST_OWNING_SMARTPOINTER
1816 
1817 #define TEST_NONOWNING_SMARTPOINTER(SMARTPOINTER, ELEMENT_TYPE, FLAG_TEST, FROMVARIANTFUNCTION) \
1818  { \
1819  ELEMENT_TYPE elem; \
1820  SMARTPOINTER < ELEMENT_TYPE > sp(&elem); \
1821  sp.data()->setObjectName("Test name"); \
1822  QVariant v = QVariant::fromValue(sp); \
1823  QCOMPARE(v.typeName(), #SMARTPOINTER "<" #ELEMENT_TYPE ">"); \
1824  QVERIFY(QMetaType::typeFlags(::qMetaTypeId<SMARTPOINTER < ELEMENT_TYPE > >()) & QMetaType::FLAG_TEST); \
1825  SMARTPOINTER < QObject > extractedPtr = FROMVARIANTFUNCTION<QObject>(v); \
1826  QCOMPARE(extractedPtr.data()->objectName(), sp.data()->objectName()); \
1827  }
1828 
1830  TEST_NONOWNING_SMARTPOINTER(QPointer, QFile, TrackingPointerToQObject, qPointerFromVariant)
1833 #undef TEST_NONOWNING_SMARTPOINTER
1834 
1835 
1836 #define TEST_WEAK_SMARTPOINTER(ELEMENT_TYPE, FLAG_TEST) \
1837  { \
1838  ELEMENT_TYPE elem; \
1839  QSharedPointer < ELEMENT_TYPE > shared(new ELEMENT_TYPE); \
1840  QWeakPointer < ELEMENT_TYPE > sp(shared); \
1841  sp.toStrongRef()->setObjectName("Test name"); \
1842  QVariant v = QVariant::fromValue(sp); \
1843  QCOMPARE(v.typeName(), "QWeakPointer<" #ELEMENT_TYPE ">"); \
1844  QVERIFY(QMetaType::typeFlags(::qMetaTypeId<QWeakPointer < ELEMENT_TYPE > >()) & QMetaType::FLAG_TEST); \
1845  }
1846 
1847  TEST_WEAK_SMARTPOINTER(QObject, WeakPointerToQObject)
1848  TEST_WEAK_SMARTPOINTER(QFile, WeakPointerToQObject)
1849  TEST_WEAK_SMARTPOINTER(QTemporaryFile, WeakPointerToQObject)
1850  TEST_WEAK_SMARTPOINTER(MyObject, WeakPointerToQObject)
1851 #undef TEST_WEAK_SMARTPOINTER
1852 }
1853 
1854 template <typename T>
1856 {
1857  enum { isStreamable = 1 }; // Streamable by default
1858 };
1859 
1860 // Non-streamable types
1861 
1862 #define DECLARE_NONSTREAMABLE(Type) \
1863  template<> struct StreamingTraits<Type> { enum { isStreamable = 0 }; };
1864 
1866 DECLARE_NONSTREAMABLE(void*)
1871 
1872 #define DECLARE_WIDGETS_CLASS_NONSTREAMABLE(MetaTypeName, MetaTypeId, RealType) \
1873  DECLARE_NONSTREAMABLE(RealType)
1875 #undef DECLARE_WIDGETS_CLASS_NONSTREAMABLE
1876 
1877 #undef DECLARE_NONSTREAMABLE
1878 
1879 void tst_QMetaType::saveAndLoadBuiltin_data()
1880 {
1881  QTest::addColumn<int>("type");
1882  QTest::addColumn<bool>("isStreamable");
1883 
1884 #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
1885  QTest::newRow(#RealType) << MetaTypeId << bool(StreamingTraits<RealType>::isStreamable);
1887 #undef ADD_METATYPE_TEST_ROW
1888 }
1889 
1890 void tst_QMetaType::saveAndLoadBuiltin()
1891 {
1892  QFETCH(int, type);
1893  QFETCH(bool, isStreamable);
1894 
1895  void *value = QMetaType::create(type);
1896 
1897  QByteArray ba;
1899  QCOMPARE(QMetaType::save(stream, type, value), isStreamable);
1900  QCOMPARE(stream.status(), QDataStream::Ok);
1901 
1902  if (isStreamable) {
1903  QVERIFY(QMetaType(type).hasRegisteredDataStreamOperators());
1904  QVERIFY(QMetaType::load(stream, type, value)); // Hmmm, shouldn't it return false?
1905 
1906  // std::nullptr_t is nullary: it doesn't actually read anything
1907  if (type != QMetaType::Nullptr)
1909  } else {
1910  QVERIFY(!QMetaType(type).hasRegisteredDataStreamOperators());
1911  }
1912 
1913  stream.device()->seek(0);
1914  stream.resetStatus();
1915  QCOMPARE(QMetaType::load(stream, type, value), isStreamable);
1916  QCOMPARE(stream.status(), QDataStream::Ok);
1917 
1918  if (isStreamable) {
1919  QVERIFY(QMetaType::load(stream, type, value)); // Hmmm, shouldn't it return false?
1920 
1921  // std::nullptr_t is nullary: it doesn't actually read anything
1922  if (type != QMetaType::Nullptr)
1924  }
1925 
1927 }
1928 
1930 {
1931  int a;
1932 };
1933 
1935 {
1936  out << t.a; return out;
1937 }
1938 
1940 {
1941  int a;
1942  in >> a;
1943  if (in.status() == QDataStream::Ok)
1944  t.a = a;
1945  return in;
1946 }
1948 
1949 void tst_QMetaType::saveAndLoadCustom()
1950 {
1952  t.a = 123;
1953 
1954  int id = ::qMetaTypeId<CustomStreamableType>();
1955  QByteArray ba;
1957 
1958  QVERIFY(QMetaType::save(stream, id, &t));
1959  QCOMPARE(stream.status(), QDataStream::Ok);
1960 
1962  t2.a = -1;
1963  QVERIFY(QMetaType::load(stream, id, &t2)); // Hmmm, shouldn't it return false?
1965  QCOMPARE(t2.a, -1);
1966 
1967  stream.device()->seek(0);
1968  stream.resetStatus();
1969  QVERIFY(QMetaType::load(stream, id, &t2));
1970  QCOMPARE(stream.status(), QDataStream::Ok);
1971  QCOMPARE(t2.a, t.a);
1972 
1973  QVERIFY(QMetaType::load(stream, id, &t2)); // Hmmm, shouldn't it return false?
1975 }
1976 
1977 class MyGadget {
1978  Q_GADGET;
1979 public:
1980  enum MyEnum { Val1, Val2, Val3 };
1981  Q_ENUM(MyEnum)
1982 };
1983 
1984 class MyQObjectFromGadget : public QObject, public MyGadget
1985 {
1986  Q_OBJECT
1987 public:
1989  : QObject(parent)
1990  {}
1991 };
1992 
1999 
2000 void tst_QMetaType::metaObject_data()
2001 {
2002  QTest::addColumn<int>("type");
2003  QTest::addColumn<const QMetaObject*>("result");
2004  QTest::addColumn<bool>("isGadget");
2005  QTest::addColumn<bool>("isGadgetPtr");
2006  QTest::addColumn<bool>("isQObjectPtr");
2007 
2008  QTest::newRow("QObject") << int(QMetaType::QObjectStar) << &QObject::staticMetaObject << false << false << true;
2009  QTest::newRow("QFile*") << ::qMetaTypeId<QFile*>() << &QFile::staticMetaObject << false << false << true;
2010  QTest::newRow("MyObject*") << ::qMetaTypeId<MyObject*>() << &MyObject::staticMetaObject << false << false << true;
2011  QTest::newRow("int") << int(QMetaType::Int) << static_cast<const QMetaObject *>(0) << false << false << false;
2012  QTest::newRow("QEasingCurve") << ::qMetaTypeId<QEasingCurve>() << &QEasingCurve::staticMetaObject << true << false << false;
2013  QTest::newRow("MyGadget") << ::qMetaTypeId<MyGadget>() << &MyGadget::staticMetaObject << true << false << false;
2014  QTest::newRow("MyGadget*") << ::qMetaTypeId<MyGadget*>() << &MyGadget::staticMetaObject << false << true << false;
2015  QTest::newRow("MyEnum") << ::qMetaTypeId<MyGadget::MyEnum>() << &MyGadget::staticMetaObject << false << false << false;
2016  QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &Qt::staticMetaObject << false << false << false;
2017  QTest::newRow("MyQObjectFromGadget*") << ::qMetaTypeId<MyQObjectFromGadget*>() << &MyQObjectFromGadget::staticMetaObject << false << false << true;
2018 
2019  QTest::newRow("GadgetDerivedAndTyped<int>") << ::qMetaTypeId<GadgetDerivedAndTyped<int>>() << &GadgetDerivedAndTyped<int>::staticMetaObject << true << false << false;
2020  QTest::newRow("GadgetDerivedAndTyped<int>*") << ::qMetaTypeId<GadgetDerivedAndTyped<int>*>() << &GadgetDerivedAndTyped<int>::staticMetaObject << false << true << false;
2021 }
2022 
2023 
2024 void tst_QMetaType::metaObject()
2025 {
2026  QFETCH(int, type);
2027  QFETCH(const QMetaObject *, result);
2028  QFETCH(bool, isGadget);
2029  QFETCH(bool, isGadgetPtr);
2030  QFETCH(bool, isQObjectPtr);
2031 
2032  QCOMPARE(QMetaType::metaObjectForType(type), result);
2033  QMetaType mt(type);
2034  QCOMPARE(mt.metaObject(), result);
2035  QCOMPARE(!!(mt.flags() & QMetaType::IsGadget), isGadget);
2036  QCOMPARE(!!(mt.flags() & QMetaType::PointerToGadget), isGadgetPtr);
2037  QCOMPARE(!!(mt.flags() & QMetaType::PointerToQObject), isQObjectPtr);
2038 }
2039 
2040 #define METATYPE_ID_FUNCTION(Type, MetaTypeId, Name) \
2041  case ::qMetaTypeId< Name >(): metaType = MetaTypeIdStruct<MetaTypeId>::Value; break;
2042 
2043 #define REGISTER_METATYPE_FUNCTION(Type, MetaTypeId, Name) \
2044  case qRegisterMetaType< Name >(): metaType = RegisterMetaTypeStruct<MetaTypeId>::Value; break;
2045 
2046 template<int>
2048 {
2049 };
2050 
2051 template<int>
2053 {
2054 };
2055 
2056 #define METATYPE_ID_STRUCT(Type, MetaTypeId, Name) \
2057 template<> \
2058 struct MetaTypeIdStruct< ::qMetaTypeId< Name >()> \
2059 { \
2060  enum { Value = ::qMetaTypeId< Name >() }; \
2061 };
2062 
2063 #define REGISTER_METATYPE_STRUCT(Type, MetaTypeId, Name) \
2064 template<> \
2065 struct RegisterMetaTypeStruct<qRegisterMetaType< Name >()> \
2066 { \
2067  enum { Value = qRegisterMetaType< Name >() }; \
2068 };
2069 
2072 
2073 template<int i = ::qMetaTypeId<int>()>
2075 {
2076  enum { Value };
2077 };
2078 
2079 template<int i = qRegisterMetaType<int>()>
2081 {
2082  enum { Value };
2083 };
2084 
2085 void tst_QMetaType::constexprMetaTypeIds()
2086 {
2087  int id = 0;
2088  int metaType;
2089 
2090  switch(id) {
2093  default:;
2094  }
2095 
2096  switch (id) {
2099  default:;
2100  }
2101  Q_UNUSED(metaType);
2102 }
2103 
2104 struct S {
2105  using value_type = S; // used to cause compilation error with Qt6
2106  int begin();
2107  int end();
2108 };
2109 
2110 // should not cause a compilation failure
2111 // used to cause issues due to S being equal to S::value_type
2113 
2115 #include "tst_qmetatype.moc"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
constexpr size_t getSize< void >
auto getAlignOf()
MyObject * MyObjectPtr
#define TYPENAME_DATA(MetaTypeName, MetaTypeId, RealType)
#define CHECK_BUILTIN(MetaTypeName, MetaTypeId, RealType)
QPair< int, uint > IntUIntPair
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType)
isEnumTest_Enum0
QPair< C, M > QPairCM
#define REGISTER_METATYPE_FUNCTION(Type, MetaTypeId, Name)
#define RETURN_CREATE_COPY_FUNCTION(MetaTypeName, MetaTypeId, RealType)
constexpr size_t getSize
FlagsDataEnum
QT_BEGIN_NAMESPACE QT_END_NAMESPACE typedef QPair< C, C > QPairCC
#define TEST_SEQUENTIAL_CONTAINER(CONTAINER, VALUE_TYPE)
#define TST_QMETATYPE_TYPE_DATA(MetaTypeName, MetaTypeId, RealType)
QPair< M, P > QPairMP
#define DECLARE_NONSTREAMABLE(Type)
QPair< M, M > QPairMM
#define METATYPE_ID_STRUCT(Type, MetaTypeId, Name)
#define TEST_OWNING_SMARTPOINTER(SMARTPOINTER, ELEMENT_TYPE, FLAG_TEST, FROMVARIANTFUNCTION)
#define ADD_TESTSPACE(F)
isEnumTest_Enum1
QPair< P, M > QPairPM
#define TEST_NONOWNING_SMARTPOINTER(SMARTPOINTER, ELEMENT_TYPE, FLAG_TEST, FROMVARIANTFUNCTION)
#define TEST_WEAK_SMARTPOINTER(ELEMENT_TYPE, FLAG_TEST)
#define RETURN_CREATE_FUNCTION(MetaTypeName, MetaTypeId, RealType)
#define RETURN_CONSTRUCT_COPY_FUNCTION(MetaTypeName, MetaTypeId, RealType)
#define RETURN_CONSTRUCT_FUNCTION(MetaTypeName, MetaTypeId, RealType)
#define REGISTER_METATYPE_STRUCT(Type, MetaTypeId, Name)
#define DECLARE_WIDGETS_CLASS_NONSTREAMABLE(MetaTypeName, MetaTypeId, RealType)
Q_DECLARE_METATYPE(CustomObject *)
void(* TypeTestFunction)()
QPair< P, C > QPairPC
#define METATYPE_ID_FUNCTION(Type, MetaTypeId, Name)
QPair< M, C > QPairMC
QPair< int, CustomComparable > IntComparablePair
#define TST_QMETATYPE_TYPE_DATA_ALIAS(MetaTypeName, MetaTypeId, AliasType, RealTypeString)
#define ADD_METATYPE_CASE(MetaTypeName, MetaTypeId, RealType)
QHash< int, CustomComparable > IntComparableHash
QPair< P, P > QPairPP
QPair< C, P > QPairCP
QString CustomString
QHash< int, uint > IntUIntHash
int NaturalNumber
#define value
[5]
@ Double
QHash< int, int > someHash() const
AutoMetaTypeObject(QObject *parent=nullptr)
C()=default
CustomMultiInheritanceObject(QObject *parent=nullptr)
CustomObject(QObject *parent=nullptr)
CustomQObject(QObject *parent=nullptr)
void run() override
[0]
Definition: myobject.h:58
MyObject(QObject *parent=nullptr)
MyQObjectFromGadget(QObject *parent=nullptr)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
char * data()
const char * constData() const noexcept
Definition: qbytearray.h:144
static QByteArray number(int, int base=10)
void clear()
static QByteArray fromRawData(const char *data, qsizetype size)
Definition: qbytearray.h:396
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:66
operator>>(QDataStream &ds, qfloat16 &f)
Definition: qfloat16.cpp:344
operator<<(QDataStream &ds, qfloat16 f)
Definition: qfloat16.cpp:327
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:94
bool open(OpenMode flags) override
Definition: qfile.cpp:897
T value(const Key &key) const noexcept
Definition: qhash.h:997
iterator insert(const Key &key, const T &value)
Definition: qhash.h:1228
Definition: qlist.h:108
qsizetype size() const noexcept
Definition: qlist.h:414
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
QList< T > toList() const noexcept
Definition: qlist.h:727
iterator insert(const Key &key, const T &value)
Definition: qmap.h:719
QMetaObject * toMetaObject() const
void setFlags(MetaObjectFlags)
QMetaPropertyBuilder addProperty(const QByteArray &name, const QByteArray &type, int notifierId=-1)
void setClassName(const QByteArray &name)
void setWritable(bool value)
The QMetaType class manages named types in the meta-object system.
Definition: qmetatype.h:328
bool isRegistered() const
Definition: qmetatype.cpp:521
void destruct(void *data) const
Definition: qmetatype.cpp:705
constexpr TypeFlags flags() const
Definition: qmetatype.h:2516
constexpr qsizetype sizeOf() const
Definition: qmetatype.h:2506
static QMetaType fromName(QByteArrayView name)
Definition: qmetatype.cpp:2789
void destroy(void *data) const
Definition: qmetatype.cpp:639
int id(int=0) const
Definition: qmetatype.h:453
@ NeedsDestruction
Definition: qmetatype.h:387
@ PointerToQObject
Definition: qmetatype.h:392
@ IsEnumeration
Definition: qmetatype.h:393
@ RelocatableType
Definition: qmetatype.h:388
@ NeedsConstruction
Definition: qmetatype.h:386
@ PointerToGadget
Definition: qmetatype.h:399
@ FirstWidgetsType
Definition: qmetatype.h:340
@ LastCoreType
Definition: qmetatype.h:337
@ UnknownType
Definition: qmetatype.h:346
void * create(const void *copy=nullptr) const
Definition: qmetatype.cpp:616
void * construct(void *where, const void *copy=nullptr) const
Definition: qmetatype.cpp:678
bool load(QDataStream &stream, void *data) const
Definition: qmetatype.cpp:2740
bool save(QDataStream &stream, const void *data) const
Definition: qmetatype.cpp:2699
The QModelIndex class is used to locate data in a data model.
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
Q_INVOKABLE QObject(QObject *parent=nullptr)
Definition: qobject.cpp:913
QObject * parent() const
Definition: qobject.h:409
QVariant property(const char *name) const
Definition: qobject.cpp:4118
bool setProperty(const char *name, const QVariant &value)
Definition: qobject.cpp:4063
static const QPartialOrdering Equivalent
Definition: qcompare.h:76
static const QPartialOrdering Unordered
Definition: qcompare.h:78
The QPersistentModelIndex class is used to locate data in a data model.
The QPointer class is a template class that provides guarded pointers to QObject.
Definition: qpointer.h:54
The QSharedPointer class holds a strong reference to a shared pointer.
The QString class provides a Unicode character string.
Definition: qstring.h:388
static QString fromLatin1(QByteArrayView ba)
Definition: qstring.cpp:5488
The QTemporaryFile class is an I/O device that operates on temporary files.
static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION
Definition: qthread.h:187
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
void * data()
Definition: qvariant.cpp:2464
static auto fromValue(const T &value) -> std::enable_if_t< std::is_copy_constructible_v< T >, QVariant >
Definition: qvariant.h:391
int userType() const
Definition: qvariant.h:240
T value() const
Definition: qvariant.h:378
void detach()
Definition: qvariant.cpp:1049
QMetaType metaType() const
Definition: qvariant.cpp:1003
const void * constData() const
Definition: qvariant.h:350
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:133
QList< QVariant > prop
Definition: tst_qmetatype.h:54
#define T(x)
Definition: main.cpp:42
auto mo
[7]
QCOMPARE(spy.count(), 1)
unsigned short UShort
Definition: ftraster.c:310
char Bool
Definition: ftraster.c:315
int Int
Definition: ftraster.c:307
unsigned int UInt
Definition: ftraster.c:308
short Short
Definition: ftraster.c:309
backing_store_ptr info
[4]
Definition: jmemsys.h:161
#define S(cp)
Q_TESTLIB_EXPORT QTestData & newRow(const char *dataTag)
Definition: qtestcase.cpp:2658
constexpr bool has_operator_equal_v
Definition: qtypeinfo.h:330
constexpr bool has_operator_less_than_v
Definition: qtypeinfo.h:338
ScrollBarPolicy
Definition: qnamespace.h:1276
QString self
Definition: language.cpp:80
#define QString()
Definition: parse-defines.h:51
void
Definition: png.h:1080
#define Q_FUNC_INFO
#define Q_DECL_UNUSED_MEMBER
std::pair< T1, T2 > QPair
Definition: qcontainerfwd.h:56
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLStreamKHR stream
EGLOutputLayerEXT EGLint EGLAttrib value
unsigned int quint32
Definition: qglobal.h:288
size_t quintptr
Definition: qglobal.h:310
unsigned int uint
Definition: qglobal.h:334
QList< QVariant > QVariantList
Definition: qjsonarray.h:50
#define qWarning
Definition: qlogging.h:179
QT_BEGIN_NAMESPACE void * qMallocAligned(size_t size, size_t alignment)
Definition: qmalloc.cpp:52
void qFreeAligned(void *ptr)
Definition: qmalloc.cpp:106
@ DynamicMetaObject
@ PropertyAccessInStaticMetaCall
const char * typeName
Definition: qmetatype.cpp:869
#define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)
Definition: qmetatype.h:202
#define QT_FOR_EACH_STATIC_CORE_POINTER(F)
Definition: qmetatype.h:158
int qRegisterMetaType(const char *typeName)
Definition: qmetatype.h:1291
#define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)
Definition: qmetatype.h:102
#define QT_FOR_EACH_STATIC_CORE_CLASS(F)
Definition: qmetatype.h:127
#define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)
Definition: qmetatype.h:206
#define QT_FOR_EACH_STATIC_TYPE(F)
Definition: qmetatype.h:228
GLenum type
Definition: qopengl.h:270
GLint GLfloat GLfloat GLfloat v2
GLenum GLsizei GLsizei GLint * values
[16]
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei GLenum GLenum * types
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
[4]
GLenum GLuint buffer
GLbitfield flags
GLint GLfloat GLfloat v1
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLuint name
GLint first
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
GLuint in
Definition: qopenglext.h:8870
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLfixed GLfixed GLint GLint order
Definition: qopenglext.h:5206
constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
Definition: qpair.h:55
QPointer< T > qPointerFromVariant(const QVariant &variant)
Definition: qpointer.h:119
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition: qscopeguard.h:93
QSharedPointer< typename std::enable_if< QtPrivate::IsPointerToTypeDerivedFromQObject< T * >::Value, T >::type > qSharedPointerFromVariant(const QVariant &variant)
#define QStringLiteral(str)
#define t1
#define QTEST_MAIN(TestObject)
Definition: qtest.h:664
#define QSKIP(statement,...)
Definition: qtestcase.h:222
#define QFETCH(Type, name)
Definition: qtestcase.h:230
#define QVERIFY(statement)
Definition: qtestcase.h:64
#define QFINDTESTDATA(basepath)
Definition: qtestcase.h:251
#define QVERIFY2(statement, description)
Definition: qtestcase.h:76
#define Q_ENUM(x)
Definition: qtmetamacros.h:104
#define Q_PROPERTY(...)
Definition: qtmetamacros.h:92
#define Q_OBJECT
Definition: qtmetamacros.h:158
#define Q_GADGET
Definition: qtmetamacros.h:193
@ Q_PRIMITIVE_TYPE
Definition: qtypeinfo.h:155
@ Q_RELOCATABLE_TYPE
Definition: qtypeinfo.h:156
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition: qtypeinfo.h:173
Q_UNUSED(salary)
[21]
QList< int > vector
[14]
QByteArray ba
[0]
QFile file
[0]
QStorageInfo storage
[1]
QTextStream out(stdout)
[7]
qRegisterMetaType< CustomString >("CustomString")
QSharedPointer< T > other(t)
[5]
QSize t3(10, 12)
QSize t2(10, 12)
http get(QUrl::toPercentEncoding("/index.html"))
view create()
QDBusVariant Type
void testObject()
[11]
QStringList::Iterator it
QStringList list
[0]
static int failureCount
virtual void loadOperator(QDataStream &in)=0
virtual void saveOperator(QDataStream &out) const =0
virtual ~BaseGenericType()
virtual void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a)=0
QMetaType m_metatype
virtual void * constructor(int typeId, void *where, const void *copy)=0
bool operator==(const CustomComparable &other) const
CustomComparable(int i_=0)
void saveOperator(QDataStream &out) const override
void * constructor(int typeId, void *where, const void *copy) override
void loadOperator(QDataStream &in) override
QList< QVariant > properties
void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) override
void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) override
void saveOperator(QDataStream &out) const override
void * constructor(int typeId, void *where, const void *copy) override
void loadOperator(QDataStream &in) override
QByteArray podData
StaticMetacallFunction static_metacall
Definition: qobjectdefs.h:435
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:165
struct QMetaObject::Data d
static QByteArray normalizedType(const char *type)
int begin()
int end()
Definition: moc.h:48
const QByteArray testData("test")
MyEnum
Definition: tst_qflags.cpp:497
#define PRINT_1ARG_TEMPLATE(RealName)
#define CREATE_AND_VERIFY_CONTAINER(CONTAINER,...)
#define REGISTER_TYPEDEF(TYPE, ARG1, ARG2)
#define FOR_EACH_STATIC_PRIMITIVE_TYPE(F)
#define FOR_EACH_PRIMITIVE_METATYPE(F)
#define FOR_EACH_CORE_METATYPE(F)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent