diff options
-rw-r--r-- | src/corelib/global/qflags.h | 17 | ||||
-rw-r--r-- | src/corelib/global/qglobal.cpp | 10 | ||||
-rw-r--r-- | tests/auto/corelib/global/qflags/tst_qflags.cpp | 24 |
3 files changed, 51 insertions, 0 deletions
diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h index 9e97724fec..d7b673bc1f 100644 --- a/src/corelib/global/qflags.h +++ b/src/corelib/global/qflags.h @@ -47,6 +47,10 @@ #include <QtCore/qtypeinfo.h> #include <QtCore/qtypetraits.h> +#ifdef Q_COMPILER_INITIALIZER_LISTS +#include <initializer_list> +#endif + QT_BEGIN_NAMESPACE class QFlag @@ -107,6 +111,11 @@ public: Q_DECL_CONSTEXPR inline QFlags(Zero = 0) : i(0) {} Q_DECL_CONSTEXPR inline QFlags(QFlag f) : i(f) {} +#ifdef Q_COMPILER_INITIALIZER_LISTS + Q_DECL_CONSTEXPR inline QFlags(std::initializer_list<Enum> flags) + : i(initializer_list_helper(flags.begin(), flags.end())) {} +#endif + inline QFlags &operator&=(int mask) { i &= mask; return *this; } inline QFlags &operator&=(uint mask) { i &= mask; return *this; } inline QFlags &operator&=(Enum mask) { i &= Int(mask); return *this; } @@ -130,6 +139,14 @@ public: Q_DECL_CONSTEXPR inline bool testFlag(Enum f) const { return (i & Int(f)) == Int(f) && (Int(f) != 0 || i == Int(f) ); } private: +#ifdef Q_COMPILER_INITIALIZER_LISTS + Q_DECL_CONSTEXPR static inline Int initializer_list_helper(typename std::initializer_list<Enum>::const_iterator it, + typename std::initializer_list<Enum>::const_iterator end) + { + return (it == end ? Int(0) : (Int(*it) | initializer_list_helper(it + 1, end))); + } +#endif + Int i; }; diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 98460481ca..56d8ea197f 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -270,6 +270,16 @@ Q_STATIC_ASSERT_X(UCHAR_MAX == 255, "Qt assumes that char is 8 bits"); */ /*! + \fn QFlags::QFlags(std::initializer_list<Enum> flags) + \since 5.4 + + Constructs a QFlags object initialized with all \a flags + combined using the bitwise OR operator. + + \sa operator|=(), operator|() +*/ + +/*! \fn QFlags &QFlags::operator=(const QFlags &other) Assigns \a other to this object and returns a reference to this diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp index 73a69a1309..42add6150a 100644 --- a/tests/auto/corelib/global/qflags/tst_qflags.cpp +++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp @@ -50,6 +50,7 @@ private slots: void constExpr(); void signedness(); void classEnum(); + void initializerLists(); }; void tst_QFlags::testFlag() const @@ -143,6 +144,9 @@ enum class MyStrictEnum { StrictZero, StrictOne, StrictTwo, StrictFour=4 }; Q_DECLARE_FLAGS( MyStrictFlags, MyStrictEnum ) Q_DECLARE_OPERATORS_FOR_FLAGS( MyStrictFlags ) +enum class MyStrictNoOpEnum { StrictZero, StrictOne, StrictTwo, StrictFour=4 }; +Q_DECLARE_FLAGS( MyStrictNoOpFlags, MyStrictNoOpEnum ) + Q_STATIC_ASSERT( !QTypeInfo<MyStrictFlags>::isComplex ); Q_STATIC_ASSERT( !QTypeInfo<MyStrictFlags>::isStatic ); Q_STATIC_ASSERT( !QTypeInfo<MyStrictFlags>::isLarge ); @@ -253,6 +257,26 @@ void tst_QFlags::classEnum() #endif } +void tst_QFlags::initializerLists() +{ +#if defined(Q_COMPILER_INITIALIZER_LISTS) + Qt::MouseButtons bts = { Qt::LeftButton, Qt::RightButton }; + QVERIFY(bts.testFlag(Qt::LeftButton)); + QVERIFY(bts.testFlag(Qt::RightButton)); + QVERIFY(!bts.testFlag(Qt::MiddleButton)); + +#if defined(Q_COMPILER_CLASS_ENUM) + MyStrictNoOpFlags flags = { MyStrictNoOpEnum::StrictOne, MyStrictNoOpEnum::StrictFour }; + QVERIFY(flags.testFlag(MyStrictNoOpEnum::StrictOne)); + QVERIFY(flags.testFlag(MyStrictNoOpEnum::StrictFour)); + QVERIFY(!flags.testFlag(MyStrictNoOpEnum::StrictTwo)); +#endif // Q_COMPILER_CLASS_ENUM + +#else + QSKIP("This test requires C++11 initializer_list support."); +#endif // Q_COMPILER_INITIALIZER_LISTS +} + // (statically) check QTypeInfo for QFlags instantiations: enum MyEnum { Zero, One, Two, Four=4 }; Q_DECLARE_FLAGS( MyFlags, MyEnum ) |