QFlags: use unsigned int when the enum's underlying is unsigned
Replace storage and operator int() return types with unsigned int if the enum is unsigned. This fixes a number of exisiting warnings, in particular with Qt::MouseButton under GCC. Change-Id: Ia12d36212329aec3e9d62a5fbd38809a6c2b36d0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
26f238a80d
commit
ac9be327f8
5
dist/changes-5.0.0
vendored
5
dist/changes-5.0.0
vendored
@ -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.
|
||||
|
@ -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)\
|
||||
|
@ -171,6 +171,15 @@ Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n);
|
||||
\sa QFlag
|
||||
*/
|
||||
|
||||
/*!
|
||||
\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
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -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 );
|
||||
|
Loading…
Reference in New Issue
Block a user