HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SYS_Types.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: SYS_Types.h ( SYS Library, C++)
7  *
8  * COMMENTS: Common types used throughout Houdini.
9  */
10 
11 #ifndef __SYS_Types__
12 #define __SYS_Types__
13 
14 #include "SYS_Compiler.h"
15 #include "SYS_Inline.h"
16 
17 /* Include system types */
18 #include <limits> // for std::numeric_limits
19 #include <float.h> // DBL_MAX etc
20 
21 #include <sys/types.h>
22 #ifdef _MSC_VER
23 using pid_t = int; // this is missing from Visual C++'s <sys/types.h>
24 #endif
25 
26 // <sys/types.h> defines macros with the names 'major' and 'minor'.
27 // glibc 2.25+ emits deprecation warnings for this, so eventually the include
28 // of <sys/sysmacros.h> will be removed and the undef'ing won't be necessary.
29 #undef major
30 #undef minor
31 
32 /*
33  * Integer types
34  */
35 using int8 = signed char;
36 using uint8 = unsigned char;
37 using int16 = short;
38 using uint16 = unsigned short;
39 using int32 = int;
40 using uint32 = unsigned int;
41 
42 using uchar = unsigned char;
43 
44 #ifndef MBSD
45 using uint = unsigned int;
46 #endif
47 
48 /*
49  * Unicode code units for Unicode Transformation Formats
50  * Houdini uses UTF8.
51  */
52 using utf8 = char;
53 #ifdef _WIN32
54 using utf16 = wchar_t;
55 #else
56 using utf16 = unsigned short;
57 #endif
58 using utf32 = unsigned int;
59 
60 
61 /*
62  * The SYS_PRI?64 is to mimic the C99 PRI?64 macro.
63  * printf("%" SYS_PRId64, (int64) value);
64  */
65 #if defined(_MSC_VER)
66  #define SYS_PRI64_PREFIX "I64"
67 #elif defined(MBSD)
68  #define SYS_PRI64_PREFIX "ll"
69 #elif defined(AMD64)
70  #define SYS_PRI64_PREFIX "l"
71 #else
72  #define SYS_PRI64_PREFIX "ll"
73 #endif
74 
75 #if defined(SYS_PRI64_PREFIX)
76 #define SYS_PRId64 SYS_PRI64_PREFIX "d"
77 #define SYS_PRIu64 SYS_PRI64_PREFIX "u"
78 #define SYS_PRIx64 SYS_PRI64_PREFIX "x"
79 #define SYS_PRIX64 SYS_PRI64_PREFIX "X"
80 #endif
81 
82 #if SIZEOF_VOID_P == 8
83  #if defined(MBSD)
84  #include <inttypes.h>
85  #define SYS_PRIiPTR PRIiPTR
86  #define SYS_PRIuPTR PRIuPTR
87  #else
88  #define SYS_PRIiPTR SYS_PRId64
89  #define SYS_PRIuPTR SYS_PRIu64
90  #endif
91 #elif SIZEOF_VOID_P == 4
92  #define SYS_PRIiPTR "d"
93  #define SYS_PRIuPTR "u"
94 #else
95  #error Unknown SIZEOF_VOID_P
96 #endif
97 
98 /*
99  * Avoid using uint64.
100  * The extra bit of precision is NOT worth the cost in pain and suffering
101  * induced by use of unsigned.
102  */
103 #if defined(WIN32)
104  using int64 = __int64;
105  using uint64 = unsigned __int64;
106 #elif defined(MBSD)
107  // On MBSD, int64/uint64 are also defined in the system headers so we must
108  // declare these in the same way or else we get conflicts.
109  #include <stdint.h>
110  using int64 = int64_t;
111  using uint64 = uint64_t;
112 #elif defined(AMD64)
113  using int64 = long;
114  using uint64 = unsigned long;
115 #else
116  using int64 = long long;
117  using uint64 = unsigned long long;
118 #endif
119 
120 /*
121  * The problem with int64 is that it implies that it is a fixed 64-bit quantity
122  * that is saved to disk. Therefore, we need another integral type for
123  * indexing our arrays.
124  */
125 using exint = int64;
126 
127 /*
128  * When casting away const, it is good to use const_cast as it tells
129  * the reader what you are doing (as opposed to C-style cast)
130  * However, it requires redundant information that breaks cut-and-paste
131  * code. So this template lets you cast away const without worrying
132  * about the underlying type.
133  */
134 template <typename T>
136 SYSconst_cast(const T *foo)
137 {
138  return const_cast<T *>(foo);
139 }
140 
141 template <typename T>
143 SYSconst_cast(const T &foo)
144 {
145  return const_cast<T &>(foo);
146 }
147 
148 /*
149  * Integer limits
150  */
151 #if defined(GCC3) && defined(AMD64)
152 #define SYS_INT64_C(x) x ## L
153 #define SYS_UINT64_C(x) x ## UL
154 #else
155 #define SYS_INT64_C(x) x ## LL
156 #define SYS_UINT64_C(x) x ## ULL
157 #endif
158 
159 // int8/uint8
160 #define SYS_INT8_MIN std::numeric_limits<int8>::min()
161 #define SYS_INT8_MAX std::numeric_limits<int8>::max()
162 #define SYS_UINT8_MAX std::numeric_limits<uint8>::max()
163 
164 // int16/uint16
165 #define SYS_INT16_MIN std::numeric_limits<int16>::min()
166 #define SYS_INT16_MAX std::numeric_limits<int16>::max()
167 #define SYS_UINT16_MAX std::numeric_limits<uint16>::max()
168 
169 // int32/uint32
170 #define SYS_INT32_MIN std::numeric_limits<int32>::min()
171 #define SYS_INT32_MAX std::numeric_limits<int32>::max()
172 #define SYS_UINT32_MAX std::numeric_limits<uint32>::max()
173 
174 // int64/uint64
175 #define SYS_INT64_MIN std::numeric_limits<int64>::min()
176 #define SYS_INT64_MAX std::numeric_limits<int64>::max()
177 #define SYS_UINT64_MAX std::numeric_limits<uint64>::max()
178 
179 // exint
180 #define SYS_EXINT_MIN SYS_INT64_MIN
181 #define SYS_EXINT_MAX SYS_INT64_MAX
182 
183 
184 /*
185  * These are the precision you should use for writing out
186  * streams to guarantee that you fully save a double or a float.
187  * Note that limits.h defines DBL_DIG and FLT_DIG - they are
188  * defined incorrectly!
189  */
190 #define SYS_DBL_DIG 17
191 #define SYS_FLT_DIG 9
192 
193 /*
194  * Floating Point Types
195  * By specifying the number of bits (i.e. fpreal32), the precision is
196  * automatically determined. The fpreal type defaults to the precision for the
197  * Houdini release and may change accordingly. fpreal should be used unless
198  * there are specific reasons for requiring a certain precision.
199  */
200 using fpreal32 = float;
201 using fpreal64 = double;
202 
203 /* Include half-precision floats after other types are defined */
204 #include "fpreal16.h"
205 
206 /* Floating Point Limits/Tolerance */
207 
208 #define SYS_FTOLERANCE ((fpreal32)0.00001)
209 #define SYS_FTOLERANCE_D (fpreal64(SYS_FTOLERANCE))
210 
211 // The difference between 1 and the least value greater than 1 that can be
212 // represented.
213 #define SYS_FP32_EPSILON std::numeric_limits<fpreal32>::epsilon()
214 #define SYS_FP64_EPSILON std::numeric_limits<fpreal64>::epsilon()
215 
216 #define SYS_FP16_MIN ((fpreal32)H_REAL16_MIN)
217 #define SYS_FP32_MIN ((fpreal32)2e-45)
218 #define SYS_FP64_MIN ((fpreal64)2e-324)
219 #define SYS_FP16_MAX ((fpreal32)H_REAL16_MAX)
220 #define SYS_FP32_MAX std::numeric_limits<fpreal32>::max()
221 #define SYS_FP64_MAX std::numeric_limits<fpreal64>::max()
222 
223 // Tolerance values we can use for templates. This can surely be expanded
224 template<typename T>
225 struct SYS_Types : public std::numeric_limits<T>
226 {
227  static T tolerance() { return static_cast<T>(0); }
228 };
229 template<>
230 struct SYS_Types<int32> : public std::numeric_limits<int32>
231 {
232  static int32 tolerance() { return 0; }
233 };
234 template<>
235 struct SYS_Types<int64> : public std::numeric_limits<int64>
236 {
237  static int64 tolerance() { return 0; }
238 };
239 template<>
240 struct SYS_Types<fpreal32> : public std::numeric_limits<fpreal32>
241 {
242  static fpreal32 tolerance() { return SYS_FTOLERANCE; }
243 };
244 template<>
245 struct SYS_Types<fpreal64> : public std::numeric_limits<fpreal64>
246 {
247  static fpreal64 tolerance() { return SYS_FTOLERANCE_D; }
248 };
249 
250 
251 /*
252  * fpreal definition
253  *
254  * Default to double unless SIZEOF_FPREAL_IS_4 is defined as 1
255  */
256 #if SIZEOF_FPREAL_IS_4
257  /*
258  * Single precision fpreal
259  */
260  using fpreal = fpreal32;
261 
262  // sizeof(fpreal)
263  #define SYS_SIZEOF_FPREAL 4
264 
265  #define SYS_FPREAL_DIG SYS_FLT_DIG
266  #define SYS_FTOLERANCE_R (fpreal(SYS_FTOLERANCE))
267  #define SYS_FPEPSILON SYS_FP32_EPSILON
268  #define SYS_FPREAL_MIN SYS_FP32_MIN
269  #define SYS_FPREAL_MAX SYS_FP32_MAX
270 
271  // The scan code to use in scanf() for fpreal
272  #define SYS_SCANF_FPREAL "g"
273 #else
274  /*
275  * Double precision fpreal
276  */
277  using fpreal = fpreal64;
278 
279  // sizeof(fpreal)
280  #define SYS_SIZEOF_FPREAL 8
281 
282  #define SYS_FPREAL_DIG SYS_DBL_DIG
283  #define SYS_FTOLERANCE_R (fpreal(SYS_FTOLERANCE))
284  #define SYS_FPEPSILON SYS_FP64_EPSILON
285  #define SYS_FPREAL_MIN SYS_FP64_MIN
286  #define SYS_FPREAL_MAX SYS_FP64_MAX
287 
288  // The scan code to use in scanf() for fpreal
289  #define SYS_SCANF_FPREAL "lg"
290 #endif
291 /* need an extra level to ensure complete macro expansion before stringize */
292 #define SYS_DIG_FMT_INTERNAL(PREC) "%." #PREC "g"
293 #define SYS_DIG_FMT(PREC) SYS_DIG_FMT_INTERNAL(PREC)
294  /* float precision */
295 #define SYS_FLT_DIG_FMT SYS_DIG_FMT(SYS_FLT_DIG)
296  /* double precision */
297 #define SYS_DBL_DIG_FMT SYS_DIG_FMT(SYS_DBL_DIG)
298  /* fpreal precision */
299 #define SYS_FPREAL_DIG_FMT SYS_DIG_FMT(SYS_FPREAL_DIG)
300 
301 /*
302  * When declaring floating point constants, please use the following macros.
303  * If a floating point expression contains a double precision constant, all
304  * arguments will be promoted to double precision then the result cast back to
305  * single precision. To avoid the cost of conversions, please use the correct
306  * types. Try to avoid using 180.0F.
307  */
308 
309 #define CONST_INT8(x) ((int8)x)
310 #define CONST_UINT8(x) ((uint8)x)
311 #define CONST_INT16(x) ((int16)x)
312 #define CONST_UINT16(x) ((uint16)x)
313 #define CONST_INT32(x) ((int32)x)
314 #define CONST_UINT32(x) ((uint32)x)
315 
316 #if defined(WIN32)
317  #define CONST_INT64(x) ((int64)x)
318  #define CONST_UINT64(x) ((uint64)x)
319 #else
320  #define CONST_INT64(x) (x##LL)
321  #define CONST_UINT64(x) (x##LL)
322 #endif
323 
324 #define CONST_FPREAL16(c) ((fpreal16)c)
325 #define CONST_FPREAL32(c) ((fpreal32)c)
326 #define CONST_FPREAL64(c) ((fpreal64)c)
327 #define CONST_FPREAL(c) ((fpreal)c)
328 
329 ///
330 /// SYS_FPRealUnionT for type-safe casting with integral types
331 ///
332 template <typename T>
334 
335 template <>
337 {
339 
340  using int_type = int16;
341  using uint_type = uint16;
343 
344  enum {
345  EXPONENT_BITS = 5,
346  MANTISSA_BITS = 10,
347  EXPONENT_BIAS = 15
348  };
349 
353 
354  struct
355  {
356  uint_type mantissa_val: 10;
357  uint_type exponent_val: 5;
358  uint_type sign_val: 1;
359  };
360 };
361 
362 
363 template <>
365 {
366  using int_type = int32;
367  using uint_type = uint32;
369 
370  enum {
371  EXPONENT_BITS = 8,
372  MANTISSA_BITS = 23,
373  EXPONENT_BIAS = 127 };
374 
378 
379  struct
380  {
381  uint_type mantissa_val: 23;
382  uint_type exponent_val: 8;
383  uint_type sign_val: 1;
384  };
385 };
386 
387 template <>
389 {
390  using int_type = int64;
391  using uint_type = uint64;
393 
394  enum {
395  EXPONENT_BITS = 11,
396  MANTISSA_BITS = 52,
397  EXPONENT_BIAS = 1023 };
398 
402 
403  struct
404  {
405  uint_type mantissa_val: 52;
406  uint_type exponent_val: 11;
407  uint_type sign_val: 1;
408  };
409 };
410 
415 
416 /// Special enum to disambiguate default constructors from empty constructors.
417 /// This can be handy for constructing static objects that do not need to
418 /// be explicitly constructed but are safe to use if all members are
419 /// initialized to zero upon DSO load (e.g. their storage is defined by the
420 /// .bss section in ELF files).
422 
423 
424 /// Mark a function as doing printf-style formatting, and generate warnings
425 /// if the formatting string doesn't match the types. string_index is the
426 /// parameter index of the format string, and first_to_check is the index of
427 /// the "..." parameter. These indices are both base 1, and "this" counts as
428 /// the first parameter if it's a method.
429 #if (defined(GCC3) && !defined(__clang__)) || SYS_IS_CLANG_GE(3,3)
430  #define SYS_PRINTF_CHECK_ATTRIBUTE(string_index, first_to_check) \
431  __attribute__ ((format (printf, string_index, first_to_check)))
432 #else
433  #define SYS_PRINTF_CHECK_ATTRIBUTE(string_index, first_to_check)
434 #endif
435 
436 
437 /// Struct modifiers
438 ///
439 /// Note that these qualifiers can only appear in struct declarations.
440 ///
441 // @{
442 
443 /// Compiler hint to pack the struct with the specified alignment.
444 /// Note this is not supported on some platforms and is only a hint.
445 #if defined(GCC4)
446 # define SYS_PACKED_STRUCT_HINT_BEGIN(name, n) \
447  struct __attribute__((__packed__, __aligned__(n))) name
448 # define SYS_PACKED_STRUCT_HINT_END
449 #elif defined(_MSC_VER)
450 # define SYS_PACKED_STRUCT_HINT_BEGIN(name, n) \
451  __pragma(pack(push, n)) struct name
452 # define SYS_PACKED_STRUCT_HINT_END __pragma(pack(pop))
453 #else
454 # define SYS_PACKED_STRUCT_HINT_BEGIN(name, n) struct name
455 # define SYS_PACKED_STRUCT_HINT_END
456 #endif
457 // @}
458 
459 #include "SYS_Decimal128.h"
461 
462 #endif
unsigned short uint16
Definition: SYS_Types.h:38
int int32
Definition: SYS_Types.h:39
static int32 tolerance()
Definition: SYS_Types.h:232
unsigned short utf16
Definition: SYS_Types.h:56
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:136
int64 exint
Definition: SYS_Types.h:125
#define SYS_FTOLERANCE_D
Definition: SYS_Types.h:209
unsigned long long uint64
Definition: SYS_Types.h:117
float fpreal32
Definition: SYS_Types.h:200
SYS_EmptyConstructor
Definition: SYS_Types.h:421
double fpreal64
Definition: SYS_Types.h:201
unsigned char uint8
Definition: SYS_Types.h:36
static T tolerance()
Definition: SYS_Types.h:227
unsigned int utf32
Definition: SYS_Types.h:58
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
long long int64
Definition: SYS_Types.h:116
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
signed char int8
Definition: SYS_Types.h:35
static int64 tolerance()
Definition: SYS_Types.h:237
short int16
Definition: SYS_Types.h:37
fpreal64 fpreal
Definition: SYS_Types.h:277
Decimal128 floating point class (IEEE 754-2008)
static fpreal64 tolerance()
Definition: SYS_Types.h:247
unsigned int uint32
Definition: SYS_Types.h:40
#define SYS_FTOLERANCE
Definition: SYS_Types.h:208
static fpreal32 tolerance()
Definition: SYS_Types.h:242
char utf8
Definition: SYS_Types.h:52
unsigned int uint
Definition: SYS_Types.h:45
unsigned char uchar
Definition: SYS_Types.h:42