MDL SDK API nvidia_logo_transpbg.gif Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
types.h
Go to the documentation of this file.
1 /***************************************************************************************************
2  * Copyright 2022 NVIDIA Corporation. All rights reserved.
3  **************************************************************************************************/
8 
9 #ifndef MI_BASE_TYPES_H
10 #define MI_BASE_TYPES_H
11 
12 #include <mi/base/config.h>
13 #include <mi/base/assert.h>
14 #include <cstddef> // define size_t, ptrdiff_t
15 #include <cstdlib> // declare abs
16 #include <cmath> // declare abs overloads
17 
18 #ifndef MI_BASE_NO_STL
19 #include <algorithm> // define min, max
20 #endif // MI_BASE_NO_STL
21 
22 namespace mi {
23 
34 // primitive types of known bit size
35 
36 typedef signed char Sint8;
37 typedef signed short Sint16;
38 typedef signed int Sint32;
39 typedef unsigned char Uint8;
40 typedef unsigned short Uint16;
41 typedef unsigned int Uint32;
42 
43 typedef float Float32;
44 typedef double Float64;
45 
46 #if defined(MI_COMPILER_MSC)
47 
48 typedef signed __int64 Sint64;
49 typedef unsigned __int64 Uint64;
50 
51 #elif defined(MI_COMPILER_GCC) // defined(MI_COMPILER_MSC)
52 
53 typedef long long Sint64;
54 typedef unsigned long long Uint64;
55 
56 #else // defined(MI_COMPILER_GCC)
57 
58 typedef signed long long Sint64;
59 typedef unsigned long long Uint64;
60 
61 #endif // defined(MI_COMPILER_GCC)
62 
63 mi_static_assert( sizeof( Sint8) == 1);
64 mi_static_assert( sizeof( Sint16) == 2);
65 mi_static_assert( sizeof( Sint32) == 4);
66 mi_static_assert( sizeof( Sint64) == 8);
67 mi_static_assert( sizeof( Uint8) == 1);
68 mi_static_assert( sizeof( Uint16) == 2);
69 mi_static_assert( sizeof( Uint32) == 4);
70 mi_static_assert( sizeof( Uint64) == 8);
71 mi_static_assert( sizeof(Float32) == 4);
72 mi_static_assert( sizeof(Float64) == 8);
73 
80 #ifdef MI_ARCH_64BIT
81 #define MI_BASE_FMT_MI_SINT64 "lld"
82 #else // MI_ARCH_64BIT
83 #define MI_BASE_FMT_MI_SINT64 "d"
84 #endif // MI_ARCH_64BIT
85 
92 #ifdef MI_ARCH_64BIT
93 #define MI_BASE_FMT_MI_UINT64 "llu"
94 #else // MI_ARCH_64BIT
95 #define MI_BASE_FMT_MI_UINT64 "u"
96 #endif // MI_ARCH_64BIT
97 
103 #ifdef MI_ARCH_64BIT
104 typedef Uint64 Size;
105 #else // MI_ARCH_64BIT
106 typedef Uint32 Size;
107 #endif // MI_ARCH_64BIT
108 
113 #ifdef MI_ARCH_64BIT
115 #else // MI_ARCH_64BIT
116 typedef Sint32 Difference;
117 #endif // MI_ARCH_64BIT
118 
119 #ifdef MI_ARCH_64BIT
120 mi_static_assert( sizeof(Size) == 8);
121 mi_static_assert( sizeof(Difference) == 8);
122 #else // MI_ARCH_64BIT
123 mi_static_assert( sizeof(Size) == 4);
124 mi_static_assert( sizeof(Difference) == 4);
125 #endif // MI_ARCH_64BIT
126 
131 #ifdef MI_ARCH_64BIT
132 static const Size SIZE_MAX_VALUE = 18446744073709551615ULL;
133 #else // MI_ARCH_64BIT
134 static const Size SIZE_MAX_VALUE = 4294967295U;
135 #endif // MI_ARCH_64BIT
136 
141 #ifdef MI_ARCH_64BIT
142 static const Difference DIFFERENCE_MIN_VALUE = -9223372036854775807LL - 1LL;
143 #else // MI_ARCH_64BIT
144 static const Difference DIFFERENCE_MIN_VALUE = -2147483647 - 1;
145 #endif // MI_ARCH_64BIT
146 
151 #ifdef MI_ARCH_64BIT
152 static const Difference DIFFERENCE_MAX_VALUE = 9223372036854775807LL;
153 #else // MI_ARCH_64BIT
154 static const Difference DIFFERENCE_MAX_VALUE = 2147483647;
155 #endif // MI_ARCH_64BIT
156 
163 #ifdef MI_ARCH_64BIT
164 #define MI_BASE_FMT_MI_SIZE "llu"
165 #else // MI_ARCH_64BIT
166 #define MI_BASE_FMT_MI_SIZE "u"
167 #endif // MI_ARCH_64BIT
168 
175 #ifdef MI_ARCH_64BIT
176 #define MI_BASE_FMT_MI_DIFFERENCE "lld"
177 #else // MI_ARCH_64BIT
178 #define MI_BASE_FMT_MI_DIFFERENCE "d"
179 #endif // MI_ARCH_64BIT
180 
181 // primitive types related constants
182 
184 #define MI_PI 3.14159265358979323846
185 #define MI_PI_2 1.57079632679489661923
187 #define MI_PI_4 0.78539816339744830962
189 
195 {
196  NEGATIVE = -1,
197  ZERO = 0,
198  POSITIVE = 1,
199 
200  LESS = -1,
201  EQUAL = 0,
202  GREATER = 1
203 };
204 
207 {
208  return Comparison_result( -static_cast<int>( sign));
209 }
210 
216 template <typename T>
218 {
219  if (t < 0) return NEGATIVE;
220  else if (t > 0) return POSITIVE;
221  else return ZERO;
222 }
223 
229 template <typename T>
231 {
232  if (lhs < rhs) return LESS;
233  else if (rhs < lhs) return GREATER;
234  else return EQUAL;
235 }
236 
237 namespace base {
238 
239 // Define min/max within mi::base if and only if no STL usage is selected by defining the
240 // MI_BASE_NO_STL macro. Use std definitions otherwise.
241 #ifdef MI_BASE_NO_STL
242 
243 template <class T>
244 inline const T& min MI_PREVENT_MACRO_EXPAND (const T& a, const T& b)
245 { return a < b ? a : b; }
246 
247 template <class T>
248 inline const T& max MI_PREVENT_MACRO_EXPAND (const T& a, const T& b)
249 { return a > b ? a : b; }
250 
251 #else // MI_BASE_NO_STL
252 
253 using std::min;
254 using std::max;
255 
256 #endif // MI_BASE_NO_STL
257 
258 // For simple types, we add variants that pass the arguments by value. This can result in better
259 // performance on some compilers.
260 inline Sint8 min MI_PREVENT_MACRO_EXPAND (const Sint8 a, const Sint8 b)
261 { return a < b ? a : b; }
262 inline Sint16 min MI_PREVENT_MACRO_EXPAND (const Sint16 a, const Sint16 b)
263 { return a < b ? a : b; }
264 inline Sint32 min MI_PREVENT_MACRO_EXPAND (const Sint32 a, const Sint32 b)
265 { return a < b ? a : b; }
266 inline Sint64 min MI_PREVENT_MACRO_EXPAND (const Sint64 a, const Sint64 b)
267 { return a < b ? a : b; }
268 inline Uint8 min MI_PREVENT_MACRO_EXPAND (const Uint8 a, const Uint8 b)
269 { return a < b ? a : b; }
270 inline Uint16 min MI_PREVENT_MACRO_EXPAND (const Uint16 a, const Uint16 b)
271 { return a < b ? a : b; }
272 inline Uint32 min MI_PREVENT_MACRO_EXPAND (const Uint32 a, const Uint32 b)
273 { return a < b ? a : b; }
274 inline Uint64 min MI_PREVENT_MACRO_EXPAND (const Uint64 a, const Uint64 b)
275 { return a < b ? a : b; }
276 inline Float32 min MI_PREVENT_MACRO_EXPAND (const Float32 a, const Float32 b)
277 { return a < b ? a : b; }
278 inline Float64 min MI_PREVENT_MACRO_EXPAND (const Float64 a, const Float64 b)
279 { return a < b ? a : b; }
280 
281 inline Sint8 max MI_PREVENT_MACRO_EXPAND (const Sint8 a, const Sint8 b)
282 { return a > b ? a : b; }
283 inline Sint16 max MI_PREVENT_MACRO_EXPAND (const Sint16 a, const Sint16 b)
284 { return a > b ? a : b; }
285 inline Sint32 max MI_PREVENT_MACRO_EXPAND (const Sint32 a, const Sint32 b)
286 { return a > b ? a : b; }
287 inline Sint64 max MI_PREVENT_MACRO_EXPAND (const Sint64 a, const Sint64 b)
288 { return a > b ? a : b; }
289 inline Uint8 max MI_PREVENT_MACRO_EXPAND (const Uint8 a, const Uint8 b)
290 { return a > b ? a : b; }
291 inline Uint16 max MI_PREVENT_MACRO_EXPAND (const Uint16 a, const Uint16 b)
292 { return a > b ? a : b; }
293 inline Uint32 max MI_PREVENT_MACRO_EXPAND (const Uint32 a, const Uint32 b)
294 { return a > b ? a : b; }
295 inline Uint64 max MI_PREVENT_MACRO_EXPAND (const Uint64 a, const Uint64 b)
296 { return a > b ? a : b; }
297 inline Float32 max MI_PREVENT_MACRO_EXPAND (const Float32 a, const Float32 b)
298 { return a > b ? a : b; }
299 inline Float64 max MI_PREVENT_MACRO_EXPAND (const Float64 a, const Float64 b)
300 { return a > b ? a : b; }
301 
302 // Take the abs function overloads from the Standard Library header cmath.
303 
311 using std::abs;
312 
313 namespace {
314  // helper class for the \c binary_cast function defined below
315  template <class Target, class Source>
316  union Binary_cast
317  {
318  Source source;
319  Target target;
320  };
321 }
322 
328 #if (defined(_WIN32) && defined(_HAS_CXX20) && _HAS_CXX20) || (defined(__GNUC__) && (__GNUC__ >= 11 ))
329 #include <bit>
330 template<class T, class S> constexpr T binary_cast(const S& src) noexcept { return std::bit_cast<T,S>(src); }
331 #else
332 template <class Target, class Source>
333 inline Target binary_cast(Source const & val)
334 {
335  mi_static_assert( sizeof(Source) == sizeof(Target));
336  Binary_cast<Target, Source> val_;
337  val_.source = val;
338  return val_.target;
339 }
340 #endif
341 
350 template <typename T>
352 {
354  static const bool is_specialized = false;
355 
359  static const bool has_infinity = false;
360 
364  static const bool has_quiet_NaN = false;
365 
370  static const bool has_signaling_NaN = false;
371 
372 
380  static T (min)() throw() { return T(); }
381 
388  static T (max)() throw() { return T(); }
389 
396  static T negative_max() throw() { return T(); }
397 
399  static T infinity() throw() { return T(); }
400 
402  static T quiet_NaN() throw() { return T(); }
403 
405  static T signaling_NaN() throw() { return T(); }
406 };
407 
418 template <typename T>
420 {};
421 
433 template <> struct numeric_traits<Sint8> : public numeric_traits_base<Sint8>
435 {
436  static const bool is_specialized = true;
437  static Sint8 (min)() throw() { return -128; }
438  static Sint8 (max)() throw() { return 127; }
439  static Sint8 negative_max() throw() { return -128; }
440 };
441 
443 template <> struct numeric_traits<Sint16> : public numeric_traits_base<Sint16>
444 {
445  static const bool is_specialized = true;
446  static Sint16 (min)() throw() { return -32768; }
447  static Sint16 (max)() throw() { return 32767; }
448  static Sint16 negative_max() throw() { return -32768; }
449 };
450 
452 template <> struct numeric_traits<Sint32> : public numeric_traits_base<Sint32>
453 {
454  static const bool is_specialized = true;
455  static Sint32 (min)() throw() { return -2147483647 - 1; }
456  static Sint32 (max)() throw() { return 2147483647; }
457  static Sint32 negative_max() throw() { return -2147483647 - 1; }
458 };
459 
461 template <> struct numeric_traits<Sint64> : public numeric_traits_base<Sint64>
462 {
463  static const bool is_specialized = true;
464  static Sint64 (min)() throw() { return -9223372036854775807LL - 1LL; }
465  static Sint64 (max)() throw() { return 9223372036854775807LL; }
466  static Sint64 negative_max() throw() { return -9223372036854775807LL - 1LL; }
467 };
468 
470 template <> struct numeric_traits<Uint8> : public numeric_traits_base<Uint8>
471 {
472  static const bool is_specialized = true;
473  static Uint8 (max)() throw() { return 255; }
474 };
475 
477 template <> struct numeric_traits<Uint16> : public numeric_traits_base<Uint16>
478 {
479  static const bool is_specialized = true;
480  static Uint16 (max)() throw() { return 65535; }
481 };
482 
484 template <> struct numeric_traits<Uint32> : public numeric_traits_base<Uint32>
485 {
486  static const bool is_specialized = true;
487  static Uint32 (max)() throw() { return 4294967295U; }
488 };
489 
491 template <> struct numeric_traits<Uint64> : public numeric_traits_base<Uint64>
492 {
493  static const bool is_specialized = true;
494  static Uint64 (max)() throw() { return 18446744073709551615ULL; }
495 };
496 
497 // Architecture dependent definition of quiet NaN
498 #ifdef MI_ARCH_BIG_ENDIAN
499 # define MI__FLOAT32_INF_REP { 0x7f80, 0 }
500 # define MI__FLOAT32_QNAN_REP { 0x7fc1, 0 }
501 # define MI__FLOAT32_SNAN_REP { 0x7f81, 0 }
502 # define MI__FLOAT64_INF_REP { 0x7ff0, 0, 0, 0 }
503 # define MI__FLOAT64_QNAN_REP { 0x7ff9, 0, 0, 0 }
504 # define MI__FLOAT64_SNAN_REP { 0x7ff1, 0, 0, 0 }
505 #endif // MI_ARCH_BIG_ENDIAN
506 #ifdef MI_ARCH_LITTLE_ENDIAN
507 # define MI__FLOAT32_INF_REP { 0, 0x7f80 }
508 # define MI__FLOAT32_QNAN_REP { 0, 0x7fc0 }
509 # define MI__FLOAT32_SNAN_REP { 0, 0x7fa0 }
510 # define MI__FLOAT64_INF_REP { 0, 0, 0, 0x7ff0 }
511 # define MI__FLOAT64_QNAN_REP { 0, 0, 0, 0x7ff8 }
512 # define MI__FLOAT64_SNAN_REP { 0, 0, 0, 0x7ff4 }
513 #endif // MI_ARCH_LITTLE_ENDIAN
514 
515 namespace {
516  // Float number type representation for bitwise inits with NaNs
517  union Float32_rep { Uint16 rep[2]; Float32 val; };
518  union Float64_rep { Uint16 rep[4]; Float64 val; };
519 }
520 
522 template <> struct numeric_traits<Float32> : public numeric_traits_base<Float32>
523 {
524  static const bool is_specialized = true;
525  static const bool has_infinity = true;
526  static const bool has_quiet_NaN = true;
527  static const bool has_signaling_NaN = true;
528  static Float32 (min)() throw() { return 1.17549435e-38F; }
529  static Float32 (max)() throw() { return 3.402823466e+38F; }
530  static Float32 negative_max() throw() { return -3.402823466e+38F; }
531  static Float32 infinity() throw() {
532  Float32_rep rep = { MI__FLOAT32_INF_REP };
533  return rep.val;
534  }
535  static Float32 quiet_NaN() throw() {
536  Float32_rep rep = { MI__FLOAT32_QNAN_REP };
537  return rep.val;
538  }
539  static Float32 signaling_NaN() throw() {
540  Float32_rep rep = { MI__FLOAT32_SNAN_REP };
541  return rep.val;
542  }
543 };
544 
546 template <> struct numeric_traits<Float64> : public numeric_traits_base<Float64>
547 {
548  static const bool is_specialized = true;
549  static const bool has_infinity = true;
550  static const bool has_quiet_NaN = true;
551  static const bool has_signaling_NaN = true;
552  static Float64 (min)() throw() { return 2.2250738585072014e-308; }
553  static Float64 (max)() throw() { return 1.7976931348623158e+308; }
554  static Float64 negative_max() throw() { return -1.7976931348623158e+308; }
555  static Float64 infinity() throw() {
556  Float64_rep rep = { MI__FLOAT64_INF_REP };
557  return rep.val;
558  }
559  static Float64 quiet_NaN() throw() {
560  Float64_rep rep = { MI__FLOAT64_QNAN_REP };
561  return rep.val;
562  }
563  static Float64 signaling_NaN() throw() {
564  Float64_rep rep = { MI__FLOAT64_SNAN_REP };
565  return rep.val;
566  }
567 };
568  // end group mi_base_number_traits_specialization
570 
571 } // namespace base
572  // end group mi_base_types
574 
575 } // namespace mi
576 
577 #endif // MI_BASE_TYPES_H