Line data Source code
1 : /****************************************************************************
2 : **
3 : ** Copyright (C) 2016 The Qt Company Ltd.
4 : ** Contact: https://www.qt.io/licensing/
5 : **
6 : ** This file is part of the QtCore module of the Qt Toolkit.
7 : **
8 : ** $QT_BEGIN_LICENSE:LGPL$
9 : ** Commercial License Usage
10 : ** Licensees holding valid commercial Qt licenses may use this file in
11 : ** accordance with the commercial license agreement provided with the
12 : ** Software or, alternatively, in accordance with the terms contained in
13 : ** a written agreement between you and The Qt Company. For licensing terms
14 : ** and conditions see https://www.qt.io/terms-conditions. For further
15 : ** information use the contact form at https://www.qt.io/contact-us.
16 : **
17 : ** GNU Lesser General Public License Usage
18 : ** Alternatively, this file may be used under the terms of the GNU Lesser
19 : ** General Public License version 3 as published by the Free Software
20 : ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 : ** packaging of this file. Please review the following information to
22 : ** ensure the GNU Lesser General Public License version 3 requirements
23 : ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 : **
25 : ** GNU General Public License Usage
26 : ** Alternatively, this file may be used under the terms of the GNU
27 : ** General Public License version 2.0 or (at your option) the GNU General
28 : ** Public license version 3 or any later version approved by the KDE Free
29 : ** Qt Foundation. The licenses are as published by the Free Software
30 : ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 : ** included in the packaging of this file. Please review the following
32 : ** information to ensure the GNU General Public License requirements will
33 : ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 : ** https://www.gnu.org/licenses/gpl-3.0.html.
35 : **
36 : ** $QT_END_LICENSE$
37 : **
38 : ****************************************************************************/
39 :
40 : #include <QtCore/qglobal.h>
41 :
42 : #ifndef QFLAGS_H
43 : #define QFLAGS_H
44 :
45 : #ifdef Q_COMPILER_INITIALIZER_LISTS
46 : #include <initializer_list>
47 : #endif
48 :
49 : QT_BEGIN_NAMESPACE
50 :
51 : class QDataStream;
52 :
53 : class QFlag
54 : {
55 : int i;
56 : public:
57 : Q_DECL_CONSTEXPR inline QFlag(int ai) Q_DECL_NOTHROW : i(ai) {}
58 : Q_DECL_CONSTEXPR inline operator int() const Q_DECL_NOTHROW { return i; }
59 :
60 : #if !defined(Q_CC_MSVC)
61 : // Microsoft Visual Studio has buggy behavior when it comes to
62 : // unsigned enums: even if the enum is unsigned, the enum tags are
63 : // always signed
64 : # if !defined(__LP64__) && !defined(Q_QDOC)
65 : Q_DECL_CONSTEXPR inline QFlag(long ai) Q_DECL_NOTHROW : i(int(ai)) {}
66 : Q_DECL_CONSTEXPR inline QFlag(ulong ai) Q_DECL_NOTHROW : i(int(long(ai))) {}
67 : # endif
68 : Q_DECL_CONSTEXPR inline QFlag(uint ai) Q_DECL_NOTHROW : i(int(ai)) {}
69 : Q_DECL_CONSTEXPR inline QFlag(short ai) Q_DECL_NOTHROW : i(int(ai)) {}
70 : Q_DECL_CONSTEXPR inline QFlag(ushort ai) Q_DECL_NOTHROW : i(int(uint(ai))) {}
71 : Q_DECL_CONSTEXPR inline operator uint() const Q_DECL_NOTHROW { return uint(i); }
72 : #endif
73 : };
74 : Q_DECLARE_TYPEINFO(QFlag, Q_PRIMITIVE_TYPE);
75 :
76 : class QIncompatibleFlag
77 : {
78 : int i;
79 : public:
80 : Q_DECL_CONSTEXPR inline explicit QIncompatibleFlag(int i) Q_DECL_NOTHROW;
81 : Q_DECL_CONSTEXPR inline operator int() const Q_DECL_NOTHROW { return i; }
82 : };
83 : Q_DECLARE_TYPEINFO(QIncompatibleFlag, Q_PRIMITIVE_TYPE);
84 :
85 : Q_DECL_CONSTEXPR inline QIncompatibleFlag::QIncompatibleFlag(int ai) Q_DECL_NOTHROW : i(ai) {}
86 :
87 :
88 : #ifndef Q_NO_TYPESAFE_FLAGS
89 :
90 : template<typename Enum>
91 : class QFlags
92 : {
93 : Q_STATIC_ASSERT_X((sizeof(Enum) <= sizeof(int)),
94 : "QFlags uses an int as storage, so an enum with underlying "
95 : "long long will overflow.");
96 : Q_STATIC_ASSERT_X((std::is_enum<Enum>::value), "QFlags is only usable on enumeration types.");
97 :
98 : struct Private;
99 : typedef int (Private::*Zero);
100 : template <typename E> friend QDataStream &operator>>(QDataStream &, QFlags<E> &);
101 : template <typename E> friend QDataStream &operator<<(QDataStream &, QFlags<E>);
102 : public:
103 : #if defined(Q_CC_MSVC) || defined(Q_QDOC)
104 : // see above for MSVC
105 : // the definition below is too complex for qdoc
106 : typedef int Int;
107 : #else
108 : typedef typename std::conditional<
109 : std::is_unsigned<typename std::underlying_type<Enum>::type>::value,
110 : unsigned int,
111 : signed int
112 : >::type Int;
113 : #endif
114 : typedef Enum enum_type;
115 : // compiler-generated copy/move ctor/assignment operators are fine!
116 : #ifdef Q_QDOC
117 : Q_DECL_CONSTEXPR inline QFlags(const QFlags &other);
118 : Q_DECL_CONSTEXPR inline QFlags &operator=(const QFlags &other);
119 : #endif
120 59 : Q_DECL_CONSTEXPR inline QFlags(Enum f) Q_DECL_NOTHROW : i(Int(f)) {}
121 : Q_DECL_CONSTEXPR inline QFlags(Zero = Q_NULLPTR) Q_DECL_NOTHROW : i(0) {}
122 : Q_DECL_CONSTEXPR inline QFlags(QFlag f) Q_DECL_NOTHROW : i(f) {}
123 :
124 : #ifdef Q_COMPILER_INITIALIZER_LISTS
125 : Q_DECL_CONSTEXPR inline QFlags(std::initializer_list<Enum> flags) Q_DECL_NOTHROW
126 : : i(initializer_list_helper(flags.begin(), flags.end())) {}
127 : #endif
128 :
129 : Q_DECL_RELAXED_CONSTEXPR inline QFlags &operator&=(int mask) Q_DECL_NOTHROW { i &= mask; return *this; }
130 : Q_DECL_RELAXED_CONSTEXPR inline QFlags &operator&=(uint mask) Q_DECL_NOTHROW { i &= mask; return *this; }
131 : Q_DECL_RELAXED_CONSTEXPR inline QFlags &operator&=(Enum mask) Q_DECL_NOTHROW { i &= Int(mask); return *this; }
132 : Q_DECL_RELAXED_CONSTEXPR inline QFlags &operator|=(QFlags f) Q_DECL_NOTHROW { i |= f.i; return *this; }
133 0 : Q_DECL_RELAXED_CONSTEXPR inline QFlags &operator|=(Enum f) Q_DECL_NOTHROW { i |= Int(f); return *this; }
134 : Q_DECL_RELAXED_CONSTEXPR inline QFlags &operator^=(QFlags f) Q_DECL_NOTHROW { i ^= f.i; return *this; }
135 : Q_DECL_RELAXED_CONSTEXPR inline QFlags &operator^=(Enum f) Q_DECL_NOTHROW { i ^= Int(f); return *this; }
136 :
137 : Q_DECL_CONSTEXPR inline operator Int() const Q_DECL_NOTHROW { return i; }
138 :
139 : Q_DECL_CONSTEXPR inline QFlags operator|(QFlags f) const Q_DECL_NOTHROW { return QFlags(QFlag(i | f.i)); }
140 : Q_DECL_CONSTEXPR inline QFlags operator|(Enum f) const Q_DECL_NOTHROW { return QFlags(QFlag(i | Int(f))); }
141 : Q_DECL_CONSTEXPR inline QFlags operator^(QFlags f) const Q_DECL_NOTHROW { return QFlags(QFlag(i ^ f.i)); }
142 : Q_DECL_CONSTEXPR inline QFlags operator^(Enum f) const Q_DECL_NOTHROW { return QFlags(QFlag(i ^ Int(f))); }
143 : Q_DECL_CONSTEXPR inline QFlags operator&(int mask) const Q_DECL_NOTHROW { return QFlags(QFlag(i & mask)); }
144 : Q_DECL_CONSTEXPR inline QFlags operator&(uint mask) const Q_DECL_NOTHROW { return QFlags(QFlag(i & mask)); }
145 : Q_DECL_CONSTEXPR inline QFlags operator&(Enum f) const Q_DECL_NOTHROW { return QFlags(QFlag(i & Int(f))); }
146 : Q_DECL_CONSTEXPR inline QFlags operator~() const Q_DECL_NOTHROW { return QFlags(QFlag(~i)); }
147 :
148 : Q_DECL_CONSTEXPR inline bool operator!() const Q_DECL_NOTHROW { return !i; }
149 :
150 0 : Q_DECL_CONSTEXPR inline bool testFlag(Enum f) const Q_DECL_NOTHROW { return (i & Int(f)) == Int(f) && (Int(f) != 0 || i == Int(f) ); }
151 : Q_DECL_RELAXED_CONSTEXPR inline QFlags &setFlag(Enum f, bool on = true) Q_DECL_NOTHROW
152 : {
153 : return on ? (*this |= f) : (*this &= ~Int(f));
154 : }
155 :
156 : private:
157 : #ifdef Q_COMPILER_INITIALIZER_LISTS
158 : Q_DECL_CONSTEXPR static inline Int initializer_list_helper(typename std::initializer_list<Enum>::const_iterator it,
159 : typename std::initializer_list<Enum>::const_iterator end)
160 : Q_DECL_NOTHROW
161 : {
162 : return (it == end ? Int(0) : (Int(*it) | initializer_list_helper(it + 1, end)));
163 : }
164 : #endif
165 :
166 : Int i;
167 : };
168 :
169 : #ifndef Q_MOC_RUN
170 : #define Q_DECLARE_FLAGS(Flags, Enum)\
171 : typedef QFlags<Enum> Flags;
172 : #endif
173 :
174 : #define Q_DECLARE_INCOMPATIBLE_FLAGS(Flags) \
175 : Q_DECL_CONSTEXPR inline QIncompatibleFlag operator|(Flags::enum_type f1, int f2) Q_DECL_NOTHROW \
176 : { return QIncompatibleFlag(int(f1) | f2); }
177 :
178 : #define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
179 : Q_DECL_CONSTEXPR inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, Flags::enum_type f2) Q_DECL_NOTHROW \
180 : { return QFlags<Flags::enum_type>(f1) | f2; } \
181 : Q_DECL_CONSTEXPR inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, QFlags<Flags::enum_type> f2) Q_DECL_NOTHROW \
182 : { return f2 | f1; } Q_DECLARE_INCOMPATIBLE_FLAGS(Flags)
183 :
184 :
185 : #else /* Q_NO_TYPESAFE_FLAGS */
186 :
187 : #ifndef Q_MOC_RUN
188 : #define Q_DECLARE_FLAGS(Flags, Enum)\
189 : typedef uint Flags;
190 : #endif
191 :
192 : #define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
193 :
194 : #endif /* Q_NO_TYPESAFE_FLAGS */
195 :
196 : QT_END_NAMESPACE
197 :
198 : #endif // QFLAGS_H
|