xref: /aosp_15_r20/external/deqp/framework/delibs/decpp/deDefs.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker #ifndef _DEDEFS_HPP
2*35238bceSAndroid Build Coastguard Worker #define _DEDEFS_HPP
3*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  * drawElements C++ Base Library
5*35238bceSAndroid Build Coastguard Worker  * -----------------------------
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
8*35238bceSAndroid Build Coastguard Worker  *
9*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
10*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
11*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
14*35238bceSAndroid Build Coastguard Worker  *
15*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
16*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
17*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
19*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
20*35238bceSAndroid Build Coastguard Worker  *
21*35238bceSAndroid Build Coastguard Worker  *//*!
22*35238bceSAndroid Build Coastguard Worker  * \file
23*35238bceSAndroid Build Coastguard Worker  * \brief Basic definitions.
24*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "deDefs.h"
27*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
28*35238bceSAndroid Build Coastguard Worker 
29*35238bceSAndroid Build Coastguard Worker #if !defined(__cplusplus)
30*35238bceSAndroid Build Coastguard Worker #error "C++ is required"
31*35238bceSAndroid Build Coastguard Worker #endif
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker #include <type_traits>
34*35238bceSAndroid Build Coastguard Worker #include <utility>
35*35238bceSAndroid Build Coastguard Worker 
36*35238bceSAndroid Build Coastguard Worker namespace de
37*35238bceSAndroid Build Coastguard Worker {
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker //! Compute absolute value of x.
40*35238bceSAndroid Build Coastguard Worker template <typename T>
abs(T x)41*35238bceSAndroid Build Coastguard Worker inline T abs(T x)
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker     return x < T(0) ? -x : x;
44*35238bceSAndroid Build Coastguard Worker }
45*35238bceSAndroid Build Coastguard Worker 
46*35238bceSAndroid Build Coastguard Worker //! Get minimum of x and y.
47*35238bceSAndroid Build Coastguard Worker template <typename T>
min(T x,T y)48*35238bceSAndroid Build Coastguard Worker inline T min(T x, T y)
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker     return x <= y ? x : y;
51*35238bceSAndroid Build Coastguard Worker }
52*35238bceSAndroid Build Coastguard Worker 
53*35238bceSAndroid Build Coastguard Worker //! Get maximum of x and y.
54*35238bceSAndroid Build Coastguard Worker template <typename T>
max(T x,T y)55*35238bceSAndroid Build Coastguard Worker inline T max(T x, T y)
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker     return x >= y ? x : y;
58*35238bceSAndroid Build Coastguard Worker }
59*35238bceSAndroid Build Coastguard Worker 
60*35238bceSAndroid Build Coastguard Worker //! Clamp x in range a <= x <= b.
61*35238bceSAndroid Build Coastguard Worker template <typename T>
clamp(T x,T a,T b)62*35238bceSAndroid Build Coastguard Worker inline T clamp(T x, T a, T b)
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(a <= b);
65*35238bceSAndroid Build Coastguard Worker     return x < a ? a : (x > b ? b : x);
66*35238bceSAndroid Build Coastguard Worker }
67*35238bceSAndroid Build Coastguard Worker 
68*35238bceSAndroid Build Coastguard Worker //! Test if x is in bounds a <= x < b.
69*35238bceSAndroid Build Coastguard Worker template <typename T>
inBounds(T x,T a,T b)70*35238bceSAndroid Build Coastguard Worker inline bool inBounds(T x, T a, T b)
71*35238bceSAndroid Build Coastguard Worker {
72*35238bceSAndroid Build Coastguard Worker     return a <= x && x < b;
73*35238bceSAndroid Build Coastguard Worker }
74*35238bceSAndroid Build Coastguard Worker 
75*35238bceSAndroid Build Coastguard Worker //! Test if x is in range a <= x <= b.
76*35238bceSAndroid Build Coastguard Worker template <typename T>
inRange(T x,T a,T b)77*35238bceSAndroid Build Coastguard Worker inline bool inRange(T x, T a, T b)
78*35238bceSAndroid Build Coastguard Worker {
79*35238bceSAndroid Build Coastguard Worker     return a <= x && x <= b;
80*35238bceSAndroid Build Coastguard Worker }
81*35238bceSAndroid Build Coastguard Worker 
82*35238bceSAndroid Build Coastguard Worker //! Return T with low n bits set
83*35238bceSAndroid Build Coastguard Worker template <typename T>
rightSetMask(T n)84*35238bceSAndroid Build Coastguard Worker inline T rightSetMask(T n)
85*35238bceSAndroid Build Coastguard Worker {
86*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(n < T(sizeof(T) * 8));
87*35238bceSAndroid Build Coastguard Worker     T one = T(1);
88*35238bceSAndroid Build Coastguard Worker     return T((one << n) - one);
89*35238bceSAndroid Build Coastguard Worker }
90*35238bceSAndroid Build Coastguard Worker 
91*35238bceSAndroid Build Coastguard Worker //! Return T with low n bits reset
92*35238bceSAndroid Build Coastguard Worker template <typename T>
rightZeroMask(T n)93*35238bceSAndroid Build Coastguard Worker inline T rightZeroMask(T n)
94*35238bceSAndroid Build Coastguard Worker {
95*35238bceSAndroid Build Coastguard Worker     return T(~rightSetMask(n));
96*35238bceSAndroid Build Coastguard Worker }
97*35238bceSAndroid Build Coastguard Worker 
98*35238bceSAndroid Build Coastguard Worker //! Return T with high n bits set
99*35238bceSAndroid Build Coastguard Worker template <typename T>
leftSetMask(T n)100*35238bceSAndroid Build Coastguard Worker inline T leftSetMask(T n)
101*35238bceSAndroid Build Coastguard Worker {
102*35238bceSAndroid Build Coastguard Worker     const T tlen = T(sizeof(T) * 8);
103*35238bceSAndroid Build Coastguard Worker     return T(~rightSetMask(tlen >= n ? tlen - n : T(0)));
104*35238bceSAndroid Build Coastguard Worker }
105*35238bceSAndroid Build Coastguard Worker 
106*35238bceSAndroid Build Coastguard Worker //! Return T with high n bits reset
107*35238bceSAndroid Build Coastguard Worker template <typename T>
leftZeroMask(T n)108*35238bceSAndroid Build Coastguard Worker inline T leftZeroMask(T n)
109*35238bceSAndroid Build Coastguard Worker {
110*35238bceSAndroid Build Coastguard Worker     return T(~leftSetMask(n));
111*35238bceSAndroid Build Coastguard Worker }
112*35238bceSAndroid Build Coastguard Worker 
113*35238bceSAndroid Build Coastguard Worker //! Round x up to a multiple of y.
114*35238bceSAndroid Build Coastguard Worker template <typename T>
roundUp(T x,T y)115*35238bceSAndroid Build Coastguard Worker inline T roundUp(T x, T y)
116*35238bceSAndroid Build Coastguard Worker {
117*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(y != T(0));
118*35238bceSAndroid Build Coastguard Worker     const T mod = x % y;
119*35238bceSAndroid Build Coastguard Worker     return x + ((mod == T(0)) ? T(0) : (y - mod));
120*35238bceSAndroid Build Coastguard Worker }
121*35238bceSAndroid Build Coastguard Worker 
122*35238bceSAndroid Build Coastguard Worker //! Round x down to a multiple of y.
123*35238bceSAndroid Build Coastguard Worker template <typename T>
roundDown(T x,T y)124*35238bceSAndroid Build Coastguard Worker inline T roundDown(T x, T y)
125*35238bceSAndroid Build Coastguard Worker {
126*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(y != T(0));
127*35238bceSAndroid Build Coastguard Worker     return (x / y) * y;
128*35238bceSAndroid Build Coastguard Worker }
129*35238bceSAndroid Build Coastguard Worker 
130*35238bceSAndroid Build Coastguard Worker //! Find the greatest common divisor of x and y.
131*35238bceSAndroid Build Coastguard Worker template <typename T>
gcd(T x,T y)132*35238bceSAndroid Build Coastguard Worker T gcd(T x, T y)
133*35238bceSAndroid Build Coastguard Worker {
134*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(std::is_integral<T>::value && std::is_unsigned<T>::value);
135*35238bceSAndroid Build Coastguard Worker 
136*35238bceSAndroid Build Coastguard Worker     // Euclidean algorithm.
137*35238bceSAndroid Build Coastguard Worker     while (y != T{0})
138*35238bceSAndroid Build Coastguard Worker     {
139*35238bceSAndroid Build Coastguard Worker         T mod = x % y;
140*35238bceSAndroid Build Coastguard Worker         x     = y;
141*35238bceSAndroid Build Coastguard Worker         y     = mod;
142*35238bceSAndroid Build Coastguard Worker     }
143*35238bceSAndroid Build Coastguard Worker 
144*35238bceSAndroid Build Coastguard Worker     return x;
145*35238bceSAndroid Build Coastguard Worker }
146*35238bceSAndroid Build Coastguard Worker 
147*35238bceSAndroid Build Coastguard Worker //! Find the least common multiple of x and y.
148*35238bceSAndroid Build Coastguard Worker template <typename T>
lcm(T x,T y)149*35238bceSAndroid Build Coastguard Worker T lcm(T x, T y)
150*35238bceSAndroid Build Coastguard Worker {
151*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(std::is_integral<T>::value && std::is_unsigned<T>::value);
152*35238bceSAndroid Build Coastguard Worker 
153*35238bceSAndroid Build Coastguard Worker     T prod = x * y;
154*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(x == 0 || prod / x == y); // Check overflow just in case.
155*35238bceSAndroid Build Coastguard Worker     return (prod) / gcd(x, y);
156*35238bceSAndroid Build Coastguard Worker }
157*35238bceSAndroid Build Coastguard Worker 
158*35238bceSAndroid Build Coastguard Worker //! Helper for DE_CHECK() macros.
159*35238bceSAndroid Build Coastguard Worker void throwRuntimeError(const char *message, const char *expr, const char *file, int line);
160*35238bceSAndroid Build Coastguard Worker 
161*35238bceSAndroid Build Coastguard Worker //! Default deleter.
162*35238bceSAndroid Build Coastguard Worker template <typename T>
163*35238bceSAndroid Build Coastguard Worker struct DefaultDeleter
164*35238bceSAndroid Build Coastguard Worker {
DefaultDeleterde::DefaultDeleter165*35238bceSAndroid Build Coastguard Worker     inline DefaultDeleter(void)
166*35238bceSAndroid Build Coastguard Worker     {
167*35238bceSAndroid Build Coastguard Worker     }
168*35238bceSAndroid Build Coastguard Worker     template <typename U>
DefaultDeleterde::DefaultDeleter169*35238bceSAndroid Build Coastguard Worker     inline DefaultDeleter(const DefaultDeleter<U> &)
170*35238bceSAndroid Build Coastguard Worker     {
171*35238bceSAndroid Build Coastguard Worker     }
172*35238bceSAndroid Build Coastguard Worker     template <typename U>
operator =de::DefaultDeleter173*35238bceSAndroid Build Coastguard Worker     inline DefaultDeleter<T> &operator=(const DefaultDeleter<U> &)
174*35238bceSAndroid Build Coastguard Worker     {
175*35238bceSAndroid Build Coastguard Worker         return *this;
176*35238bceSAndroid Build Coastguard Worker     }
operator ()de::DefaultDeleter177*35238bceSAndroid Build Coastguard Worker     inline void operator()(T *ptr) const
178*35238bceSAndroid Build Coastguard Worker     {
179*35238bceSAndroid Build Coastguard Worker         delete ptr;
180*35238bceSAndroid Build Coastguard Worker     }
181*35238bceSAndroid Build Coastguard Worker };
182*35238bceSAndroid Build Coastguard Worker 
183*35238bceSAndroid Build Coastguard Worker //! A deleter for arrays
184*35238bceSAndroid Build Coastguard Worker template <typename T>
185*35238bceSAndroid Build Coastguard Worker struct ArrayDeleter
186*35238bceSAndroid Build Coastguard Worker {
ArrayDeleterde::ArrayDeleter187*35238bceSAndroid Build Coastguard Worker     inline ArrayDeleter(void)
188*35238bceSAndroid Build Coastguard Worker     {
189*35238bceSAndroid Build Coastguard Worker     }
190*35238bceSAndroid Build Coastguard Worker     template <typename U>
ArrayDeleterde::ArrayDeleter191*35238bceSAndroid Build Coastguard Worker     inline ArrayDeleter(const ArrayDeleter<U> &)
192*35238bceSAndroid Build Coastguard Worker     {
193*35238bceSAndroid Build Coastguard Worker     }
194*35238bceSAndroid Build Coastguard Worker     template <typename U>
operator =de::ArrayDeleter195*35238bceSAndroid Build Coastguard Worker     inline ArrayDeleter<T> &operator=(const ArrayDeleter<U> &)
196*35238bceSAndroid Build Coastguard Worker     {
197*35238bceSAndroid Build Coastguard Worker         return *this;
198*35238bceSAndroid Build Coastguard Worker     }
operator ()de::ArrayDeleter199*35238bceSAndroid Build Coastguard Worker     inline void operator()(T *ptr) const
200*35238bceSAndroid Build Coastguard Worker     {
201*35238bceSAndroid Build Coastguard Worker         delete[] ptr;
202*35238bceSAndroid Build Coastguard Worker     }
203*35238bceSAndroid Build Coastguard Worker };
204*35238bceSAndroid Build Coastguard Worker 
205*35238bceSAndroid Build Coastguard Worker //! Get required memory alignment for type
206*35238bceSAndroid Build Coastguard Worker template <typename T>
alignOf(void)207*35238bceSAndroid Build Coastguard Worker size_t alignOf(void)
208*35238bceSAndroid Build Coastguard Worker {
209*35238bceSAndroid Build Coastguard Worker     struct PaddingCheck
210*35238bceSAndroid Build Coastguard Worker     {
211*35238bceSAndroid Build Coastguard Worker         uint8_t b;
212*35238bceSAndroid Build Coastguard Worker         T t;
213*35238bceSAndroid Build Coastguard Worker     };
214*35238bceSAndroid Build Coastguard Worker     return (size_t)offsetof(PaddingCheck, t);
215*35238bceSAndroid Build Coastguard Worker }
216*35238bceSAndroid Build Coastguard Worker 
217*35238bceSAndroid Build Coastguard Worker //! Similar to DE_LENGTH_OF_ARRAY but constexpr and without auxiliar helpers.
218*35238bceSAndroid Build Coastguard Worker template <typename T, size_t N>
arrayLength(const T (&)[N])219*35238bceSAndroid Build Coastguard Worker constexpr size_t arrayLength(const T (&)[N])
220*35238bceSAndroid Build Coastguard Worker {
221*35238bceSAndroid Build Coastguard Worker     return N;
222*35238bceSAndroid Build Coastguard Worker }
223*35238bceSAndroid Build Coastguard Worker 
224*35238bceSAndroid Build Coastguard Worker //! Get least significant bit index
findLSB(uint32_t value)225*35238bceSAndroid Build Coastguard Worker inline int findLSB(uint32_t value)
226*35238bceSAndroid Build Coastguard Worker {
227*35238bceSAndroid Build Coastguard Worker     return value ? deCtz32(value) : (-1);
228*35238bceSAndroid Build Coastguard Worker }
229*35238bceSAndroid Build Coastguard Worker 
230*35238bceSAndroid Build Coastguard Worker //! Get most significant bit index
findMSB(uint32_t value)231*35238bceSAndroid Build Coastguard Worker inline int findMSB(uint32_t value)
232*35238bceSAndroid Build Coastguard Worker {
233*35238bceSAndroid Build Coastguard Worker     return 31 - deClz32(value);
234*35238bceSAndroid Build Coastguard Worker }
235*35238bceSAndroid Build Coastguard Worker 
236*35238bceSAndroid Build Coastguard Worker //! Get most significant bit index
findMSB(int32_t value)237*35238bceSAndroid Build Coastguard Worker inline int findMSB(int32_t value)
238*35238bceSAndroid Build Coastguard Worker {
239*35238bceSAndroid Build Coastguard Worker     return (value < 0) ? findMSB(~(uint32_t)value) : findMSB((uint32_t)value);
240*35238bceSAndroid Build Coastguard Worker }
241*35238bceSAndroid Build Coastguard Worker 
242*35238bceSAndroid Build Coastguard Worker } // namespace de
243*35238bceSAndroid Build Coastguard Worker 
244*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
245*35238bceSAndroid Build Coastguard Worker  * \brief Throw runtime error if condition is not met.
246*35238bceSAndroid Build Coastguard Worker  * \param X        Condition to check.
247*35238bceSAndroid Build Coastguard Worker  *
248*35238bceSAndroid Build Coastguard Worker  * This macro throws std::runtime_error if condition X is not met.
249*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
250*35238bceSAndroid Build Coastguard Worker #define DE_CHECK_RUNTIME_ERR(X)                                       \
251*35238bceSAndroid Build Coastguard Worker     do                                                                \
252*35238bceSAndroid Build Coastguard Worker     {                                                                 \
253*35238bceSAndroid Build Coastguard Worker         if ((!false && (X)) ? false : true)                           \
254*35238bceSAndroid Build Coastguard Worker             ::de::throwRuntimeError(DE_NULL, #X, __FILE__, __LINE__); \
255*35238bceSAndroid Build Coastguard Worker     } while (false)
256*35238bceSAndroid Build Coastguard Worker 
257*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
258*35238bceSAndroid Build Coastguard Worker  * \brief Throw runtime error if condition is not met.
259*35238bceSAndroid Build Coastguard Worker  * \param X        Condition to check.
260*35238bceSAndroid Build Coastguard Worker  * \param MSG    Additional message to include in the exception.
261*35238bceSAndroid Build Coastguard Worker  *
262*35238bceSAndroid Build Coastguard Worker  * This macro throws std::runtime_error with message MSG if condition X is
263*35238bceSAndroid Build Coastguard Worker  * not met.
264*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
265*35238bceSAndroid Build Coastguard Worker #define DE_CHECK_RUNTIME_ERR_MSG(X, MSG)                          \
266*35238bceSAndroid Build Coastguard Worker     do                                                            \
267*35238bceSAndroid Build Coastguard Worker     {                                                             \
268*35238bceSAndroid Build Coastguard Worker         if ((!false && (X)) ? false : true)                       \
269*35238bceSAndroid Build Coastguard Worker             ::de::throwRuntimeError(MSG, #X, __FILE__, __LINE__); \
270*35238bceSAndroid Build Coastguard Worker     } while (false)
271*35238bceSAndroid Build Coastguard Worker 
272*35238bceSAndroid Build Coastguard Worker //! Get array start pointer.
273*35238bceSAndroid Build Coastguard Worker #define DE_ARRAY_BEGIN(ARR) (&(ARR)[0])
274*35238bceSAndroid Build Coastguard Worker 
275*35238bceSAndroid Build Coastguard Worker //! Get array end pointer.
276*35238bceSAndroid Build Coastguard Worker #define DE_ARRAY_END(ARR) (DE_ARRAY_BEGIN(ARR) + DE_LENGTH_OF_ARRAY(ARR))
277*35238bceSAndroid Build Coastguard Worker 
278*35238bceSAndroid Build Coastguard Worker //! Empty C++ compilation unit silencing.
279*35238bceSAndroid Build Coastguard Worker #if (DE_COMPILER == DE_COMPILER_MSC)
280*35238bceSAndroid Build Coastguard Worker #define DE_EMPTY_CPP_FILE \
281*35238bceSAndroid Build Coastguard Worker     namespace             \
282*35238bceSAndroid Build Coastguard Worker     {                     \
283*35238bceSAndroid Build Coastguard Worker     uint8_t unused;       \
284*35238bceSAndroid Build Coastguard Worker     }
285*35238bceSAndroid Build Coastguard Worker #else
286*35238bceSAndroid Build Coastguard Worker #define DE_EMPTY_CPP_FILE
287*35238bceSAndroid Build Coastguard Worker #endif
288*35238bceSAndroid Build Coastguard Worker 
289*35238bceSAndroid Build Coastguard Worker // Warn if type is constructed, but left unused
290*35238bceSAndroid Build Coastguard Worker //
291*35238bceSAndroid Build Coastguard Worker // Used in types with non-trivial ctor/dtor but with ctor-dtor pair causing no (observable)
292*35238bceSAndroid Build Coastguard Worker // side-effects.
293*35238bceSAndroid Build Coastguard Worker //
294*35238bceSAndroid Build Coastguard Worker // \todo add attribute for GCC
295*35238bceSAndroid Build Coastguard Worker #if (DE_COMPILER == DE_COMPILER_CLANG) && defined(__has_attribute)
296*35238bceSAndroid Build Coastguard Worker #if __has_attribute(warn_unused)
297*35238bceSAndroid Build Coastguard Worker #define DE_WARN_UNUSED_TYPE __attribute__((warn_unused))
298*35238bceSAndroid Build Coastguard Worker #else
299*35238bceSAndroid Build Coastguard Worker #define DE_WARN_UNUSED_TYPE
300*35238bceSAndroid Build Coastguard Worker #endif
301*35238bceSAndroid Build Coastguard Worker #else
302*35238bceSAndroid Build Coastguard Worker #define DE_WARN_UNUSED_TYPE
303*35238bceSAndroid Build Coastguard Worker #endif
304*35238bceSAndroid Build Coastguard Worker 
305*35238bceSAndroid Build Coastguard Worker #endif // _DEDEFS_HPP
306