1 | // |
2 | // Redistribution and use in source and binary forms, with or without |
3 | // modification, are permitted provided that the following conditions |
4 | // are met: |
5 | // * Redistributions of source code must retain the above copyright |
6 | // notice, this list of conditions and the following disclaimer. |
7 | // * Redistributions in binary form must reproduce the above copyright |
8 | // notice, this list of conditions and the following disclaimer in the |
9 | // documentation and/or other materials provided with the distribution. |
10 | // * Neither the name of NVIDIA CORPORATION nor the names of its |
11 | // contributors may be used to endorse or promote products derived |
12 | // from this software without specific prior written permission. |
13 | // |
14 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY |
15 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
18 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 | // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | // |
26 | // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. |
27 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
28 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
29 | |
30 | #ifndef PXFOUNDATION_PXFLAGS_H |
31 | #define PXFOUNDATION_PXFLAGS_H |
32 | |
33 | /** \addtogroup foundation |
34 | @{ |
35 | */ |
36 | |
37 | #include "foundation/Px.h" |
38 | |
39 | #if !PX_DOXYGEN |
40 | namespace physx |
41 | { |
42 | #endif |
43 | /** |
44 | \brief Container for bitfield flag variables associated with a specific enum type. |
45 | |
46 | This allows for type safe manipulation for bitfields. |
47 | |
48 | <h3>Example</h3> |
49 | // enum that defines each bit... |
50 | struct MyEnum |
51 | { |
52 | enum Enum |
53 | { |
54 | eMAN = 1, |
55 | eBEAR = 2, |
56 | ePIG = 4, |
57 | }; |
58 | }; |
59 | |
60 | // implements some convenient global operators. |
61 | PX_FLAGS_OPERATORS(MyEnum::Enum, uint8_t); |
62 | |
63 | PxFlags<MyEnum::Enum, uint8_t> myFlags; |
64 | myFlags |= MyEnum::eMAN; |
65 | myFlags |= MyEnum::eBEAR | MyEnum::ePIG; |
66 | if(myFlags & MyEnum::eBEAR) |
67 | { |
68 | doSomething(); |
69 | } |
70 | */ |
71 | |
72 | template <typename enumtype, typename storagetype = uint32_t> |
73 | class PxFlags |
74 | { |
75 | public: |
76 | typedef storagetype InternalType; |
77 | |
78 | PX_CUDA_CALLABLE PX_INLINE explicit PxFlags(const PxEMPTY) |
79 | { |
80 | } |
81 | PX_CUDA_CALLABLE PX_INLINE PxFlags(void); |
82 | PX_CUDA_CALLABLE PX_INLINE PxFlags(enumtype e); |
83 | PX_CUDA_CALLABLE PX_INLINE PxFlags(const PxFlags<enumtype, storagetype>& f); |
84 | PX_CUDA_CALLABLE PX_INLINE explicit PxFlags(storagetype b); |
85 | |
86 | PX_CUDA_CALLABLE PX_INLINE bool isSet(enumtype e) const; |
87 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& set(enumtype e); |
88 | PX_CUDA_CALLABLE PX_INLINE bool operator==(enumtype e) const; |
89 | PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxFlags<enumtype, storagetype>& f) const; |
90 | PX_CUDA_CALLABLE PX_INLINE bool operator==(bool b) const; |
91 | PX_CUDA_CALLABLE PX_INLINE bool operator!=(enumtype e) const; |
92 | PX_CUDA_CALLABLE PX_INLINE bool operator!=(const PxFlags<enumtype, storagetype>& f) const; |
93 | |
94 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& operator=(const PxFlags<enumtype, storagetype>& f); |
95 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& operator=(enumtype e); |
96 | |
97 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& operator|=(enumtype e); |
98 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& operator|=(const PxFlags<enumtype, storagetype>& f); |
99 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> operator|(enumtype e) const; |
100 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> operator|(const PxFlags<enumtype, storagetype>& f) const; |
101 | |
102 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& operator&=(enumtype e); |
103 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& operator&=(const PxFlags<enumtype, storagetype>& f); |
104 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> operator&(enumtype e) const; |
105 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> operator&(const PxFlags<enumtype, storagetype>& f) const; |
106 | |
107 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& operator^=(enumtype e); |
108 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& operator^=(const PxFlags<enumtype, storagetype>& f); |
109 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> operator^(enumtype e) const; |
110 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> operator^(const PxFlags<enumtype, storagetype>& f) const; |
111 | |
112 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> operator~(void) const; |
113 | |
114 | PX_CUDA_CALLABLE PX_INLINE operator bool(void) const; |
115 | PX_CUDA_CALLABLE PX_INLINE operator uint8_t(void) const; |
116 | PX_CUDA_CALLABLE PX_INLINE operator uint16_t(void) const; |
117 | PX_CUDA_CALLABLE PX_INLINE operator uint32_t(void) const; |
118 | |
119 | PX_CUDA_CALLABLE PX_INLINE void clear(enumtype e); |
120 | |
121 | public: |
122 | friend PX_INLINE PxFlags<enumtype, storagetype> operator&(enumtype a, PxFlags<enumtype, storagetype>& b) |
123 | { |
124 | PxFlags<enumtype, storagetype> out; |
125 | out.mBits = a & b.mBits; |
126 | return out; |
127 | } |
128 | |
129 | private: |
130 | storagetype mBits; |
131 | }; |
132 | |
133 | #if !PX_DOXYGEN |
134 | |
135 | #define PX_FLAGS_OPERATORS(enumtype, storagetype) \ |
136 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> operator|(enumtype a, enumtype b) \ |
137 | { \ |
138 | PxFlags<enumtype, storagetype> r(a); \ |
139 | r |= b; \ |
140 | return r; \ |
141 | } \ |
142 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> operator&(enumtype a, enumtype b) \ |
143 | { \ |
144 | PxFlags<enumtype, storagetype> r(a); \ |
145 | r &= b; \ |
146 | return r; \ |
147 | } \ |
148 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> operator~(enumtype a) \ |
149 | { \ |
150 | return ~PxFlags<enumtype, storagetype>(a); \ |
151 | } |
152 | |
153 | #define PX_FLAGS_TYPEDEF(x, y) \ |
154 | typedef PxFlags<x::Enum, y> x##s; \ |
155 | PX_FLAGS_OPERATORS(x::Enum, y) |
156 | |
157 | template <typename enumtype, typename storagetype> |
158 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>::PxFlags(void) |
159 | { |
160 | mBits = 0; |
161 | } |
162 | |
163 | template <typename enumtype, typename storagetype> |
164 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>::PxFlags(enumtype e) |
165 | { |
166 | mBits = static_cast<storagetype>(e); |
167 | } |
168 | |
169 | template <typename enumtype, typename storagetype> |
170 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>::PxFlags(const PxFlags<enumtype, storagetype>& f) |
171 | { |
172 | mBits = f.mBits; |
173 | } |
174 | |
175 | template <typename enumtype, typename storagetype> |
176 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>::PxFlags(storagetype b) |
177 | { |
178 | mBits = b; |
179 | } |
180 | |
181 | template <typename enumtype, typename storagetype> |
182 | PX_CUDA_CALLABLE PX_INLINE bool PxFlags<enumtype, storagetype>::isSet(enumtype e) const |
183 | { |
184 | return (mBits & static_cast<storagetype>(e)) == static_cast<storagetype>(e); |
185 | } |
186 | |
187 | template <typename enumtype, typename storagetype> |
188 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& PxFlags<enumtype, storagetype>::set(enumtype e) |
189 | { |
190 | mBits = static_cast<storagetype>(e); |
191 | return *this; |
192 | } |
193 | |
194 | template <typename enumtype, typename storagetype> |
195 | PX_CUDA_CALLABLE PX_INLINE bool PxFlags<enumtype, storagetype>::operator==(enumtype e) const |
196 | { |
197 | return mBits == static_cast<storagetype>(e); |
198 | } |
199 | |
200 | template <typename enumtype, typename storagetype> |
201 | PX_CUDA_CALLABLE PX_INLINE bool PxFlags<enumtype, storagetype>::operator==(const PxFlags<enumtype, storagetype>& f) const |
202 | { |
203 | return mBits == f.mBits; |
204 | } |
205 | |
206 | template <typename enumtype, typename storagetype> |
207 | PX_CUDA_CALLABLE PX_INLINE bool PxFlags<enumtype, storagetype>::operator==(bool b) const |
208 | { |
209 | return bool(*this) == b; |
210 | } |
211 | |
212 | template <typename enumtype, typename storagetype> |
213 | PX_CUDA_CALLABLE PX_INLINE bool PxFlags<enumtype, storagetype>::operator!=(enumtype e) const |
214 | { |
215 | return mBits != static_cast<storagetype>(e); |
216 | } |
217 | |
218 | template <typename enumtype, typename storagetype> |
219 | PX_CUDA_CALLABLE PX_INLINE bool PxFlags<enumtype, storagetype>::operator!=(const PxFlags<enumtype, storagetype>& f) const |
220 | { |
221 | return mBits != f.mBits; |
222 | } |
223 | |
224 | template <typename enumtype, typename storagetype> |
225 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& PxFlags<enumtype, storagetype>::operator=(enumtype e) |
226 | { |
227 | mBits = static_cast<storagetype>(e); |
228 | return *this; |
229 | } |
230 | |
231 | template <typename enumtype, typename storagetype> |
232 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& PxFlags<enumtype, storagetype>::operator=(const PxFlags<enumtype, storagetype>& f) |
233 | { |
234 | mBits = f.mBits; |
235 | return *this; |
236 | } |
237 | |
238 | template <typename enumtype, typename storagetype> |
239 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& PxFlags<enumtype, storagetype>::operator|=(enumtype e) |
240 | { |
241 | mBits |= static_cast<storagetype>(e); |
242 | return *this; |
243 | } |
244 | |
245 | template <typename enumtype, typename storagetype> |
246 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& PxFlags<enumtype, storagetype>:: |
247 | operator|=(const PxFlags<enumtype, storagetype>& f) |
248 | { |
249 | mBits |= f.mBits; |
250 | return *this; |
251 | } |
252 | |
253 | template <typename enumtype, typename storagetype> |
254 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> PxFlags<enumtype, storagetype>::operator|(enumtype e) const |
255 | { |
256 | PxFlags<enumtype, storagetype> out(*this); |
257 | out |= e; |
258 | return out; |
259 | } |
260 | |
261 | template <typename enumtype, typename storagetype> |
262 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> PxFlags<enumtype, storagetype>:: |
263 | operator|(const PxFlags<enumtype, storagetype>& f) const |
264 | { |
265 | PxFlags<enumtype, storagetype> out(*this); |
266 | out |= f; |
267 | return out; |
268 | } |
269 | |
270 | template <typename enumtype, typename storagetype> |
271 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& PxFlags<enumtype, storagetype>::operator&=(enumtype e) |
272 | { |
273 | mBits &= static_cast<storagetype>(e); |
274 | return *this; |
275 | } |
276 | |
277 | template <typename enumtype, typename storagetype> |
278 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& PxFlags<enumtype, storagetype>:: |
279 | operator&=(const PxFlags<enumtype, storagetype>& f) |
280 | { |
281 | mBits &= f.mBits; |
282 | return *this; |
283 | } |
284 | |
285 | template <typename enumtype, typename storagetype> |
286 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> PxFlags<enumtype, storagetype>::operator&(enumtype e) const |
287 | { |
288 | PxFlags<enumtype, storagetype> out = *this; |
289 | out.mBits &= static_cast<storagetype>(e); |
290 | return out; |
291 | } |
292 | |
293 | template <typename enumtype, typename storagetype> |
294 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> PxFlags<enumtype, storagetype>:: |
295 | operator&(const PxFlags<enumtype, storagetype>& f) const |
296 | { |
297 | PxFlags<enumtype, storagetype> out = *this; |
298 | out.mBits &= f.mBits; |
299 | return out; |
300 | } |
301 | |
302 | template <typename enumtype, typename storagetype> |
303 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& PxFlags<enumtype, storagetype>::operator^=(enumtype e) |
304 | { |
305 | mBits ^= static_cast<storagetype>(e); |
306 | return *this; |
307 | } |
308 | |
309 | template <typename enumtype, typename storagetype> |
310 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>& PxFlags<enumtype, storagetype>:: |
311 | operator^=(const PxFlags<enumtype, storagetype>& f) |
312 | { |
313 | mBits ^= f.mBits; |
314 | return *this; |
315 | } |
316 | |
317 | template <typename enumtype, typename storagetype> |
318 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> PxFlags<enumtype, storagetype>::operator^(enumtype e) const |
319 | { |
320 | PxFlags<enumtype, storagetype> out = *this; |
321 | out.mBits ^= static_cast<storagetype>(e); |
322 | return out; |
323 | } |
324 | |
325 | template <typename enumtype, typename storagetype> |
326 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> PxFlags<enumtype, storagetype>:: |
327 | operator^(const PxFlags<enumtype, storagetype>& f) const |
328 | { |
329 | PxFlags<enumtype, storagetype> out = *this; |
330 | out.mBits ^= f.mBits; |
331 | return out; |
332 | } |
333 | |
334 | template <typename enumtype, typename storagetype> |
335 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype> PxFlags<enumtype, storagetype>::operator~(void) const |
336 | { |
337 | PxFlags<enumtype, storagetype> out; |
338 | out.mBits = storagetype(~mBits); |
339 | return out; |
340 | } |
341 | |
342 | template <typename enumtype, typename storagetype> |
343 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>::operator bool(void) const |
344 | { |
345 | return mBits ? true : false; |
346 | } |
347 | |
348 | template <typename enumtype, typename storagetype> |
349 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>::operator uint8_t(void) const |
350 | { |
351 | return static_cast<uint8_t>(mBits); |
352 | } |
353 | |
354 | template <typename enumtype, typename storagetype> |
355 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>::operator uint16_t(void) const |
356 | { |
357 | return static_cast<uint16_t>(mBits); |
358 | } |
359 | |
360 | template <typename enumtype, typename storagetype> |
361 | PX_CUDA_CALLABLE PX_INLINE PxFlags<enumtype, storagetype>::operator uint32_t(void) const |
362 | { |
363 | return static_cast<uint32_t>(mBits); |
364 | } |
365 | |
366 | template <typename enumtype, typename storagetype> |
367 | PX_CUDA_CALLABLE PX_INLINE void PxFlags<enumtype, storagetype>::clear(enumtype e) |
368 | { |
369 | mBits &= ~static_cast<storagetype>(e); |
370 | } |
371 | |
372 | } // namespace physx |
373 | #endif //!PX_DOXYGEN |
374 | |
375 | /** @} */ |
376 | #endif // #ifndef PXFOUNDATION_PXFLAGS_H |
377 | |