Material Definition Language 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 2020 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 template <class Target, class Source>
329 inline Target binary_cast(Source const & val)
330 {
331  mi_static_assert( sizeof(Source) == sizeof(Target));
332  Binary_cast<Target, Source> val_;
333  val_.source = val;
334  return val_.target;
335 }
336 
345 template <typename T>
347 {
349  static const bool is_specialized = false;
350 
354  static const bool has_infinity = false;
355 
359  static const bool has_quiet_NaN = false;
360 
365  static const bool has_signaling_NaN = false;
366 
367 
375  static T (min)() throw() { return T(); }
376 
383  static T (max)() throw() { return T(); }
384 
391  static T negative_max() throw() { return T(); }
392 
394  static T infinity() throw() { return T(); }
395 
397  static T quiet_NaN() throw() { return T(); }
398 
400  static T signaling_NaN() throw() { return T(); }
401 };
402 
413 template <typename T>
415 {};
416 
428 template <> struct numeric_traits<Sint8> : public numeric_traits_base<Sint8>
430 {
431  static const bool is_specialized = true;
432  static Sint8 (min)() throw() { return -128; }
433  static Sint8 (max)() throw() { return 127; }
434  static Sint8 negative_max() throw() { return -128; }
435 };
436 
438 template <> struct numeric_traits<Sint16> : public numeric_traits_base<Sint16>
439 {
440  static const bool is_specialized = true;
441  static Sint16 (min)() throw() { return -32768; }
442  static Sint16 (max)() throw() { return 32767; }
443  static Sint16 negative_max() throw() { return -32768; }
444 };
445 
447 template <> struct numeric_traits<Sint32> : public numeric_traits_base<Sint32>
448 {
449  static const bool is_specialized = true;
450  static Sint32 (min)() throw() { return -2147483647 - 1; }
451  static Sint32 (max)() throw() { return 2147483647; }
452  static Sint32 negative_max() throw() { return -2147483647 - 1; }
453 };
454 
456 template <> struct numeric_traits<Sint64> : public numeric_traits_base<Sint64>
457 {
458  static const bool is_specialized = true;
459  static Sint64 (min)() throw() { return -9223372036854775807LL - 1LL; }
460  static Sint64 (max)() throw() { return 9223372036854775807LL; }
461  static Sint64 negative_max() throw() { return -9223372036854775807LL - 1LL; }
462 };
463 
465 template <> struct numeric_traits<Uint8> : public numeric_traits_base<Uint8>
466 {
467  static const bool is_specialized = true;
468  static Uint8 (max)() throw() { return 255; }
469 };
470 
472 template <> struct numeric_traits<Uint16> : public numeric_traits_base<Uint16>
473 {
474  static const bool is_specialized = true;
475  static Uint16 (max)() throw() { return 65535; }
476 };
477 
479 template <> struct numeric_traits<Uint32> : public numeric_traits_base<Uint32>
480 {
481  static const bool is_specialized = true;
482  static Uint32 (max)() throw() { return 4294967295U; }
483 };
484 
486 template <> struct numeric_traits<Uint64> : public numeric_traits_base<Uint64>
487 {
488  static const bool is_specialized = true;
489  static Uint64 (max)() throw() { return 18446744073709551615ULL; }
490 };
491 
492 // Architecture dependent definition of quiet NaN
493 #ifdef MI_ARCH_BIG_ENDIAN
494 # define MI__FLOAT32_INF_REP { 0x7f80, 0 }
495 # define MI__FLOAT32_QNAN_REP { 0x7fc1, 0 }
496 # define MI__FLOAT32_SNAN_REP { 0x7f81, 0 }
497 # define MI__FLOAT64_INF_REP { 0x7ff0, 0, 0, 0 }
498 # define MI__FLOAT64_QNAN_REP { 0x7ff9, 0, 0, 0 }
499 # define MI__FLOAT64_SNAN_REP { 0x7ff1, 0, 0, 0 }
500 #endif // MI_ARCH_BIG_ENDIAN
501 #ifdef MI_ARCH_LITTLE_ENDIAN
502 # define MI__FLOAT32_INF_REP { 0, 0x7f80 }
503 # define MI__FLOAT32_QNAN_REP { 0, 0x7fc0 }
504 # define MI__FLOAT32_SNAN_REP { 0, 0x7fa0 }
505 # define MI__FLOAT64_INF_REP { 0, 0, 0, 0x7ff0 }
506 # define MI__FLOAT64_QNAN_REP { 0, 0, 0, 0x7ff8 }
507 # define MI__FLOAT64_SNAN_REP { 0, 0, 0, 0x7ff4 }
508 #endif // MI_ARCH_LITTLE_ENDIAN
509 
510 namespace {
511  // Float number type representation for bitwise inits with NaNs
512  union Float32_rep { Uint16 rep[2]; Float32 val; };
513  union Float64_rep { Uint16 rep[4]; Float64 val; };
514 }
515 
517 template <> struct numeric_traits<Float32> : public numeric_traits_base<Float32>
518 {
519  static const bool is_specialized = true;
520  static const bool has_infinity = true;
521  static const bool has_quiet_NaN = true;
522  static const bool has_signaling_NaN = true;
523  static Float32 (min)() throw() { return 1.17549435e-38F; }
524  static Float32 (max)() throw() { return 3.402823466e+38F; }
525  static Float32 negative_max() throw() { return -3.402823466e+38F; }
526  static Float32 infinity() throw() {
527  Float32_rep rep = { MI__FLOAT32_INF_REP };
528  return rep.val;
529  }
530  static Float32 quiet_NaN() throw() {
531  Float32_rep rep = { MI__FLOAT32_QNAN_REP };
532  return rep.val;
533  }
534  static Float32 signaling_NaN() throw() {
535  Float32_rep rep = { MI__FLOAT32_SNAN_REP };
536  return rep.val;
537  }
538 };
539 
541 template <> struct numeric_traits<Float64> : public numeric_traits_base<Float64>
542 {
543  static const bool is_specialized = true;
544  static const bool has_infinity = true;
545  static const bool has_quiet_NaN = true;
546  static const bool has_signaling_NaN = true;
547  static Float64 (min)() throw() { return 2.2250738585072014e-308; }
548  static Float64 (max)() throw() { return 1.7976931348623158e+308; }
549  static Float64 negative_max() throw() { return -1.7976931348623158e+308; }
550  static Float64 infinity() throw() {
551  Float64_rep rep = { MI__FLOAT64_INF_REP };
552  return rep.val;
553  }
554  static Float64 quiet_NaN() throw() {
555  Float64_rep rep = { MI__FLOAT64_QNAN_REP };
556  return rep.val;
557  }
558  static Float64 signaling_NaN() throw() {
559  Float64_rep rep = { MI__FLOAT64_SNAN_REP };
560  return rep.val;
561  }
562 };
563  // end group mi_base_number_traits_specialization
565 
566 } // namespace base
567  // end group mi_base_types
569 
570 } // namespace mi
571 
572 #endif // MI_BASE_TYPES_H