summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.0.05
-rw-r--r--src/corelib/global/qflags.h16
-rw-r--r--src/corelib/global/qglobal.cpp13
-rw-r--r--tests/auto/corelib/global/qflags/tst_qflags.cpp18
4 files changed, 46 insertions, 6 deletions
diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0
index b5f63c3600..795cb88935 100644
--- a/dist/changes-5.0.0
+++ b/dist/changes-5.0.0
@@ -62,6 +62,11 @@ information about a particular change.
- qIsDetached<> has been removed without replacement.
+- The return type of QFlags<Enum>::operator int() now matches the Enum's underlying
+ type in signedness instead of always being 'int'. This was done in order to allow
+ QFlags over enums whose underlying type is unsigned (Qt::MouseButton is one such
+ enum).
+
- QMetaType:
* QMetaType::construct() has been renamed to QMetaType::create().
* QMetaType::unregisterType() has been removed.
diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h
index faacf7321c..3edbef3bd6 100644
--- a/src/corelib/global/qflags.h
+++ b/src/corelib/global/qflags.h
@@ -44,6 +44,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qtypeinfo.h>
+#include <QtCore/qtypetraits.h>
QT_BEGIN_HEADER
@@ -82,11 +83,18 @@ class QFlags
"long long would overflow. Qt 5.1 will have support for 64bit enums.");
struct Private;
typedef int (Private::*Zero);
- int i;
public:
+#ifndef qdoc
+ typedef typename QtPrivate::if_<
+ QtPrivate::is_unsigned<Enum>::value,
+ unsigned int,
+ signed int
+ >::type Int;
+#endif
typedef Enum enum_type;
// compiler-generated copy/move ctor/assignment operators are fine!
#ifdef qdoc
+ typedef int Int; // the real typedef above is too complex for qdoc
inline QFlags(const QFlags &other);
inline QFlags &operator=(const QFlags &other);
#endif
@@ -101,7 +109,7 @@ public:
inline QFlags &operator^=(QFlags f) { i ^= f.i; return *this; }
inline QFlags &operator^=(Enum f) { i ^= f; return *this; }
- Q_DECL_CONSTEXPR inline operator int() const { return i; }
+ Q_DECL_CONSTEXPR inline operator Int() const { return i; }
Q_DECL_CONSTEXPR inline QFlags operator|(QFlags f) const { return QFlags(Enum(i | f.i)); }
Q_DECL_CONSTEXPR inline QFlags operator|(Enum f) const { return QFlags(Enum(i | f)); }
@@ -114,7 +122,9 @@ public:
Q_DECL_CONSTEXPR inline bool operator!() const { return !i; }
- Q_DECL_CONSTEXPR inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i == int(f) ); }
+ Q_DECL_CONSTEXPR inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i == Int(f) ); }
+private:
+ Int i;
};
#define Q_DECLARE_FLAGS(Flags, Enum)\
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index ef211cfce2..805868f4c6 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -172,6 +172,15 @@ Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n);
*/
/*!
+ \typedef QFlags::Int
+ \since 5.0
+
+ Typedef for the integer type used for storage as well as for
+ implicit conversion. Either \c int or \c{unsigned int}, depending
+ on whether the enum's underlying type is signed or unsigned.
+*/
+
+/*!
\typedef QFlags::enum_type
Typedef for the Enum template type.
@@ -261,9 +270,11 @@ Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n);
*/
/*!
- \fn QFlags::operator int() const
+ \fn QFlags::operator Int() const
Returns the value stored in the QFlags object as an integer.
+
+ \sa Int
*/
/*!
diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp
index f608dd6f93..215462606b 100644
--- a/tests/auto/corelib/global/qflags/tst_qflags.cpp
+++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp
@@ -48,6 +48,7 @@ private slots:
void testFlagZeroFlag() const;
void testFlagMultiBits() const;
void constExpr();
+ void signedness();
};
void tst_QFlags::testFlag() const
@@ -123,10 +124,23 @@ void tst_QFlags::constExpr()
#endif
}
+void tst_QFlags::signedness()
+{
+ // these are all 'true' on GCC, but since the std says the
+ // underlying type is implementation-defined, we need to allow for
+ // a different signedness, so we only check that the relative
+ // signedness of the types matches:
+ Q_STATIC_ASSERT((QtPrivate::is_unsigned<Qt::MouseButton>::value ==
+ QtPrivate::is_unsigned<Qt::MouseButtons::Int>::value));
+
+ Q_STATIC_ASSERT((QtPrivate::is_signed<Qt::AlignmentFlag>::value ==
+ QtPrivate::is_signed<Qt::Alignment::Int>::value));
+}
+
// (statically) check QTypeInfo for QFlags instantiations:
enum MyEnum { Zero, One, Two, Four=4 };
-Q_DECLARE_FLAGS( MyFlags, MyEnum );
-Q_DECLARE_OPERATORS_FOR_FLAGS( MyFlags );
+Q_DECLARE_FLAGS( MyFlags, MyEnum )
+Q_DECLARE_OPERATORS_FOR_FLAGS( MyFlags )
Q_STATIC_ASSERT( !QTypeInfo<MyFlags>::isComplex );
Q_STATIC_ASSERT( !QTypeInfo<MyFlags>::isStatic );