7#include <QtCore/qcompare_impl.h>
8#include <QtCore/qtypeinfo.h>
11#include <initializer_list>
15template<
typename Enum>
class QFlags;
24#if !defined(Q_CC_MSVC)
28# if !defined(__LP64__
) && !defined(Q_QDOC)
55template<
typename Enum>
59 "Only enumerations 64 bits or smaller are supported.");
60 static_assert((
std::is_enum<Enum>::value),
"QFlags is only usable on enumeration types.");
62 static constexpr size_t IntegerSize = (
std::max)(
sizeof(Enum),
sizeof(
int));
80template <
typename Enum,
int Size =
sizeof(
QFlagsStorage<Enum>)>
97#ifdef QT_TYPESAFE_FLAGS
105template<
typename Enum>
115 constexpr inline QFlags()
noexcept =
default;
125 constexpr inline QFlags(
std::initializer_list<Enum> flags)
noexcept
129 constexpr inline Int toInt()
const noexcept {
return i; }
131#ifndef QT_TYPESAFE_FLAGS
132 constexpr inline QFlags &
operator&=(
int mask)
noexcept { i &= mask;
return *
this; }
133 constexpr inline QFlags &
operator&=(uint mask)
noexcept { i &= mask;
return *
this; }
136 constexpr inline QFlags &
operator&=(Enum mask)
noexcept { i &= Int(mask);
return *
this; }
138 constexpr inline QFlags &
operator|=(Enum other)
noexcept { i |= Int(other);
return *
this; }
140 constexpr inline QFlags &
operator^=(Enum other)
noexcept { i ^= Int(other);
return *
this; }
142#ifdef QT_TYPESAFE_FLAGS
143 constexpr inline explicit operator Int()
const noexcept {
return i; }
144 constexpr inline explicit operator bool()
const noexcept {
return i; }
147 constexpr inline bool operator!()
const noexcept {
return !
i; }
154#ifndef QT_TYPESAFE_FLAGS
163 constexpr inline void operator+(Enum other)
const noexcept =
delete;
164 constexpr inline void operator+(
int other)
const noexcept =
delete;
166 constexpr inline void operator-(Enum other)
const noexcept =
delete;
167 constexpr inline void operator-(
int other)
const noexcept =
delete;
170 constexpr inline bool testFlags(
QFlags flags)
const noexcept {
return flags.i ? ((i & flags.i) == flags.i) : i == Int(0); }
175 return on ? (*
this |= flag) : (*
this &= ~
QFlags(flag));
179 {
return lhs.i == rhs.i; }
181 {
return lhs.i != rhs.i; }
183 {
return lhs ==
QFlags(rhs); }
185 {
return lhs !=
QFlags(rhs); }
187 {
return QFlags(lhs) == rhs; }
189 {
return QFlags(lhs) != rhs; }
191#ifdef QT_TYPESAFE_FLAGS
206 constexpr static inline Int initializer_list_helper(
typename std::initializer_list<Enum>::const_iterator it,
207 typename std::initializer_list<Enum>::const_iterator end)
210 return (it == end ? Int(0) : (Int(*it) | initializer_list_helper(it + 1, end)));
217#define Q_DECLARE_FLAGS(Flags, Enum)typedef
221#ifdef QT_TYPESAFE_FLAGS
224#define QT_DECLARE_TYPESAFE_OPERATORS_FOR_FLAGS_ENUM(Flags) \
225[[maybe_unused]]constexpr
226 inline Flags operator
~(Flags::enum_type e) noexcept \
227{return ~Flags(e); } \
228[[maybe_unused]]constexpr
229 inline void operator
|(Flags::enum_type f1, int f2) noexcept = delete;
231#define QT_DECLARE_TYPESAFE_OPERATORS_FOR_FLAGS_ENUM(Flags) \
232[[maybe_unused]]constexpr
233 inline QIncompatibleFlag operator
|(Flags::enum_type f1, int f2) noexcept \
234{return QIncompatibleFlag(int(f1) | f2); }
237#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
238[[maybe_unused]]constexpr
239 inline QFlags<Flags::enum_type> operator
|(Flags::enum_type f1, Flags::enum_type f2) noexcept \
240{return QFlags<Flags::enum_type>(f1) | f2; } \
241[[maybe_unused]]constexpr
242 inline QFlags<Flags::enum_type> operator
|(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept \
243{return f2 | f1; } \
244[[maybe_unused]]constexpr
245 inline QFlags<Flags::enum_type> operator
&(Flags::enum_type f1, Flags::enum_type f2) noexcept \
246{return QFlags<Flags::enum_type>(f1) & f2; } \
247[[maybe_unused]]constexpr
248 inline QFlags<Flags::enum_type> operator
&(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept \
249{return f2 & f1; } \
250[[maybe_unused]]constexpr
251 inline QFlags<Flags::enum_type> operator
^(Flags::enum_type f1, Flags::enum_type f2) noexcept \
252{return QFlags<Flags::enum_type>(f1) ^ f2; } \
253[[maybe_unused]]constexpr
254 inline QFlags<Flags::enum_type> operator
^(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept \
255{return f2 ^ f1; } constexpr
256 inline void operator
+(Flags::enum_type f1, Flags::enum_type f2) noexcept = delete; constexpr
257 inline void operator
+(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept = delete; constexpr
258 inline void operator
+(int f1, QFlags<Flags::enum_type> f2) noexcept = delete; constexpr
259 inline void operator
-(Flags::enum_type f1, Flags::enum_type f2) noexcept = delete; constexpr
260 inline void operator
-(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept = delete; constexpr
261 inline void operator
-(int f1, QFlags<Flags::enum_type> f2) noexcept = delete; constexpr
262 inline void operator
+(int f1, Flags::enum_type f2) noexcept = delete; constexpr
263 inline void operator
+(Flags::enum_type f1, int f2) noexcept = delete; constexpr
264 inline void operator
-(int f1, Flags::enum_type f2) noexcept = delete; constexpr
265 inline void operator
-(Flags::enum_type f1, int f2) noexcept = delete; QT_DECLARE_TYPESAFE_OPERATORS_FOR_FLAGS_ENUM
270#if __cplusplus
> 201702L
272# define Q_DECLARE_MIXED_ENUM_OPERATOR(op, Ret, LHS, RHS)
274 constexpr inline Ret operator
op (LHS lhs, RHS rhs) noexcept
275 { return static_cast<Ret>(qToUnderlying(lhs) op qToUnderlying(rhs)); }
280# define Q_DECLARE_MIXED_ENUM_OPERATOR(op, Ret, LHS, RHS)
281 static_assert(std::is_same_v<decltype(std::declval<LHS>() op std::declval<RHS>()), Ret>);
284#define Q_DECLARE_MIXED_ENUM_OPERATORS(Ret, Flags, Enum)
290#define Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(Ret, Flags, Enum)
constexpr QFlags(std::initializer_list< Enum > flags) noexcept
constexpr QFlags & operator&=(Enum mask) noexcept
constexpr QFlags & operator&=(int mask) noexcept
constexpr void operator+(int other) const noexcept=delete
constexpr QFlags & operator|=(QFlags other) noexcept
constexpr Int toInt() const noexcept
constexpr QFlags & operator&=(uint mask) noexcept
friend constexpr bool operator!=(Enum lhs, QFlags rhs) noexcept
friend constexpr bool operator==(Enum lhs, QFlags rhs) noexcept
constexpr void operator-(int other) const noexcept=delete
constexpr bool testFlag(Enum flag) const noexcept
constexpr QFlags & operator^=(Enum other) noexcept
friend constexpr bool operator==(QFlags lhs, Enum rhs) noexcept
constexpr bool testAnyFlag(Enum flag) const noexcept
constexpr bool testAnyFlags(QFlags flags) const noexcept
constexpr void operator+(Enum other) const noexcept=delete
friend constexpr bool operator!=(QFlags lhs, QFlags rhs) noexcept
constexpr QFlags & operator&=(QFlags mask) noexcept
constexpr QFlags & operator|=(Enum other) noexcept
constexpr void operator-(Enum other) const noexcept=delete
friend constexpr bool operator!=(QFlags lhs, Enum rhs) noexcept
friend constexpr bool operator==(QFlags lhs, QFlags rhs) noexcept
constexpr void operator-(QFlags other) const noexcept=delete
static constexpr QFlags fromInt(Int i) noexcept
constexpr QFlags & operator^=(QFlags other) noexcept
constexpr QFlags & setFlag(Enum flag, bool on=true) noexcept
constexpr bool testFlags(QFlags flags) const noexcept
constexpr QFlags() noexcept=default
constexpr QIncompatibleFlag(int i) noexcept
constexpr QFlagsStorage(std::in_place_t, Int v)
std::conditional< std::is_unsigned< typenamestd::underlying_type< Enum >::type >::value, typenameIntegers::Unsigned, typenameIntegers::Signed >::type Int
Q_DECLARE_TYPEINFO(QIncompatibleFlag, Q_PRIMITIVE_TYPE)
#define Q_DECLARE_MIXED_ENUM_OPERATORS(Ret, Flags, Enum)
Q_DECLARE_TYPEINFO(QFlag, Q_PRIMITIVE_TYPE)
#define Q_DECLARE_MIXED_ENUM_OPERATOR(op, Ret, LHS, RHS)