NVIDIA Iray API
 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, 2014 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 
177 template <typename T>
179  T t) // the value
180 {
181  if (t < 0) return NEGATIVE;
182  else if (t > 0) return POSITIVE;
183  else return ZERO;
184 }
185 
188 template <typename T>
190  T lhs, // left hand-side of comparison
191  T rhs) // right hand-side of comparison
192 {
193  if (lhs < rhs) return LESS;
194  else if (rhs < lhs) return GREATER;
195  else return EQUAL;
196 }
197 
198 
199 namespace base {
200 
201 // Define min/max within mi::base if and only if no STL usage is
202 // selected by defining the MI_BASE_NO_STL macro. Use MISTD definitions
203 // otherwise.
204 #ifdef MI_BASE_NO_STL
205 
206 template <class T>
207 inline const T& min MI_PREVENT_MACRO_EXPAND (const T& a, const T& b)
208 { return a < b ? a : b; }
209 
210 template <class T>
211 inline const T& max MI_PREVENT_MACRO_EXPAND (const T& a, const T& b)
212 { return a > b ? a : b; }
213 
214 #else // MI_BASE_NO_STL
215 
216 using MISTD::min;
217 using MISTD::max;
218 
219 #endif // MI_BASE_NO_STL
220 
221 // For simple types, we add variants that pass the arguments by value.
222 // This can result in better performance on some compilers.
223 inline Sint8 min MI_PREVENT_MACRO_EXPAND (const Sint8 a, const Sint8 b)
224 { return a < b ? a : b; }
225 inline Sint16 min MI_PREVENT_MACRO_EXPAND (const Sint16 a, const Sint16 b)
226 { return a < b ? a : b; }
227 inline Sint32 min MI_PREVENT_MACRO_EXPAND (const Sint32 a, const Sint32 b)
228 { return a < b ? a : b; }
229 inline Sint64 min MI_PREVENT_MACRO_EXPAND (const Sint64 a, const Sint64 b)
230 { return a < b ? a : b; }
231 inline Uint8 min MI_PREVENT_MACRO_EXPAND (const Uint8 a, const Uint8 b)
232 { return a < b ? a : b; }
233 inline Uint16 min MI_PREVENT_MACRO_EXPAND (const Uint16 a, const Uint16 b)
234 { return a < b ? a : b; }
235 inline Uint32 min MI_PREVENT_MACRO_EXPAND (const Uint32 a, const Uint32 b)
236 { return a < b ? a : b; }
237 inline Uint64 min MI_PREVENT_MACRO_EXPAND (const Uint64 a, const Uint64 b)
238 { return a < b ? a : b; }
239 inline Float32 min MI_PREVENT_MACRO_EXPAND (const Float32 a, const Float32 b)
240 { return a < b ? a : b; }
241 inline Float64 min MI_PREVENT_MACRO_EXPAND (const Float64 a, const Float64 b)
242 { return a < b ? a : b; }
243 
244 inline Sint8 max MI_PREVENT_MACRO_EXPAND (const Sint8 a, const Sint8 b)
245 { return a > b ? a : b; }
246 inline Sint16 max MI_PREVENT_MACRO_EXPAND (const Sint16 a, const Sint16 b)
247 { return a > b ? a : b; }
248 inline Sint32 max MI_PREVENT_MACRO_EXPAND (const Sint32 a, const Sint32 b)
249 { return a > b ? a : b; }
250 inline Sint64 max MI_PREVENT_MACRO_EXPAND (const Sint64 a, const Sint64 b)
251 { return a > b ? a : b; }
252 inline Uint8 max MI_PREVENT_MACRO_EXPAND (const Uint8 a, const Uint8 b)
253 { return a > b ? a : b; }
254 inline Uint16 max MI_PREVENT_MACRO_EXPAND (const Uint16 a, const Uint16 b)
255 { return a > b ? a : b; }
256 inline Uint32 max MI_PREVENT_MACRO_EXPAND (const Uint32 a, const Uint32 b)
257 { return a > b ? a : b; }
258 inline Uint64 max MI_PREVENT_MACRO_EXPAND (const Uint64 a, const Uint64 b)
259 { return a > b ? a : b; }
260 inline Float32 max MI_PREVENT_MACRO_EXPAND (const Float32 a, const Float32 b)
261 { return a > b ? a : b; }
262 inline Float64 max MI_PREVENT_MACRO_EXPAND (const Float64 a, const Float64 b)
263 { return a > b ? a : b; }
264 
265 // Take the abs function overloads from the Standard Library header cmath.
266 
273 using MISTD::abs;
274 
275 namespace {
276  // helper class for the \c binary_cast function defined below
277  template <class Target, class Source>
278  union Binary_cast
279  {
280  Source source;
281  Target target;
282  };
283 }
284 
292 
293 template <class Target, class Source>
294 inline Target binary_cast(Source const & val)
295 {
296  mi_static_assert( sizeof(Source) == sizeof(Target));
297  Binary_cast<Target, Source> val_;
298  val_.source = val;
299  return val_.target;
300 }
301 
302 
311 template <typename T>
313 {
315  static const bool is_specialized = false;
316 
319  static const bool has_infinity = false;
320 
324  static const bool has_quiet_NaN = false;
325 
329  static const bool has_signaling_NaN = false;
330 
331 
336  static T (min)() throw() { return T(); }
337 
341  static T (max)() throw() { return T(); }
342 
348  static T negative_max() throw() { return T(); }
349 
351  static T infinity() throw() { return T(); }
352 
354  static T quiet_NaN() throw() { return T(); }
355 
357  static T signaling_NaN() throw() { return T(); }
358 };
359 
371 template <typename T>
373 {};
374 
387  template <> struct numeric_traits<Sint8> : public numeric_traits_base<Sint8>
389 {
390  static const bool is_specialized = true;
391  static Sint8 (min)() throw() { return -128; }
392  static Sint8 (max)() throw() { return 127; }
393  static Sint8 negative_max() throw() { return -128; }
394 };
395 
397 template <> struct numeric_traits<Sint16> : public numeric_traits_base<Sint16>
398 {
399  static const bool is_specialized = true;
400  static Sint16 (min)() throw() { return -32768; }
401  static Sint16 (max)() throw() { return 32767; }
402  static Sint16 negative_max() throw() { return -32768; }
403 };
404 
406 template <> struct numeric_traits<Sint32> : public numeric_traits_base<Sint32>
407 {
408  static const bool is_specialized = true;
409  static Sint32 (min)() throw() { return -2147483647 - 1; }
410  static Sint32 (max)() throw() { return 2147483647; }
411  static Sint32 negative_max() throw() { return -2147483647 - 1; }
412 };
413 
415 template <> struct numeric_traits<Sint64> : public numeric_traits_base<Sint64>
416 {
417  static const bool is_specialized = true;
418  static Sint64 (min)() throw() { return -9223372036854775807LL - 1LL; }
419  static Sint64 (max)() throw() { return 9223372036854775807LL; }
420  static Sint64 negative_max() throw() { return -9223372036854775807LL - 1LL; }
421 };
422 
424 template <> struct numeric_traits<Uint8> : public numeric_traits_base<Uint8>
425 {
426  static const bool is_specialized = true;
427  static Uint8 (max)() throw() { return 255; }
428 };
429 
431 template <> struct numeric_traits<Uint16> : public numeric_traits_base<Uint16>
432 {
433  static const bool is_specialized = true;
434  static Uint16 (max)() throw() { return 65535; }
435 };
436 
438 template <> struct numeric_traits<Uint32> : public numeric_traits_base<Uint32>
439 {
440  static const bool is_specialized = true;
441  static Uint32 (max)() throw() { return 4294967295U; }
442 };
443 
445 template <> struct numeric_traits<Uint64> : public numeric_traits_base<Uint64>
446 {
447  static const bool is_specialized = true;
448  static Uint64 (max)() throw() { return 18446744073709551615ULL; }
449 };
450 
451 
452 // architecture dependent definition of quiet NaN
453 #ifdef MI_ARCH_BIG_ENDIAN
454 // # define MI__FLOAT32_QUIET_NAN_REP { 0x7fc1, 0 }
455 // # define MI__FLOAT64_QUIET_NAN_REP { 0x7ff9, 0, 0, 0 }
456 // # define MI__FLOAT32_SIGNALING_NAN_REP { 0x7fc1, 0 }
457 // # define MI__FLOAT64_SIGNALING_NAN_REP { 0x7ff9, 0, 0, 0 }
458 # define MI__FLOAT32_INF_REP { 0x7f80, 0 }
459 # define MI__FLOAT32_QNAN_REP { 0x7fc1, 0 }
460 # define MI__FLOAT32_SNAN_REP { 0x7f81, 0 }
461 # define MI__FLOAT64_INF_REP { 0x7ff0, 0, 0, 0 }
462 # define MI__FLOAT64_QNAN_REP { 0x7ff9, 0, 0, 0 }
463 # define MI__FLOAT64_SNAN_REP { 0x7ff1, 0, 0, 0 }
464 #endif // MI_ARCH_BIG_ENDIAN
465 #ifdef MI_ARCH_LITTLE_ENDIAN
466 # define MI__FLOAT32_INF_REP { 0, 0x7f80 }
467 # define MI__FLOAT32_QNAN_REP { 0, 0x7fc0 }
468 # define MI__FLOAT32_SNAN_REP { 0, 0x7fa0 }
469 # define MI__FLOAT64_INF_REP { 0, 0, 0, 0x7ff0 }
470 # define MI__FLOAT64_QNAN_REP { 0, 0, 0, 0x7ff8 }
471 # define MI__FLOAT64_SNAN_REP { 0, 0, 0, 0x7ff4 }
472 #endif // MI_ARCH_LITTLE_ENDIAN
473 
474 namespace { // anonymous namespace
475  // float number type representation for bitwise inits with NaNs
476  union Float32_rep {
477  Uint16 rep[2];
478  Float32 val;
479  };
480  union Float64_rep {
481  Uint16 rep[4];
482  Float64 val;
483  };
484 }
485 
487 template <> struct numeric_traits<Float32> : public numeric_traits_base<Float32>
488 {
489  static const bool is_specialized = true;
490  static const bool has_infinity = true;
491  static const bool has_quiet_NaN = true;
492  static const bool has_signaling_NaN = true;
493  static Float32 (min)() throw() { return 1.17549435e-38F; }
494  static Float32 (max)() throw() { return 3.402823466e+38F; }
495  static Float32 negative_max() throw() { return -3.402823466e+38F; }
496  static Float32 infinity() throw() {
497  Float32_rep rep = { MI__FLOAT32_INF_REP };
498  return rep.val;
499  }
500  static Float32 quiet_NaN() throw() {
501  Float32_rep rep = { MI__FLOAT32_QNAN_REP };
502  return rep.val;
503  }
504  static Float32 signaling_NaN() throw() {
505  Float32_rep rep = { MI__FLOAT32_SNAN_REP };
506  return rep.val;
507  }
508 };
509 
511 template <> struct numeric_traits<Float64> : public numeric_traits_base<Float64>
512 {
513  static const bool is_specialized = true;
514  static const bool has_infinity = true;
515  static const bool has_quiet_NaN = true;
516  static const bool has_signaling_NaN = true;
517  static Float64 (min)() throw() { return 2.2250738585072014e-308; }
518  static Float64 (max)() throw() { return 1.7976931348623158e+308; }
519  static Float64 negative_max() throw() { return -1.7976931348623158e+308; }
520  static Float64 infinity() throw() {
521  Float64_rep rep = { MI__FLOAT64_INF_REP };
522  return rep.val;
523  }
524  static Float64 quiet_NaN() throw() {
525  Float64_rep rep = { MI__FLOAT64_QNAN_REP };
526  return rep.val;
527  }
528  static Float64 signaling_NaN() throw() {
529  Float64_rep rep = { MI__FLOAT64_SNAN_REP };
530  return rep.val;
531  }
532 };
533  // end group mi_base_number_traits_specialization
535  // end group mi_base_types
537 
538 } // namespace base
539 } // namespace mi
540 
541 #endif // MI_BASE_TYPES_H