diff options
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 51 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 18 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype_p.h | 39 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 3 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 124 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h | 2 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp | 67 |
7 files changed, 242 insertions, 62 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index f2676fa48f..16d51ae7a1 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -414,7 +414,9 @@ const char *QtMetaTypePrivate::typedefNameForType(const QtPrivate::QMetaTypeInte The enum describes attributes of a type supported by QMetaType. - \value NeedsConstruction This type has non-trivial constructors. If the flag is not set instances can be safely initialized with memset to 0. + \value NeedsConstruction This type has a non-trivial default constructor. If the flag is not set, instances can be safely initialized with memset to 0. + \value NeedsCopyConstruction (since 6.5) This type has a non-trivial copy construtcor. If the flag is not set, instances can be copied with memcpy. + \value NeedsMoveConstruction (since 6.5) This type has a non-trivial move constructor. If the flag is not set, instances can be moved with memcpy. \value NeedsDestruction This type has a non-trivial destructor. If the flag is not set calls to the destructor are not necessary before discarding objects. \value RelocatableType An instance of a type having this attribute can be safely moved to a different memory location using memcpy. \omitvalue MovableType @@ -429,6 +431,14 @@ const char *QtMetaTypePrivate::typedefNameForType(const QtPrivate::QMetaTypeInte \omitvalue PointerToGadget \omitvalue IsQmlList \value IsConst Indicates that values of this types are immutable; for instance because they are pointers to const objects. + + \note Before Qt 6.5, both the NeedsConstruction and NeedsDestruction flags + were incorrectly set if the either copy construtor or destructor were + non-trivial (that is, if the type was not trivial). + + Note that the Needs flags may be set but the meta type may not have a + publicly-accessible constructor of the relevant type or a + publicly-accessible destructor. */ /*! @@ -598,16 +608,17 @@ int QMetaType::registerHelper(const QtPrivate::QMetaTypeInterface *iface) */ void *QMetaType::create(const void *copy) const { - if (d_ptr && (copy ? !!d_ptr->copyCtr : !!d_ptr->defaultCtr)) { - void *where = + if (copy ? !isCopyConstructible() : !isDefaultConstructible()) + return nullptr; + + void *where = #ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__ d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__ ? operator new(d_ptr->size, std::align_val_t(d_ptr->alignment)) : #endif operator new(d_ptr->size); - return construct(where, copy); - } - return nullptr; + QtMetaTypePrivate::construct(d_ptr, where, copy); + return where; } /*! @@ -621,9 +632,8 @@ void *QMetaType::create(const void *copy) const */ void QMetaType::destroy(void *data) const { - if (d_ptr) { - if (d_ptr->dtor) - d_ptr->dtor(d_ptr, data); + if (data && isDestructible()) { + QtMetaTypePrivate::destruct(d_ptr, data); if (d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { operator delete(data, std::align_val_t(d_ptr->alignment)); } else { @@ -662,16 +672,11 @@ void *QMetaType::construct(void *where, const void *copy) const { if (!where) return nullptr; - if (d_ptr) { - if (copy && d_ptr->copyCtr) { - d_ptr->copyCtr(d_ptr, where, copy); - return where; - } else if (!copy && d_ptr->defaultCtr) { - d_ptr->defaultCtr(d_ptr, where); - return where; - } - } - return nullptr; + if (copy ? !isCopyConstructible() : !isDefaultConstructible()) + return nullptr; + + QtMetaTypePrivate::construct(d_ptr, where, copy); + return where; } /*! @@ -687,12 +692,8 @@ void *QMetaType::construct(void *where, const void *copy) const */ void QMetaType::destruct(void *data) const { - if (!data) - return; - if (d_ptr && d_ptr->dtor) { - d_ptr->dtor(d_ptr, data); - return; - } + if (data && isDestructible()) + QtMetaTypePrivate::destruct(d_ptr, data); } static QPartialOrdering threeWayCompare(const void *ptr1, const void *ptr2) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 28d246d2cf..7a66767258 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -381,6 +381,9 @@ public: IsPointer = 0x800, IsQmlList =0x1000, // used in the QML engine to recognize QQmlListProperty<T> and list<T> IsConst = 0x2000, + // since 6.5: + NeedsCopyConstruction = 0x4000, + NeedsMoveConstruction = 0x8000, }; Q_DECLARE_FLAGS(TypeFlags, TypeFlag) @@ -1187,8 +1190,10 @@ namespace QtPrivate { struct QMetaTypeTypeFlags { enum { Flags = (QTypeInfo<T>::isRelocatable ? QMetaType::RelocatableType : 0) - | (QTypeInfo<T>::isComplex ? QMetaType::NeedsConstruction : 0) - | (QTypeInfo<T>::isComplex ? QMetaType::NeedsDestruction : 0) + | (!std::is_trivially_default_constructible_v<T> ? QMetaType::NeedsConstruction : 0) + | (!std::is_trivially_destructible_v<T> ? QMetaType::NeedsDestruction : 0) + | (!std::is_trivially_copy_constructible_v<T> ? QMetaType::NeedsCopyConstruction : 0) + | (!std::is_trivially_move_constructible_v<T> ? QMetaType::NeedsMoveConstruction : 0) | (IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : 0) | (IsSharedPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::SharedPointerToQObject : 0) | (IsWeakPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::WeakPointerToQObject : 0) @@ -2312,10 +2317,11 @@ class QMetaTypeForType { public: static constexpr decltype(typenameHelper<S>()) name = typenameHelper<S>(); + static constexpr unsigned Flags = QMetaTypeTypeFlags<S>::Flags; static constexpr QMetaTypeInterface::DefaultCtrFn getDefaultCtr() { - if constexpr (std::is_default_constructible_v<S>) { + if constexpr (std::is_default_constructible_v<S> && !std::is_trivially_default_constructible_v<S>) { return [](const QMetaTypeInterface *, void *addr) { new (addr) S(); }; } else { return nullptr; @@ -2324,7 +2330,7 @@ public: static constexpr QMetaTypeInterface::CopyCtrFn getCopyCtr() { - if constexpr (std::is_copy_constructible_v<S>) { + if constexpr (std::is_copy_constructible_v<S> && !std::is_trivially_copy_constructible_v<S>) { return [](const QMetaTypeInterface *, void *addr, const void *other) { new (addr) S(*reinterpret_cast<const S *>(other)); }; @@ -2335,7 +2341,7 @@ public: static constexpr QMetaTypeInterface::MoveCtrFn getMoveCtr() { - if constexpr (std::is_move_constructible_v<S>) { + if constexpr (std::is_move_constructible_v<S> && !std::is_trivially_move_constructible_v<S>) { return [](const QMetaTypeInterface *, void *addr, void *other) { new (addr) S(std::move(*reinterpret_cast<S *>(other))); }; @@ -2386,7 +2392,7 @@ struct QMetaTypeInterfaceWrapper /*.revision=*/ 0, /*.alignment=*/ alignof(T), /*.size=*/ sizeof(T), - /*.flags=*/ QMetaTypeTypeFlags<T>::Flags, + /*.flags=*/ QMetaTypeForType<T>::Flags, /*.typeId=*/ BuiltinMetaType<T>::value, /*.metaObjectFn=*/ MetaObjectForType<T>::metaObjectFunction, /*.name=*/ QMetaTypeForType<T>::getName(), diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 89f1854bf6..08c1aeaa1d 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -141,21 +141,52 @@ inline bool isDefaultConstructible(const QtPrivate::QMetaTypeInterface *iface) n inline bool isCopyConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept { - // ### broken - return checkMetaTypeFlagOrPointer(iface, iface->copyCtr, QMetaType::NeedsConstruction); + return checkMetaTypeFlagOrPointer(iface, iface->copyCtr, QMetaType::NeedsCopyConstruction); } inline bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept { - return iface->moveCtr; + return checkMetaTypeFlagOrPointer(iface, iface->moveCtr, QMetaType::NeedsMoveConstruction); } inline bool isDestructible(const QtPrivate::QMetaTypeInterface *iface) noexcept { - // ### broken return checkMetaTypeFlagOrPointer(iface, iface->dtor, QMetaType::NeedsDestruction); } +inline void defaultConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where) +{ + Q_ASSERT(isDefaultConstructible(iface)); + if (iface->defaultCtr) + iface->defaultCtr(iface, where); + else + memset(where, 0, iface->size); +} + +inline void copyConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy) +{ + Q_ASSERT(isCopyConstructible(iface)); + if (iface->copyCtr) + iface->copyCtr(iface, where, copy); + else + memcpy(where, copy, iface->size); +} + +inline void construct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy) +{ + if (copy) + copyConstruct(iface, where, copy); + else + defaultConstruct(iface, where); +} + +inline void destruct(const QtPrivate::QMetaTypeInterface *iface, void *where) +{ + Q_ASSERT(isDestructible(iface)); + if (iface->dtor) + iface->dtor(iface, where); +} + const char *typedefNameForType(const QtPrivate::QMetaTypeInterface *type_d); template<typename T> diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 59148e1579..0fd14296e9 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -222,7 +222,8 @@ static void customConstruct(QVariant::Private *d, const void *copy) return; } - if (!isCopyConstructible(iface) || (!copy && !isDefaultConstructible(iface))) { + if (!isCopyConstructible(iface) || (!copy && !isDefaultConstructible(iface)) + || !isDestructible(iface)) { *d = QVariant::Private(); qWarning("QVariant: Provided metatype does not support " "destruction, copy and default construction"); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index c25c5c6b16..dc7936cb23 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -397,13 +397,15 @@ protected: ++failureCount; qWarning() << "Wrong typeInfo returned for" << tp; } - if (!info.isRegistered()) { + if (info.flags() != (QMetaType::NeedsConstruction | QMetaType::NeedsDestruction | + QMetaType::NeedsCopyConstruction | QMetaType::NeedsMoveConstruction)) { ++failureCount; - qWarning() << name << "is not a registered metatype"; + qWarning() << "Wrong typeInfo returned for" << tp << "got" + << Qt::showbase << Qt::hex << info.flags(); } - if (QMetaType::typeFlags(tp) != (QMetaType::NeedsConstruction | QMetaType::NeedsDestruction)) { + if (!info.isRegistered()) { ++failureCount; - qWarning() << "Wrong typeInfo returned for" << tp; + qWarning() << name << "is not a registered metatype"; } if (!QMetaType::isRegistered(tp)) { ++failureCount; @@ -981,7 +983,9 @@ template <typename T> void addFlagsRow(const char *name, int id = qMetaTypeId<T> QTest::newRow(name) << id << bool(QTypeInfo<T>::isRelocatable) - << bool(QTypeInfo<T>::isComplex) + << bool(!std::is_trivially_default_constructible_v<T>) + << bool(!std::is_trivially_copy_constructible_v<T>) + << bool(!std::is_trivially_destructible_v<T>) << bool(QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value) << bool(std::is_enum<T>::value) << false; @@ -991,15 +995,17 @@ void tst_QMetaType::flags_data() { QTest::addColumn<int>("type"); QTest::addColumn<bool>("isRelocatable"); - QTest::addColumn<bool>("isComplex"); + QTest::addColumn<bool>("needsConstruction"); + QTest::addColumn<bool>("needsCopyConstruction"); + QTest::addColumn<bool>("needsDestruction"); QTest::addColumn<bool>("isPointerToQObject"); QTest::addColumn<bool>("isEnum"); QTest::addColumn<bool>("isQmlList"); // invalid ids. - QTest::newRow("-1") << -1 << false << false << false << false << false; - QTest::newRow("-124125534") << -124125534 << false << false << false << false << false; - QTest::newRow("124125534") << 124125534 << false << false << false << false << false; + QTest::newRow("-1") << -1 << false << false << false << false << false << false << false; + QTest::newRow("-124125534") << -124125534 << false << false << false << false << false << false << false; + QTest::newRow("124125534") << 124125534 << false << false << false << false << false << false << false; #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ addFlagsRow<RealType>(#RealType, MetaTypeId); @@ -1029,7 +1035,9 @@ void tst_QMetaType::flags() { QFETCH(int, type); QFETCH(bool, isRelocatable); - QFETCH(bool, isComplex); + QFETCH(bool, needsConstruction); + QFETCH(bool, needsCopyConstruction); + QFETCH(bool, needsDestruction); QFETCH(bool, isPointerToQObject); QFETCH(bool, isEnum); QFETCH(bool, isQmlList); @@ -1037,14 +1045,92 @@ void tst_QMetaType::flags() ignoreInvalidMetaTypeWarning(type); QMetaType meta(type); - QCOMPARE(bool(meta.flags() & QMetaType::NeedsConstruction), isComplex); - QCOMPARE(bool(meta.flags() & QMetaType::NeedsDestruction), isComplex); + QCOMPARE(bool(meta.flags() & QMetaType::NeedsConstruction), needsConstruction); + QCOMPARE(bool(meta.flags() & QMetaType::NeedsCopyConstruction), needsCopyConstruction); + QCOMPARE(bool(meta.flags() & QMetaType::NeedsDestruction), needsDestruction); QCOMPARE(bool(meta.flags() & QMetaType::RelocatableType), isRelocatable); QCOMPARE(bool(meta.flags() & QMetaType::PointerToQObject), isPointerToQObject); QCOMPARE(bool(meta.flags() & QMetaType::IsEnumeration), isEnum); QCOMPARE(bool(meta.flags() & QMetaType::IsQmlList), isQmlList); } +class NonDefaultConstructible +{ + NonDefaultConstructible(int) {} +}; + +struct MoveOnly +{ + MoveOnly() = default; + MoveOnly(const MoveOnly &) = delete; + MoveOnly(MoveOnly &&) = default; + MoveOnly &operator=(const MoveOnly &) = delete; + MoveOnly &operator=(MoveOnly &&) = default; +}; + +class Indestructible +{ +protected: + ~Indestructible() {} +}; + +template <typename T> static void addFlags2Row(QMetaType metaType = QMetaType::fromType<T>()) +{ + QTest::newRow(metaType.name() ? metaType.name() : "UnknownType") + << metaType + << std::is_default_constructible_v<T> + << std::is_copy_constructible_v<T> + << std::is_move_constructible_v<T> + << std::is_destructible_v<T> + << (QTypeTraits::has_operator_equal<T>::value || QTypeTraits::has_operator_less_than<T>::value) + << QTypeTraits::has_operator_less_than<T>::value; +}; + +void tst_QMetaType::flags2_data() +{ + QTest::addColumn<QMetaType>("type"); + QTest::addColumn<bool>("isDefaultConstructible"); + QTest::addColumn<bool>("isCopyConstructible"); + QTest::addColumn<bool>("isMoveConstructible"); + QTest::addColumn<bool>("isDestructible"); + QTest::addColumn<bool>("isEqualityComparable"); + QTest::addColumn<bool>("isOrdered"); + + addFlags2Row<void>(QMetaType()); + addFlags2Row<void>(); + +#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ + addFlags2Row<RealType>(); + QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(ADD_METATYPE_TEST_ROW) + QT_FOR_EACH_STATIC_CORE_CLASS(ADD_METATYPE_TEST_ROW) + QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(ADD_METATYPE_TEST_ROW) + QT_FOR_EACH_STATIC_CORE_POINTER(ADD_METATYPE_TEST_ROW) +#undef ADD_METATYPE_TEST_ROW + + addFlags2Row<NonDefaultConstructible>(); + addFlags2Row<MoveOnly>(); + addFlags2Row<QObject>(); + addFlags2Row<Indestructible>(); +} + +void tst_QMetaType::flags2() +{ + QFETCH(QMetaType, type); + QFETCH(bool, isDefaultConstructible); + QFETCH(bool, isCopyConstructible); + QFETCH(bool, isMoveConstructible); + QFETCH(bool, isDestructible); + QFETCH(bool, isEqualityComparable); + QFETCH(bool, isOrdered); + + QCOMPARE(type.isDefaultConstructible(), isDefaultConstructible); + QCOMPARE(type.isCopyConstructible(), isCopyConstructible); + QCOMPARE(type.isMoveConstructible(), isMoveConstructible); + QCOMPARE(type.isDestructible(), isDestructible); + QCOMPARE(type.isEqualityComparable(), isEqualityComparable); + QCOMPARE(type.isOrdered(), isOrdered); +} + void tst_QMetaType::flagsBinaryCompatibility6_0_data() { // Changing traits of a built-in type is illegal from BC point of view. @@ -1092,14 +1178,12 @@ void tst_QMetaType::flagsBinaryCompatibility6_0() const auto currentFlags = QMetaType::typeFlags(id); auto expectedFlags = QMetaType::TypeFlags(flags); - if (!(currentFlags.testFlag(QMetaType::NeedsConstruction) && currentFlags.testFlag(QMetaType::NeedsDestruction))) { - if (expectedFlags.testFlag(QMetaType::NeedsConstruction) && expectedFlags.testFlag(QMetaType::NeedsDestruction)) { - // If type changed from RELOCATABLE to trivial, that's fine - expectedFlags.setFlag(QMetaType::NeedsConstruction, false); - expectedFlags.setFlag(QMetaType::NeedsDestruction, false); - } - } - quint32 mask_5_0 = 0x1fb; // Only compare the values that were already defined in 5.0 + + // Only compare the values that were already defined in 5.0. + // In 6.5, some types lost NeedsConstruction and NeedsDestruction, but + // that's acceptable if that's because they were trivial + quint32 mask_5_0 = 0x1ff & ~quint32(QMetaType::NeedsConstruction | QMetaType::NeedsDestruction + | QMetaType::RelocatableType); QCOMPARE(quint32(currentFlags) & mask_5_0, quint32(expectedFlags) & mask_5_0); } diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h index 37d9f958e9..796d64c5a3 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h @@ -69,6 +69,8 @@ private slots: void alignOf(); void flags_data(); void flags(); + void flags2_data(); + void flags2(); void flagsBinaryCompatibility6_0_data(); void flagsBinaryCompatibility6_0(); void construct_data(); diff --git a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp index f4d64567ec..686e2a0e8b 100644 --- a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp +++ b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp @@ -20,6 +20,8 @@ private slots: void sizeOf(); void flags_data(); void flags(); + void flags2_data(); + void flags2(); void construct_data(); void construct(); void constructCopy_data(); @@ -298,15 +300,19 @@ template <typename T> void addFlagsRow(const char *name, int id = qMetaTypeId<T> QTest::newRow(name) << id << bool(QTypeInfo<T>::isRelocatable) - << bool(QTypeInfo<T>::isComplex); + << bool(!std::is_trivially_default_constructible_v<T>) + << bool(!std::is_trivially_copy_constructible_v<T>) + << bool(!std::is_trivially_destructible_v<T>); } - +// tst_QGuiMetaType::flags is nearly identical to tst_QMetaType::flags void tst_QGuiMetaType::flags_data() { QTest::addColumn<int>("type"); QTest::addColumn<bool>("isRelocatable"); - QTest::addColumn<bool>("isComplex"); + QTest::addColumn<bool>("needsConstruction"); + QTest::addColumn<bool>("needsCopyConstruction"); + QTest::addColumn<bool>("needsDestruction"); #define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ addFlagsRow<RealType>(#RealType, MetaTypeId); @@ -318,13 +324,62 @@ void tst_QGuiMetaType::flags() { QFETCH(int, type); QFETCH(bool, isRelocatable); - QFETCH(bool, isComplex); + QFETCH(bool, needsConstruction); + QFETCH(bool, needsCopyConstruction); + QFETCH(bool, needsDestruction); - QCOMPARE(bool(QMetaType(type).flags() & QMetaType::NeedsConstruction), isComplex); - QCOMPARE(bool(QMetaType(type).flags() & QMetaType::NeedsDestruction), isComplex); + QCOMPARE(bool(QMetaType(type).flags() & QMetaType::NeedsConstruction), needsConstruction); + QCOMPARE(bool(QMetaType(type).flags() & QMetaType::NeedsCopyConstruction), needsCopyConstruction); + QCOMPARE(bool(QMetaType(type).flags() & QMetaType::NeedsDestruction), needsDestruction); QCOMPARE(bool(QMetaType(type).flags() & QMetaType::RelocatableType), isRelocatable); } +template <typename T> static void addFlags2Row(QMetaType metaType = QMetaType::fromType<T>()) +{ + QTest::newRow(metaType.name() ? metaType.name() : "UnknownType") + << metaType + << std::is_default_constructible_v<T> + << std::is_copy_constructible_v<T> + << std::is_move_constructible_v<T> + << std::is_destructible_v<T> + << (QTypeTraits::has_operator_equal<T>::value || QTypeTraits::has_operator_less_than<T>::value) + << QTypeTraits::has_operator_less_than<T>::value; +}; + +// tst_QGuiMetaType::flags2 is nearly identical to tst_QMetaType::flags2 +void tst_QGuiMetaType::flags2_data() +{ + QTest::addColumn<QMetaType>("type"); + QTest::addColumn<bool>("isDefaultConstructible"); + QTest::addColumn<bool>("isCopyConstructible"); + QTest::addColumn<bool>("isMoveConstructible"); + QTest::addColumn<bool>("isDestructible"); + QTest::addColumn<bool>("isEqualityComparable"); + QTest::addColumn<bool>("isOrdered"); + +#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \ + addFlags2Row<RealType>(); +QT_FOR_EACH_STATIC_GUI_CLASS(ADD_METATYPE_TEST_ROW) +#undef ADD_METATYPE_TEST_ROW +} + +void tst_QGuiMetaType::flags2() +{ + QFETCH(QMetaType, type); + QFETCH(bool, isDefaultConstructible); + QFETCH(bool, isCopyConstructible); + QFETCH(bool, isMoveConstructible); + QFETCH(bool, isDestructible); + QFETCH(bool, isEqualityComparable); + QFETCH(bool, isOrdered); + + QCOMPARE(type.isDefaultConstructible(), isDefaultConstructible); + QCOMPARE(type.isCopyConstructible(), isCopyConstructible); + QCOMPARE(type.isMoveConstructible(), isMoveConstructible); + QCOMPARE(type.isDestructible(), isDestructible); + QCOMPARE(type.isEqualityComparable(), isEqualityComparable); + QCOMPARE(type.isOrdered(), isOrdered); +} void tst_QGuiMetaType::construct_data() { |