Line data Source code
1 : /****************************************************************************
2 : **
3 : ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 : ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 : ** conditions see http://qt.digia.com/licensing. For further information
15 : ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 : ** Foundation and appearing in the file LICENSE.LGPL included in the
21 : ** packaging of this file. Please review the following information to
22 : ** ensure the GNU Lesser General Public License version 2.1 requirements
23 : ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 : **
25 : ** In addition, as a special exception, Digia gives you certain additional
26 : ** rights. These rights are described in the Digia Qt LGPL Exception
27 : ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 : **
29 : ** GNU General Public License Usage
30 : ** Alternatively, this file may be used under the terms of the GNU
31 : ** General Public License version 3.0 as published by the Free Software
32 : ** Foundation and appearing in the file LICENSE.GPL included in the
33 : ** packaging of this file. Please review the following information to
34 : ** ensure the GNU General Public License version 3.0 requirements will be
35 : ** met: http://www.gnu.org/copyleft/gpl.html.
36 : **
37 : **
38 : ** $QT_END_LICENSE$
39 : **
40 : ****************************************************************************/
41 :
42 : #include <QtCore/qglobal.h>
43 :
44 : #ifndef QFLAGS_H
45 : #define QFLAGS_H
46 :
47 : #include <QtCore/qtypeinfo.h>
48 : #include <QtCore/qtypetraits.h>
49 :
50 : QT_BEGIN_NAMESPACE
51 :
52 : class QFlag
53 : {
54 : int i;
55 : public:
56 : Q_DECL_CONSTEXPR inline QFlag(int ai) : i(ai) {}
57 : Q_DECL_CONSTEXPR inline operator int() const { return i; }
58 :
59 : #if !defined(Q_CC_MSVC)
60 : // Microsoft Visual Studio has buggy behavior when it comes to
61 : // unsigned enums: even if the enum is unsigned, the enum tags are
62 : // always signed
63 : # if !defined(__LP64__) && !defined(Q_QDOC)
64 : Q_DECL_CONSTEXPR inline QFlag(long ai) : i(int(ai)) {}
65 : Q_DECL_CONSTEXPR inline QFlag(ulong ai) : i(int(long(ai))) {}
66 : # endif
67 : Q_DECL_CONSTEXPR inline QFlag(uint ai) : i(int(ai)) {}
68 : Q_DECL_CONSTEXPR inline QFlag(short ai) : i(int(ai)) {}
69 : Q_DECL_CONSTEXPR inline QFlag(ushort ai) : i(int(uint(ai))) {}
70 : Q_DECL_CONSTEXPR inline operator uint() const { return uint(i); }
71 : #endif
72 : };
73 : Q_DECLARE_TYPEINFO(QFlag, Q_PRIMITIVE_TYPE);
74 :
75 : class QIncompatibleFlag
76 : {
77 : int i;
78 : public:
79 : Q_DECL_CONSTEXPR inline explicit QIncompatibleFlag(int i);
80 : Q_DECL_CONSTEXPR inline operator int() const { return i; }
81 : };
82 : Q_DECLARE_TYPEINFO(QIncompatibleFlag, Q_PRIMITIVE_TYPE);
83 :
84 : Q_DECL_CONSTEXPR inline QIncompatibleFlag::QIncompatibleFlag(int ai) : i(ai) {}
85 :
86 :
87 : #ifndef Q_NO_TYPESAFE_FLAGS
88 :
89 : template<typename Enum>
90 : class QFlags
91 : {
92 : Q_STATIC_ASSERT_X((sizeof(Enum) <= sizeof(int)),
93 : "QFlags uses an int as storage, so an enum with underlying "
94 : "long long will overflow.");
95 : struct Private;
96 : typedef int (Private::*Zero);
97 : public:
98 : #if defined(Q_CC_MSVC) || defined(Q_QDOC)
99 : // see above for MSVC
100 : // the definition below is too complex for qdoc
101 : typedef int Int;
102 : #else
103 : typedef typename QtPrivate::if_<
104 : QtPrivate::is_unsigned<Enum>::value,
105 : unsigned int,
106 : signed int
107 : >::type Int;
108 : #endif
109 : typedef Enum enum_type;
110 : // compiler-generated copy/move ctor/assignment operators are fine!
111 : #ifdef Q_QDOC
112 : inline QFlags(const QFlags &other);
113 : inline QFlags &operator=(const QFlags &other);
114 : #endif
115 36 : Q_DECL_CONSTEXPR inline QFlags(Enum f) : i(Int(f)) {}
116 : Q_DECL_CONSTEXPR inline QFlags(Zero = 0) : i(0) {}
117 : Q_DECL_CONSTEXPR inline QFlags(QFlag f) : i(f) {}
118 :
119 : inline QFlags &operator&=(int mask) { i &= mask; return *this; }
120 : inline QFlags &operator&=(uint mask) { i &= mask; return *this; }
121 : inline QFlags &operator&=(Enum mask) { i &= Int(mask); return *this; }
122 : inline QFlags &operator|=(QFlags f) { i |= f.i; return *this; }
123 0 : inline QFlags &operator|=(Enum f) { i |= Int(f); return *this; }
124 : inline QFlags &operator^=(QFlags f) { i ^= f.i; return *this; }
125 : inline QFlags &operator^=(Enum f) { i ^= Int(f); return *this; }
126 :
127 : Q_DECL_CONSTEXPR inline operator Int() const { return i; }
128 :
129 : Q_DECL_CONSTEXPR inline QFlags operator|(QFlags f) const { return QFlags(QFlag(i | f.i)); }
130 : Q_DECL_CONSTEXPR inline QFlags operator|(Enum f) const { return QFlags(QFlag(i | Int(f))); }
131 : Q_DECL_CONSTEXPR inline QFlags operator^(QFlags f) const { return QFlags(QFlag(i ^ f.i)); }
132 : Q_DECL_CONSTEXPR inline QFlags operator^(Enum f) const { return QFlags(QFlag(i ^ Int(f))); }
133 : Q_DECL_CONSTEXPR inline QFlags operator&(int mask) const { return QFlags(QFlag(i & mask)); }
134 : Q_DECL_CONSTEXPR inline QFlags operator&(uint mask) const { return QFlags(QFlag(i & mask)); }
135 : Q_DECL_CONSTEXPR inline QFlags operator&(Enum f) const { return QFlags(QFlag(i & Int(f))); }
136 : Q_DECL_CONSTEXPR inline QFlags operator~() const { return QFlags(QFlag(~i)); }
137 :
138 : Q_DECL_CONSTEXPR inline bool operator!() const { return !i; }
139 :
140 0 : Q_DECL_CONSTEXPR inline bool testFlag(Enum f) const { return (i & Int(f)) == Int(f) && (Int(f) != 0 || i == Int(f) ); }
141 : private:
142 : Int i;
143 : };
144 :
145 : #define Q_DECLARE_FLAGS(Flags, Enum)\
146 : typedef QFlags<Enum> Flags;
147 :
148 : #define Q_DECLARE_INCOMPATIBLE_FLAGS(Flags) \
149 : Q_DECL_CONSTEXPR inline QIncompatibleFlag operator|(Flags::enum_type f1, int f2) \
150 : { return QIncompatibleFlag(int(f1) | f2); }
151 :
152 : #define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
153 : Q_DECL_CONSTEXPR inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, Flags::enum_type f2) \
154 : { return QFlags<Flags::enum_type>(f1) | f2; } \
155 : Q_DECL_CONSTEXPR inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, QFlags<Flags::enum_type> f2) \
156 : { return f2 | f1; } Q_DECLARE_INCOMPATIBLE_FLAGS(Flags)
157 :
158 :
159 : #else /* Q_NO_TYPESAFE_FLAGS */
160 :
161 : #define Q_DECLARE_FLAGS(Flags, Enum)\
162 : typedef uint Flags;
163 : #define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
164 :
165 : #endif /* Q_NO_TYPESAFE_FLAGS */
166 :
167 : QT_END_NAMESPACE
168 :
169 : #endif // QFLAGS_H
|