1/*
2 * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
3 *
4 * NVIDIA CORPORATION and its licensors retain all intellectual property
5 * and proprietary rights in and to this software, related documentation
6 * and any modifications thereto. Any use, reproduction, disclosure or
7 * distribution of this software and related documentation without an express
8 * license agreement from NVIDIA CORPORATION is strictly prohibited.
9 */
10// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
11// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
12
13
14#ifndef PX_FOUNDATION_PX_FLAGS_H
15#define PX_FOUNDATION_PX_FLAGS_H
16
17/** \addtogroup foundation
18 @{
19*/
20
21#include "foundation/Px.h"
22
23#ifndef PX_DOXYGEN
24namespace physx
25{
26#endif
27 /**
28 \brief Container for bitfield flag variables associated with a specific enum type.
29
30 This allows for type safe manipulation for bitfields.
31
32 <h3>Example</h3>
33 // enum that defines each bit...
34 struct MyEnum
35 {
36 enum Enum
37 {
38 eMAN = 1,
39 eBEAR = 2,
40 ePIG = 4,
41 };
42 };
43
44 // implements some convenient global operators.
45 PX_FLAGS_OPERATORS(MyEnum::Enum, PxU8);
46
47 PxFlags<MyEnum::Enum, PxU8> myFlags;
48 myFlags |= MyEnum::eMAN;
49 myFlags |= MyEnum::eBEAR | MyEnum::ePIG;
50 if(myFlags & MyEnum::eBEAR)
51 {
52 doSomething();
53 }
54 */
55
56 template<typename enumtype, typename storagetype=PxU32>
57 class PxFlags
58 {
59 public:
60 typedef storagetype InternalType;
61
62 PX_INLINE explicit PxFlags(const PxEMPTY&) {}
63 PX_INLINE PxFlags(void);
64 PX_INLINE PxFlags(enumtype e);
65 PX_INLINE PxFlags(const PxFlags<enumtype,storagetype> &f);
66 PX_INLINE explicit PxFlags(storagetype b);
67
68 PX_INLINE bool isSet (enumtype e) const;
69 PX_INLINE PxFlags<enumtype,storagetype> &set (enumtype e);
70 PX_INLINE bool operator==(enumtype e) const;
71 PX_INLINE bool operator==(const PxFlags<enumtype,storagetype> &f) const;
72 PX_INLINE bool operator==(bool b) const;
73 PX_INLINE bool operator!=(enumtype e) const;
74 PX_INLINE bool operator!=(const PxFlags<enumtype,storagetype> &f) const;
75
76 PX_INLINE PxFlags<enumtype,storagetype> &operator =(enumtype e);
77 PX_INLINE PxFlags<enumtype,storagetype> &operator =(const PxFlags<enumtype,storagetype> &f);
78
79 PX_INLINE PxFlags<enumtype,storagetype> &operator|=(enumtype e);
80 PX_INLINE PxFlags<enumtype,storagetype> &operator|=(const PxFlags<enumtype,storagetype> &f);
81 PX_INLINE PxFlags<enumtype,storagetype> operator| (enumtype e) const;
82 PX_INLINE PxFlags<enumtype,storagetype> operator| (const PxFlags<enumtype,storagetype> &f) const;
83
84 PX_INLINE PxFlags<enumtype,storagetype> &operator&=(enumtype e);
85 PX_INLINE PxFlags<enumtype,storagetype> &operator&=(const PxFlags<enumtype,storagetype> &f);
86 PX_INLINE PxFlags<enumtype,storagetype> operator& (enumtype e) const;
87 PX_INLINE PxFlags<enumtype,storagetype> operator& (const PxFlags<enumtype,storagetype> &f) const;
88
89 PX_INLINE PxFlags<enumtype,storagetype> &operator^=(enumtype e);
90 PX_INLINE PxFlags<enumtype,storagetype> &operator^=(const PxFlags<enumtype,storagetype> &f);
91 PX_INLINE PxFlags<enumtype,storagetype> operator^ (enumtype e) const;
92 PX_INLINE PxFlags<enumtype,storagetype> operator^ (const PxFlags<enumtype,storagetype> &f) const;
93
94 PX_INLINE PxFlags<enumtype,storagetype> operator~ (void) const;
95
96 PX_INLINE operator bool(void) const;
97 PX_INLINE operator PxU8(void) const;
98 PX_INLINE operator PxU16(void) const;
99 PX_INLINE operator PxU32(void) const;
100
101 PX_INLINE void clear(enumtype e);
102
103 public:
104 friend PX_INLINE PxFlags<enumtype,storagetype> operator&(enumtype a, PxFlags<enumtype,storagetype> &b)
105 {
106 PxFlags<enumtype,storagetype> out;
107 out.mBits = a & b.mBits;
108 return out;
109 }
110
111 private:
112 storagetype mBits;
113 };
114
115 #define PX_FLAGS_OPERATORS(enumtype, storagetype) \
116 PX_INLINE PxFlags<enumtype, storagetype> operator|(enumtype a, enumtype b) { PxFlags<enumtype, storagetype> r(a); r |= b; return r; } \
117 PX_INLINE PxFlags<enumtype, storagetype> operator&(enumtype a, enumtype b) { PxFlags<enumtype, storagetype> r(a); r &= b; return r; } \
118 PX_INLINE PxFlags<enumtype, storagetype> operator~(enumtype a) { return ~PxFlags<enumtype, storagetype>(a); }
119
120 #define PX_FLAGS_TYPEDEF(x, y) typedef PxFlags<x::Enum, y> x##s; \
121 PX_FLAGS_OPERATORS(x::Enum, y)
122
123 template<typename enumtype, typename storagetype>
124 PX_INLINE PxFlags<enumtype,storagetype>::PxFlags(void)
125 {
126 mBits = 0;
127 }
128
129 template<typename enumtype, typename storagetype>
130 PX_INLINE PxFlags<enumtype,storagetype>::PxFlags(enumtype e)
131 {
132 mBits = static_cast<storagetype>(e);
133 }
134
135 template<typename enumtype, typename storagetype>
136 PX_INLINE PxFlags<enumtype,storagetype>::PxFlags(const PxFlags<enumtype,storagetype> &f)
137 {
138 mBits = f.mBits;
139 }
140
141 template<typename enumtype, typename storagetype>
142 PX_INLINE PxFlags<enumtype,storagetype>& PxFlags<enumtype,storagetype>::operator =(const PxFlags<enumtype,storagetype> &f)
143 {
144 mBits = f.mBits;
145 return *this;
146 }
147
148 template<typename enumtype, typename storagetype>
149 PX_INLINE PxFlags<enumtype,storagetype>::PxFlags(storagetype b)
150 {
151 mBits = b;
152 }
153
154 template<typename enumtype, typename storagetype>
155 PX_INLINE bool PxFlags<enumtype,storagetype>::isSet(enumtype e) const
156 {
157 return (mBits & static_cast<storagetype>(e)) == static_cast<storagetype>(e);
158 }
159
160 template<typename enumtype, typename storagetype>
161 PX_INLINE PxFlags<enumtype,storagetype> &PxFlags<enumtype,storagetype>::set(enumtype e)
162 {
163 mBits = static_cast<storagetype>(e);
164 return *this;
165 }
166
167 template<typename enumtype, typename storagetype>
168 PX_INLINE bool PxFlags<enumtype,storagetype>::operator==(enumtype e) const
169 {
170 return mBits == static_cast<storagetype>(e);
171 }
172
173 template<typename enumtype, typename storagetype>
174 PX_INLINE bool PxFlags<enumtype,storagetype>::operator==(const PxFlags<enumtype,storagetype>& f) const
175 {
176 return mBits == f.mBits;
177 }
178
179 template<typename enumtype, typename storagetype>
180 PX_INLINE bool PxFlags<enumtype,storagetype>::operator==(bool b) const
181 {
182 return ((bool)*this) == b;
183 }
184
185 template<typename enumtype, typename storagetype>
186 PX_INLINE bool PxFlags<enumtype,storagetype>::operator!=(enumtype e) const
187 {
188 return mBits != static_cast<storagetype>(e);
189 }
190
191 template<typename enumtype, typename storagetype>
192 PX_INLINE bool PxFlags<enumtype,storagetype>::operator!=(const PxFlags<enumtype,storagetype> &f) const
193 {
194 return mBits != f.mBits;
195 }
196
197 template<typename enumtype, typename storagetype>
198 PX_INLINE PxFlags<enumtype,storagetype> &PxFlags<enumtype,storagetype>::operator =(enumtype e)
199 {
200 mBits = static_cast<storagetype>(e);
201 return *this;
202 }
203
204 template<typename enumtype, typename storagetype>
205 PX_INLINE PxFlags<enumtype,storagetype> &PxFlags<enumtype,storagetype>::operator|=(enumtype e)
206 {
207 mBits |= static_cast<storagetype>(e);
208 return *this;
209 }
210
211 template<typename enumtype, typename storagetype>
212 PX_INLINE PxFlags<enumtype,storagetype> &PxFlags<enumtype,storagetype>::operator|=(const PxFlags<enumtype,storagetype> &f)
213 {
214 mBits |= f.mBits;
215 return *this;
216 }
217
218 template<typename enumtype, typename storagetype>
219 PX_INLINE PxFlags<enumtype,storagetype> PxFlags<enumtype,storagetype>::operator| (enumtype e) const
220 {
221 PxFlags<enumtype,storagetype> out(*this);
222 out |= e;
223 return out;
224 }
225
226 template<typename enumtype, typename storagetype>
227 PX_INLINE PxFlags<enumtype,storagetype> PxFlags<enumtype,storagetype>::operator| (const PxFlags<enumtype,storagetype> &f) const
228 {
229 PxFlags<enumtype,storagetype> out(*this);
230 out |= f;
231 return out;
232 }
233
234 template<typename enumtype, typename storagetype>
235 PX_INLINE PxFlags<enumtype,storagetype> &PxFlags<enumtype,storagetype>::operator&=(enumtype e)
236 {
237 mBits &= static_cast<storagetype>(e);
238 return *this;
239 }
240
241 template<typename enumtype, typename storagetype>
242 PX_INLINE PxFlags<enumtype,storagetype> &PxFlags<enumtype,storagetype>::operator&=(const PxFlags<enumtype,storagetype> &f)
243 {
244 mBits &= f.mBits;
245 return *this;
246 }
247
248 template<typename enumtype, typename storagetype>
249 PX_INLINE PxFlags<enumtype,storagetype> PxFlags<enumtype,storagetype>::operator&(enumtype e) const
250 {
251 PxFlags<enumtype,storagetype> out = *this;
252 out.mBits &= static_cast<storagetype>(e);
253 return out;
254 }
255
256 template<typename enumtype, typename storagetype>
257 PX_INLINE PxFlags<enumtype,storagetype> PxFlags<enumtype,storagetype>::operator& (const PxFlags<enumtype,storagetype> &f) const
258 {
259 PxFlags<enumtype,storagetype> out = *this;
260 out.mBits &= f.mBits;
261 return out;
262 }
263
264 template<typename enumtype, typename storagetype>
265 PX_INLINE PxFlags<enumtype,storagetype> &PxFlags<enumtype,storagetype>::operator^=(enumtype e)
266 {
267 mBits ^= static_cast<storagetype>(e);
268 return *this;
269 }
270
271 template<typename enumtype, typename storagetype>
272 PX_INLINE PxFlags<enumtype,storagetype> &PxFlags<enumtype,storagetype>::operator^=(const PxFlags<enumtype,storagetype> &f)
273 {
274 mBits ^= f.mBits;
275 return *this;
276 }
277
278 template<typename enumtype, typename storagetype>
279 PX_INLINE PxFlags<enumtype,storagetype> PxFlags<enumtype,storagetype>::operator^ (enumtype e) const
280 {
281 PxFlags<enumtype,storagetype> out = *this;
282 out.mBits ^= static_cast<storagetype>(e);
283 return out;
284 }
285
286 template<typename enumtype, typename storagetype>
287 PX_INLINE PxFlags<enumtype,storagetype> PxFlags<enumtype,storagetype>::operator^ (const PxFlags<enumtype,storagetype> &f) const
288 {
289 PxFlags<enumtype,storagetype> out = *this;
290 out.mBits ^= f.mBits;
291 return out;
292 }
293
294 template<typename enumtype, typename storagetype>
295 PX_INLINE PxFlags<enumtype,storagetype> PxFlags<enumtype,storagetype>::operator~ (void) const
296 {
297 PxFlags<enumtype,storagetype> out;
298 out.mBits = (storagetype)~mBits;
299 return out;
300 }
301
302 template<typename enumtype, typename storagetype>
303 PX_INLINE PxFlags<enumtype,storagetype>::operator bool(void) const
304 {
305 return mBits ? true : false;
306 }
307
308 template<typename enumtype, typename storagetype>
309 PX_INLINE PxFlags<enumtype,storagetype>::operator PxU8(void) const
310 {
311 return static_cast<PxU8>(mBits);
312 }
313
314 template<typename enumtype, typename storagetype>
315 PX_INLINE PxFlags<enumtype,storagetype>::operator PxU16(void) const
316 {
317 return static_cast<PxU16>(mBits);
318 }
319
320 template<typename enumtype, typename storagetype>
321 PX_INLINE PxFlags<enumtype,storagetype>::operator PxU32(void) const
322 {
323 return static_cast<PxU32>(mBits);
324 }
325
326 template<typename enumtype, typename storagetype>
327 PX_INLINE void PxFlags<enumtype,storagetype>::clear(enumtype e)
328 {
329 mBits &= ~static_cast<storagetype>(e);
330 }
331
332#ifndef PX_DOXYGEN
333} // namespace physx
334#endif
335
336/** @} */
337#endif // #ifndef PX_FOUNDATION_PX_FLAGS_H
338