diff options
-rw-r--r-- | src/corelib/global/qglobal.cpp | 7 | ||||
-rw-r--r-- | src/corelib/global/qtypeinfo.h | 28 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 24 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qpair/tst_qpair.cpp | 4 |
4 files changed, 51 insertions, 12 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 8da94c8624..c0d46b73d9 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -4103,6 +4103,13 @@ bool qunsetenv(const char *varName) Example of a movable type: \snippet code/src_corelib_global_qglobal.cpp 39 + + Qt will try to detect the class of a type using std::is_trivial or + std::is_trivially_copyable. Use this macro to tune the behavior. + For instance many types would be candidates for Q_MOVABLE_TYPE despite + not being trivially-copyable. For binary compatibility reasons, QList + optimizations are only enabled if there is an explicit + Q_DECLARE_TYPEINFO even for trivially-copyable types. */ /*! diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index 4f79c48c51..567ff5c08e 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -49,6 +49,26 @@ QT_BEGIN_NAMESPACE QTypeInfo - type trait functionality */ +template <typename T> +static constexpr bool qIsRelocatable() +{ +#if defined(Q_CC_CLANG) || !defined(Q_CC_GNU) || Q_CC_GNU >= 501 + return std::is_trivially_copyable<T>::value && std::is_trivially_destructible<T>::value; +#else + return std::is_enum<T>::value || std::is_integral<T>::value; +#endif +} + +template <typename T> +static constexpr bool qIsTrivial() +{ +#if defined(Q_CC_CLANG) || !defined(Q_CC_GNU) || Q_CC_GNU >= 501 + return std::is_trivial<T>::value; +#else + return std::is_enum<T>::value || std::is_integral<T>::value; +#endif +} + /* The catch-all template. */ @@ -61,9 +81,9 @@ public: isSpecialized = std::is_enum<T>::value, // don't require every enum to be marked manually isPointer = false, isIntegral = std::is_integral<T>::value, - isComplex = !isIntegral && !std::is_enum<T>::value, + isComplex = !qIsTrivial<T>(), isStatic = true, - isRelocatable = std::is_enum<T>::value, + isRelocatable = qIsRelocatable<T>(), isLarge = (sizeof(T)>sizeof(void*)), isDummy = false, //### Qt6: remove sizeOf = sizeof(T) @@ -248,9 +268,9 @@ class QTypeInfo<TYPE > \ public: \ enum { \ isSpecialized = true, \ - isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \ + isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && !qIsTrivial<TYPE>(), \ isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \ - isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE), \ + isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE) || qIsRelocatable<TYPE>(), \ isLarge = (sizeof(TYPE)>sizeof(void*)), \ isPointer = false, \ isIntegral = std::is_integral< TYPE >::value, \ diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 0c328dff58..fb11e4c522 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -342,6 +342,7 @@ struct Bar ++failureCount; } } + ~Bar() {} public: static int failureCount; @@ -458,7 +459,7 @@ void tst_QMetaType::threadSafety() namespace TestSpace { - struct Foo { double d; }; + struct Foo { double d; public: ~Foo() {} }; struct QungTfu {}; } Q_DECLARE_METATYPE(TestSpace::Foo) @@ -515,11 +516,17 @@ void tst_QMetaType::properties() } template <typename T> -struct Whity { T t; }; +struct Whity { T t; Whity() {} }; Q_DECLARE_METATYPE( Whity < int > ) Q_DECLARE_METATYPE(Whity<double>) +#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501 +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(Whity<double>, Q_MOVABLE_TYPE); +QT_END_NAMESPACE +#endif + void tst_QMetaType::normalizedTypes() { int WhityIntId = ::qMetaTypeId<Whity<int> >(); @@ -818,10 +825,13 @@ void tst_QMetaType::sizeOfStaticLess() QCOMPARE(size_t(QMetaType(type).sizeOf()), size); } -struct CustomMovable {}; +struct CustomMovable { CustomMovable() {} }; +#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501 QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(CustomMovable, Q_MOVABLE_TYPE); QT_END_NAMESPACE +#endif + Q_DECLARE_METATYPE(CustomMovable); class CustomObject : public QObject @@ -850,13 +860,15 @@ public: }; Q_DECLARE_METATYPE(CustomMultiInheritanceObject*); -class C { char _[4]; }; -class M { char _[4]; }; +class C { char _[4]; public: C() = default; C(const C&) {} }; +class M { char _[4]; public: M() {} }; class P { char _[4]; }; QT_BEGIN_NAMESPACE +#if defined(Q_CC_GNU) && Q_CC_GNU < 501 Q_DECLARE_TYPEINFO(M, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(P, Q_PRIMITIVE_TYPE); +#endif QT_END_NAMESPACE // avoid the comma: @@ -902,7 +914,7 @@ 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 QTest::newRow("TestSpace::Foo") << ::qMetaTypeId<TestSpace::Foo>() << false << true << false << false; - QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << false << true << false << false; + QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << true << true << false << false; QTest::newRow("CustomMovable") << ::qMetaTypeId<CustomMovable>() << true << true << false << false; QTest::newRow("CustomObject*") << ::qMetaTypeId<CustomObject*>() << true << false << true << false; QTest::newRow("CustomMultiInheritanceObject*") << ::qMetaTypeId<CustomMultiInheritanceObject*>() << true << false << true << false; diff --git a/tests/auto/corelib/tools/qpair/tst_qpair.cpp b/tests/auto/corelib/tools/qpair/tst_qpair.cpp index 1d5f7536c8..dedc353e67 100644 --- a/tests/auto/corelib/tools/qpair/tst_qpair.cpp +++ b/tests/auto/corelib/tools/qpair/tst_qpair.cpp @@ -41,8 +41,8 @@ private Q_SLOTS: void taskQTBUG_48780_pairContainingCArray(); }; -class C { char _[4]; }; -class M { char _[4]; }; +class C { C() {} char _[4]; }; +class M { M() {} char _[4]; }; class P { char _[4]; }; QT_BEGIN_NAMESPACE |