From 15c13b91e66b0bd0d179f0303bb17c7793f80a07 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Tue, 7 Feb 2012 12:25:07 +1000 Subject: Add Q_IS_ENUM(), and provide as flag in QMetaType::typeFlags() Add Q_IS_ENUM() macro to determine if a given type is an enumeration. Use information from that in QMetaType::registerType() to store whether custom registered metatypes are enums or not. This information can then be accessed by calling QMetaType::typeFlags(int type). This is used by the declarative code to determine whether a custom type in a variant can be safely cast to an integer, which is required to allow passing non-local enums as signal/slot params. Change-Id: I9733837f56af201fa3017b4a22b761437a3c0de4 Reviewed-by: Lars Knoll --- tests/auto/corelib/global/qglobal/tst_qglobal.cpp | 122 +++++++++++++++++++++ .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 34 ++++++ 2 files changed, 156 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp index 8fedaf427a..b3d76bef8a 100644 --- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp +++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp @@ -41,10 +41,12 @@ #include +#include class tst_QGlobal: public QObject { Q_OBJECT + private slots: void qIsNull(); void for_each(); @@ -53,6 +55,7 @@ private slots: void checkptr(); void qstaticassert(); void qConstructorFunction(); + void isEnum(); }; void tst_QGlobal::qIsNull() @@ -293,5 +296,124 @@ void tst_QGlobal::qConstructorFunction() QCOMPARE(qConstructorFunctionValue, 123); } +struct isEnum_A { + int n_; +}; + +enum isEnum_B_Byte { isEnum_B_Byte_x = 63 }; +enum isEnum_B_Short { isEnum_B_Short_x = 1024 }; +enum isEnum_B_Int { isEnum_B_Int_x = 1 << 20 }; + +union isEnum_C {}; + +class isEnum_D { +public: + operator int() const; +}; + +class isEnum_E { +private: + operator int() const; +}; + +class isEnum_F { +public: + enum AnEnum {}; +}; + +#if defined (Q_COMPILER_CLASS_ENUM) +enum class isEnum_G : qint64 {}; +#endif + +void tst_QGlobal::isEnum() +{ +#if defined (Q_CC_MSVC) +#define IS_ENUM_TRUE(x) (Q_IS_ENUM(x) == true) +#define IS_ENUM_FALSE(x) (Q_IS_ENUM(x) == false) +#else +#define IS_ENUM_TRUE(x) (Q_IS_ENUM(x) == true && QtPrivate::is_enum::value == true) +#define IS_ENUM_FALSE(x) (Q_IS_ENUM(x) == false && QtPrivate::is_enum::value == false) +#endif + + QVERIFY(IS_ENUM_TRUE(isEnum_B_Byte)); + QVERIFY(IS_ENUM_TRUE(const isEnum_B_Byte)); + QVERIFY(IS_ENUM_TRUE(volatile isEnum_B_Byte)); + QVERIFY(IS_ENUM_TRUE(const volatile isEnum_B_Byte)); + + QVERIFY(IS_ENUM_TRUE(isEnum_B_Short)); + QVERIFY(IS_ENUM_TRUE(const isEnum_B_Short)); + QVERIFY(IS_ENUM_TRUE(volatile isEnum_B_Short)); + QVERIFY(IS_ENUM_TRUE(const volatile isEnum_B_Short)); + + QVERIFY(IS_ENUM_TRUE(isEnum_B_Int)); + QVERIFY(IS_ENUM_TRUE(const isEnum_B_Int)); + QVERIFY(IS_ENUM_TRUE(volatile isEnum_B_Int)); + QVERIFY(IS_ENUM_TRUE(const volatile isEnum_B_Int)); + + QVERIFY(IS_ENUM_TRUE(isEnum_F::AnEnum)); + QVERIFY(IS_ENUM_TRUE(const isEnum_F::AnEnum)); + QVERIFY(IS_ENUM_TRUE(volatile isEnum_F::AnEnum)); + QVERIFY(IS_ENUM_TRUE(const volatile isEnum_F::AnEnum)); + + QVERIFY(IS_ENUM_FALSE(void)); + QVERIFY(IS_ENUM_FALSE(isEnum_B_Byte &)); + QVERIFY(IS_ENUM_FALSE(isEnum_B_Byte[1])); + QVERIFY(IS_ENUM_FALSE(const isEnum_B_Byte[1])); + QVERIFY(IS_ENUM_FALSE(isEnum_B_Byte[])); + QVERIFY(IS_ENUM_FALSE(int)); + QVERIFY(IS_ENUM_FALSE(float)); + QVERIFY(IS_ENUM_FALSE(isEnum_A)); + QVERIFY(IS_ENUM_FALSE(isEnum_A *)); + QVERIFY(IS_ENUM_FALSE(const isEnum_A)); + QVERIFY(IS_ENUM_FALSE(isEnum_C)); + QVERIFY(IS_ENUM_FALSE(isEnum_D)); + QVERIFY(IS_ENUM_FALSE(isEnum_E)); + QVERIFY(IS_ENUM_FALSE(void())); + QVERIFY(IS_ENUM_FALSE(void(*)())); + QVERIFY(IS_ENUM_FALSE(int isEnum_A::*)); + QVERIFY(IS_ENUM_FALSE(void (isEnum_A::*)())); + + QVERIFY(IS_ENUM_FALSE(size_t)); + QVERIFY(IS_ENUM_FALSE(bool)); + QVERIFY(IS_ENUM_FALSE(wchar_t)); + + QVERIFY(IS_ENUM_FALSE(char)); + QVERIFY(IS_ENUM_FALSE(unsigned char)); + QVERIFY(IS_ENUM_FALSE(short)); + QVERIFY(IS_ENUM_FALSE(unsigned short)); + QVERIFY(IS_ENUM_FALSE(int)); + QVERIFY(IS_ENUM_FALSE(unsigned int)); + QVERIFY(IS_ENUM_FALSE(long)); + QVERIFY(IS_ENUM_FALSE(unsigned long)); + + QVERIFY(IS_ENUM_FALSE(qint8)); + QVERIFY(IS_ENUM_FALSE(quint8)); + QVERIFY(IS_ENUM_FALSE(qint16)); + QVERIFY(IS_ENUM_FALSE(quint16)); + QVERIFY(IS_ENUM_FALSE(qint32)); + QVERIFY(IS_ENUM_FALSE(quint32)); + QVERIFY(IS_ENUM_FALSE(qint64)); + QVERIFY(IS_ENUM_FALSE(quint64)); + + QVERIFY(IS_ENUM_FALSE(void *)); + QVERIFY(IS_ENUM_FALSE(int *)); + +#if defined (Q_COMPILER_UNICODE_STRINGS) + QVERIFY(IS_ENUM_FALSE(char16_t)); + QVERIFY(IS_ENUM_FALSE(char32_t)); +#endif + +#if defined (Q_COMPILER_CLASS_ENUM) + // Strongly type class enums are not handled by the + // fallback type traits implementation. Any compiler + // supported by Qt that supports C++0x class enums + // should also support the __is_enum intrinsic. + QVERIFY(Q_IS_ENUM(isEnum_G) == true); +#endif + +#undef IS_ENUM_TRUE +#undef IS_ENUM_FALSE +} + QTEST_MAIN(tst_QGlobal) #include "tst_qglobal.moc" diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 3c21a5053f..bc5fa2716b 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -94,6 +94,7 @@ private slots: void isRegistered(); void isRegisteredStaticLess_data(); void isRegisteredStaticLess(); + void isEnum(); void registerStreamBuiltin(); void automaticTemplateRegistration(); }; @@ -1042,6 +1043,39 @@ void tst_QMetaType::isRegistered() QCOMPARE(QMetaType::isRegistered(typeId), registered); } +enum isEnumTest_Enum0 {}; +struct isEnumTest_Struct0 { enum A{}; }; + +enum isEnumTest_Enum1 {}; +struct isEnumTest_Struct1 {}; + +Q_DECLARE_METATYPE(isEnumTest_Struct1) +Q_DECLARE_METATYPE(isEnumTest_Enum1) + +void tst_QMetaType::isEnum() +{ + int type0 = qRegisterMetaType("int"); + QVERIFY((QMetaType::typeFlags(type0) & QMetaType::IsEnumeration) == 0); + + int type1 = qRegisterMetaType("isEnumTest_Enum0"); + QVERIFY((QMetaType::typeFlags(type1) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration); + + int type2 = qRegisterMetaType("isEnumTest_Struct0"); + QVERIFY((QMetaType::typeFlags(type2) & QMetaType::IsEnumeration) == 0); + + int type3 = qRegisterMetaType("isEnumTest_Enum0 *"); + QVERIFY((QMetaType::typeFlags(type3) & QMetaType::IsEnumeration) == 0); + + int type4 = qRegisterMetaType("isEnumTest_Struct0::A"); + QVERIFY((QMetaType::typeFlags(type4) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration); + + int type5 = ::qMetaTypeId(); + QVERIFY((QMetaType::typeFlags(type5) & QMetaType::IsEnumeration) == 0); + + int type6 = ::qMetaTypeId(); + QVERIFY((QMetaType::typeFlags(type6) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration); +} + void tst_QMetaType::isRegisteredStaticLess_data() { isRegistered_data(); -- cgit v1.2.3