NVIDIA Iray API Home  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 1986, 2016 NVIDIA Corporation. All rights reserved.
3 //*****************************************************************************
9 //*****************************************************************************
10 
11 #ifndef MI_BASE_TYPES_H
12 #define MI_BASE_TYPES_H
13 
14 #include <mi/base/config.h>
15 #include <mi/base/assert.h>
16 #include <cstddef> // define size_t, ptrdiff_t
17 #include <cstdlib> // declare abs
18 #include <cmath> // declare abs overloads
19 
20 #ifndef MI_BASE_NO_STL
21 #include <algorithm> // define min, max
22 #endif // MI_BASE_NO_STL
23 
24 namespace mi {
25 
36 // primitive types of known bit size
37 //
38 typedef signed char Sint8;
39 typedef signed short Sint16;
40 typedef signed int Sint32;
41 typedef unsigned char Uint8;
42 typedef unsigned short Uint16;
43 typedef unsigned int Uint32;
44 
45 typedef float Float32;
46 typedef double Float64;
47 
48 #if defined(MI_COMPILER_MSC)
49 
50 typedef signed __int64 Sint64;
51 typedef unsigned __int64 Uint64;
52 
53 #elif defined(MI_COMPILER_GCC) // defined(MI_COMPILER_MSC)
54 
55 typedef long long Sint64;
56 typedef unsigned long long Uint64;
57 
58 #else // defined(MI_COMPILER_GCC)
59 
60 typedef signed long long Sint64;
61 typedef unsigned long long Uint64;
62 
63 #endif // defined(MI_COMPILER_GCC)
64 
65 
66 // make sure that the bit sizes are right:
67 mi_static_assert( sizeof( Sint8) == 1);
68 mi_static_assert( sizeof( Sint16) == 2);
69 mi_static_assert( sizeof( Sint32) == 4);
70 mi_static_assert( sizeof( Sint64) == 8);
71 mi_static_assert( sizeof( Uint8) == 1);
72 mi_static_assert( sizeof( Uint16) == 2);
73 mi_static_assert( sizeof( Uint32) == 4);
74 mi_static_assert( sizeof( Uint64) == 8);
75 mi_static_assert( sizeof(Float32) == 4);
76 mi_static_assert( sizeof(Float64) == 8);
77 
78 // primitive types related constants
79 //
80 
82 #define MI_PI 3.14159265358979323846
83 
85 #define MI_PI_2 1.57079632679489661923
86 
88 #define MI_PI_4 0.78539816339744830962
89 
90 
96 #ifdef MI_ARCH_64BIT
97 typedef Uint64 Size;
98 #else // MI_ARCH_64BIT
99 typedef Uint32 Size;
100 #endif // MI_ARCH_64BIT
101 
107 #ifdef MI_ARCH_64BIT
109 #else // MI_ARCH_64BIT
110 typedef Sint32 Difference;
111 #endif // MI_ARCH_64BIT
112 
113 #ifdef MI_ARCH_64BIT
114 mi_static_assert( sizeof(Size) == 8);
115 mi_static_assert( sizeof(Difference) == 8);
120 static const Size SIZE_MAX_VALUE = 18446744073709551615ULL;
125 static const Difference DIFFERENCE_MIN_VALUE = -9223372036854775807LL - 1LL;
130 static const Difference DIFFERENCE_MAX_VALUE = 9223372036854775807LL;
131 #else // MI_ARCH_64BIT
132 mi_static_assert( sizeof(Size) == 4);
133 mi_static_assert( sizeof(Difference) == 4);
138 static const Size SIZE_MAX_VALUE = 4294967295U;
143 static const Difference DIFFERENCE_MIN_VALUE = -2147483647 - 1;
148 static const Difference DIFFERENCE_MAX_VALUE = 2147483647;
149 #endif // MI_ARCH_64BIT
150 
151 
158 {
159  NEGATIVE = -1,
160  ZERO = 0,
161  POSITIVE = 1,
162 
163  LESS = -1,
164  EQUAL = 0,
165  GREATER = 1
166 };
167 
170  Comparison_result sign) // Comparison_result to reverse
171 {
172  return Comparison_result( -static_cast<int>(sign) );
173 }
174 
179 template <typename T>
181  T t) // the value
182 {
183  if (t < 0) return NEGATIVE;
184  else if (t > 0) return POSITIVE;
185  else return ZERO;
186 }
187 
192 template <typename T>
194  T lhs, // left hand-side of comparison
195  T rhs) // right hand-side of comparison
196 {
197  if (lhs < rhs) return LESS;
198  else if (rhs < lhs) return GREATER;
199  else return EQUAL;
200 }
201 
202 
203 namespace base {
204 
205 // Define min/max within mi::base if and only if no STL usage is
206 // selected by defining the MI_BASE_NO_STL macro. Use MISTD definitions
207 // otherwise.
208 #ifdef MI_BASE_NO_STL
209 
210 template <class T>
211 inline const T& min MI_PREVENT_MACRO_EXPAND (const T& a, const T& b)
212 { return a < b ? a : b; }
213 
214 template <class T>
215 inline const T& max MI_PREVENT_MACRO_EXPAND (const T& a, const T& b)
216 { return a > b ? a : b; }
217 
218 #else // MI_BASE_NO_STL
219 
220 using MISTD::min;
221 using MISTD::max;
222 
223 #endif // MI_BASE_NO_STL
224 
225 // For simple types, we add variants that pass the arguments by value.
226 // This can result in better performance on some compilers.
227 inline Sint8 min MI_PREVENT_MACRO_EXPAND (const Sint8 a, const Sint8 b)
228 { return a < b ? a : b; }
229 inline Sint16 min MI_PREVENT_MACRO_EXPAND (const Sint16 a, const Sint16 b)
230 { return a < b ? a : b; }
231 inline Sint32 min MI_PREVENT_MACRO_EXPAND (const Sint32 a, const Sint32 b)
232 { return a < b ? a : b; }
233 inline Sint64 min MI_PREVENT_MACRO_EXPAND (const Sint64 a, const Sint64 b)
234 { return a < b ? a : b; }
235 inline Uint8 min MI_PREVENT_MACRO_EXPAND (const Uint8 a, const Uint8 b)
236 { return a < b ? a : b; }
237 inline Uint16 min MI_PREVENT_MACRO_EXPAND (const Uint16 a, const Uint16 b)
238 { return a < b ? a : b; }
239 inline Uint32 min MI_PREVENT_MACRO_EXPAND (const Uint32 a, const Uint32 b)
240 { return a < b ? a : b; }
241 inline Uint64 min MI_PREVENT_MACRO_EXPAND (const Uint64 a, const Uint64 b)
242 { return a < b ? a : b; }
243 inline Float32 min MI_PREVENT_MACRO_EXPAND (const Float32 a, const Float32 b)
244 { return a < b ? a : b; }
245 inline Float64 min MI_PREVENT_MACRO_EXPAND (const Float64 a, const Float64 b)
246 { return a < b ? a : b; }
247 
248 inline Sint8 max MI_PREVENT_MACRO_EXPAND (const Sint8 a, const Sint8 b)
249 { return a > b ? a : b; }
250 inline Sint16 max MI_PREVENT_MACRO_EXPAND (const Sint16 a, const Sint16 b)
251 { return a > b ? a : b; }
252 inline Sint32 max MI_PREVENT_MACRO_EXPAND (const Sint32 a, const Sint32 b)
253 { return a > b ? a : b; }
254 inline Sint64 max MI_PREVENT_MACRO_EXPAND (const Sint64 a, const Sint64 b)
255 { return a > b ? a : b; }
256 inline Uint8 max MI_PREVENT_MACRO_EXPAND (const Uint8 a, const Uint8 b)
257 { return a > b ? a : b; }
258 inline Uint16 max MI_PREVENT_MACRO_EXPAND (const Uint16 a, const Uint16 b)
259 { return a > b ? a : b; }
260 inline Uint32 max MI_PREVENT_MACRO_EXPAND (const Uint32 a, const Uint32 b)
261 { return a > b ? a : b; }
262 inline Uint64 max MI_PREVENT_MACRO_EXPAND (const Uint64 a, const Uint64 b)
263 { return a > b ? a : b; }
264 inline Float32 max MI_PREVENT_MACRO_EXPAND (const Float32 a, const Float32 b)
265 { return a > b ? a : b; }
266 inline Float64 max MI_PREVENT_MACRO_EXPAND (const Float64 a, const Float64 b)
267 { return a > b ? a : b; }
268 
269 // Take the abs function overloads from the Standard Library header cmath.
270 
277 using MISTD::abs;
278 
279 namespace {
280  // helper class for the \c binary_cast function defined below
281  template <class Target, class Source>
282  union Binary_cast
283  {
284  Source source;
285  Target target;
286  };
287 }
288 
296 
297 template <class Target, class Source>
298 inline Target binary_cast(Source const & val)
299 {
300  mi_static_assert( sizeof(Source) == sizeof(Target));
301  Binary_cast<Target, Source> val_;
302  val_.source = val;
303  return val_.target;
304 }
305 
306 
315 template <typename T>
317 {
319  static const bool is_specialized = false;
320 
323  static const bool has_infinity = false;
324 
328  static const bool has_quiet_NaN = false;
329 
333  static const bool has_signaling_NaN = false;
334 
335 
340  static T (min)() throw() { return T(); }
341 
345  static T (max)() throw() { return T(); }
346 
352  static T negative_max() throw() { return T(); }
353 
355  static T infinity() throw() { return T(); }
356 
358  static T quiet_NaN() throw() { return T(); }
359 
361  static T signaling_NaN() throw() { return T(); }
362 };
363 
375 template <typename T>
377 {};
378 
391  template <> struct numeric_traits<Sint8> : public numeric_traits_base<Sint8>
393 {
394  static const bool is_specialized = true;
395  static Sint8 (min)() throw() { return -128; }
396  static Sint8 (max)() throw() { return 127; }
397  static Sint8 negative_max() throw() { return -128; }
398 };
399 
401 template <> struct numeric_traits<Sint16> : public numeric_traits_base<Sint16>
402 {
403  static const bool is_specialized = true;
404  static Sint16 (min)() throw() { return -32768; }
405  static Sint16 (max)() throw() { return 32767; }
406  static Sint16 negative_max() throw() { return -32768; }
407 };
408 
410 template <> struct numeric_traits<Sint32> : public numeric_traits_base<Sint32>
411 {
412  static const bool is_specialized = true;
413  static Sint32 (min)() throw() { return -2147483647 - 1; }
414  static Sint32 (max)() throw() { return 2147483647; }
415  static Sint32 negative_max() throw() { return -2147483647 - 1; }
416 };
417 
419 template <> struct numeric_traits<Sint64> : public numeric_traits_base<Sint64>
420 {
421  static const bool is_specialized = true;
422  static Sint64 (min)() throw() { return -9223372036854775807LL - 1LL; }
423  static Sint64 (max)() throw() { return 9223372036854775807LL; }
424  static Sint64 negative_max() throw() { return -9223372036854775807LL - 1LL; }
425 };
426 
428 template <> struct numeric_traits<Uint8> : public numeric_traits_base<Uint8>
429 {
430  static const bool is_specialized = true;
431  static Uint8 (max)() throw() { return 255; }
432 };
433 
435 template <> struct numeric_traits<Uint16> : public numeric_traits_base<Uint16>
436 {
437  static const bool is_specialized = true;
438  static Uint16 (max)() throw() { return 65535; }
439 };
440 
442 template <> struct numeric_traits<Uint32> : public numeric_traits_base<Uint32>
443 {
444  static const bool is_specialized = true;
445  static Uint32 (max)() throw() { return 4294967295U; }
446 };
447 
449 template <> struct numeric_traits<Uint64> : public numeric_traits_base<Uint64>
450 {
451  static const bool is_specialized = true;
452  static Uint64 (max)() throw() { return 18446744073709551615ULL; }
453 };
454 
455 
456 // architecture dependent definition of quiet NaN
457 #ifdef MI_ARCH_BIG_ENDIAN
458 // # define MI__FLOAT32_QUIET_NAN_REP { 0x7fc1, 0 }
459 // # define MI__FLOAT64_QUIET_NAN_REP { 0x7ff9, 0, 0, 0 }
460 // # define MI__FLOAT32_SIGNALING_NAN_REP { 0x7fc1, 0 }
461 // # define MI__FLOAT64_SIGNALING_NAN_REP { 0x7ff9, 0, 0, 0 }
462 # define MI__FLOAT32_INF_REP { 0x7f80, 0 }
463 # define MI__FLOAT32_QNAN_REP { 0x7fc1, 0 }
464 # define MI__FLOAT32_SNAN_REP { 0x7f81, 0 }
465 # define MI__FLOAT64_INF_REP { 0x7ff0, 0, 0, 0 }
466 # define MI__FLOAT64_QNAN_REP { 0x7ff9, 0, 0, 0 }
467 # define MI__FLOAT64_SNAN_REP { 0x7ff1, 0, 0, 0 }
468 #endif // MI_ARCH_BIG_ENDIAN
469 #ifdef MI_ARCH_LITTLE_ENDIAN
470 # define MI__FLOAT32_INF_REP { 0, 0x7f80 }
471 # define MI__FLOAT32_QNAN_REP { 0, 0x7fc0 }
472 # define MI__FLOAT32_SNAN_REP { 0, 0x7fa0 }
473 # define MI__FLOAT64_INF_REP { 0, 0, 0, 0x7ff0 }
474 # define MI__FLOAT64_QNAN_REP { 0, 0, 0, 0x7ff8 }
475 # define MI__FLOAT64_SNAN_REP { 0, 0, 0, 0x7ff4 }
476 #endif // MI_ARCH_LITTLE_ENDIAN
477 
478 namespace { // anonymous namespace
479  // float number type representation for bitwise inits with NaNs
480  union Float32_rep {
481  Uint16 rep[2];
482  Float32 val;
483  };
484  union Float64_rep {
485  Uint16 rep[4];
486  Float64 val;
487  };
488 }
489 
491 template <> struct numeric_traits<Float32> : public numeric_traits_base<Float32>
492 {
493  static const bool is_specialized = true;
494  static const bool has_infinity = true;
495  static const bool has_quiet_NaN = true;
496  static const bool has_signaling_NaN = true;
497  static Float32 (min)() throw() { return 1.17549435e-38F; }
498  static Float32 (max)() throw() { return 3.402823466e+38F; }
499  static Float32 negative_max() throw() { return -3.402823466e+38F; }
500  static Float32 infinity() throw() {
501  Float32_rep rep = { MI__FLOAT32_INF_REP };
502  return rep.val;
503  }
504  static Float32 quiet_NaN() throw() {
505  Float32_rep rep = { MI__FLOAT32_QNAN_REP };
506  return rep.val;
507  }
508  static Float32 signaling_NaN() throw() {
509  Float32_rep rep = { MI__FLOAT32_SNAN_REP };
510  return rep.val;
511  }
512 };
513 
515 template <> struct numeric_traits<Float64> : public numeric_traits_base<Float64>
516 {
517  static const bool is_specialized = true;
518  static const bool has_infinity = true;
519  static const bool has_quiet_NaN = true;
520  static const bool has_signaling_NaN = true;
521  static Float64 (min)() throw() { return 2.2250738585072014e-308; }
522  static Float64 (max)() throw() { return 1.7976931348623158e+308; }
523  static Float64 negative_max() throw() { return -1.7976931348623158e+308; }
524  static Float64 infinity() throw() {
525  Float64_rep rep = { MI__FLOAT64_INF_REP };
526  return rep.val;
527  }
528  static Float64 quiet_NaN() throw() {
529  Float64_rep rep = { MI__FLOAT64_QNAN_REP };
530  return rep.val;
531  }
532  static Float64 signaling_NaN() throw() {
533  Float64_rep rep = { MI__FLOAT64_SNAN_REP };
534  return rep.val;
535  }
536 };
537  // end group mi_base_number_traits_specialization
539 
540 } // namespace base
541  // end group mi_base_types
543 
544 } // namespace mi
545 
546 #endif // MI_BASE_TYPES_H