Math API nvidia_logo_transpbg.gif Up
types.h
Go to the documentation of this file.
1/***************************************************************************************************
2 * Copyright 2023 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#if defined(__has_include)
19#if (!defined(_WIN32) || (defined(_HAS_CXX20) && _HAS_CXX20) || _MSVC_LANG >= 202002L)
20#if __has_include(<bit>)
21#include <bit>
22#endif
23#endif
24#endif
25
26#ifndef MI_BASE_NO_STL
27#include <algorithm> // define min, max
28#endif // MI_BASE_NO_STL
29
30namespace mi {
31
42// primitive types of known bit size
43
44typedef signed char Sint8;
45typedef signed short Sint16;
46typedef signed int Sint32;
47typedef unsigned char Uint8;
48typedef unsigned short Uint16;
49typedef unsigned int Uint32;
50
51typedef float Float32;
52typedef double Float64;
53
54#if defined(MI_COMPILER_MSC)
55
56typedef signed __int64 Sint64;
57typedef unsigned __int64 Uint64;
58
59#elif defined(MI_COMPILER_GCC) // defined(MI_COMPILER_MSC)
60
61typedef long long Sint64;
62typedef unsigned long long Uint64;
63
64#else // defined(MI_COMPILER_GCC)
65
66typedef signed long long Sint64;
67typedef unsigned long long Uint64;
68
69#endif // defined(MI_COMPILER_GCC)
70
71mi_static_assert( sizeof( Sint8) == 1);
72mi_static_assert( sizeof( Sint16) == 2);
73mi_static_assert( sizeof( Sint32) == 4);
74mi_static_assert( sizeof( Sint64) == 8);
75mi_static_assert( sizeof( Uint8) == 1);
76mi_static_assert( sizeof( Uint16) == 2);
77mi_static_assert( sizeof( Uint32) == 4);
78mi_static_assert( sizeof( Uint64) == 8);
79mi_static_assert( sizeof(Float32) == 4);
80mi_static_assert( sizeof(Float64) == 8);
81
88#ifdef MI_ARCH_64BIT
89#define MI_BASE_FMT_MI_SINT64 "lld"
90#else // MI_ARCH_64BIT
91#define MI_BASE_FMT_MI_SINT64 "d"
92#endif // MI_ARCH_64BIT
93
100#ifdef MI_ARCH_64BIT
101#define MI_BASE_FMT_MI_UINT64 "llu"
102#else // MI_ARCH_64BIT
103#define MI_BASE_FMT_MI_UINT64 "u"
104#endif // MI_ARCH_64BIT
105
111#ifdef MI_ARCH_64BIT
112typedef Uint64 Size;
113#else // MI_ARCH_64BIT
114typedef Uint32 Size;
115#endif // MI_ARCH_64BIT
116
121#ifdef MI_ARCH_64BIT
123#else // MI_ARCH_64BIT
124typedef Sint32 Difference;
125#endif // MI_ARCH_64BIT
126
127#ifdef MI_ARCH_64BIT
128mi_static_assert( sizeof(Size) == 8);
129mi_static_assert( sizeof(Difference) == 8);
130#else // MI_ARCH_64BIT
131mi_static_assert( sizeof(Size) == 4);
132mi_static_assert( sizeof(Difference) == 4);
133#endif // MI_ARCH_64BIT
134
139#ifdef MI_ARCH_64BIT
140static const Size SIZE_MAX_VALUE = 18446744073709551615ULL;
141#else // MI_ARCH_64BIT
142static const Size SIZE_MAX_VALUE = 4294967295U;
143#endif // MI_ARCH_64BIT
144
149#ifdef MI_ARCH_64BIT
150static const Difference DIFFERENCE_MIN_VALUE = -9223372036854775807LL - 1LL;
151#else // MI_ARCH_64BIT
152static const Difference DIFFERENCE_MIN_VALUE = -2147483647 - 1;
153#endif // MI_ARCH_64BIT
154
159#ifdef MI_ARCH_64BIT
160static const Difference DIFFERENCE_MAX_VALUE = 9223372036854775807LL;
161#else // MI_ARCH_64BIT
162static const Difference DIFFERENCE_MAX_VALUE = 2147483647;
163#endif // MI_ARCH_64BIT
164
171#ifdef MI_ARCH_64BIT
172#define MI_BASE_FMT_MI_SIZE "llu"
173#else // MI_ARCH_64BIT
174#define MI_BASE_FMT_MI_SIZE "u"
175#endif // MI_ARCH_64BIT
176
183#ifdef MI_ARCH_64BIT
184#define MI_BASE_FMT_MI_DIFFERENCE "lld"
185#else // MI_ARCH_64BIT
186#define MI_BASE_FMT_MI_DIFFERENCE "d"
187#endif // MI_ARCH_64BIT
188
189// primitive types related constants
190
192#define MI_PI 3.14159265358979323846
194#define MI_PI_2 1.57079632679489661923
196#define MI_PI_4 0.78539816339744830962
197
203{
204 NEGATIVE = -1,
205 ZERO = 0,
207
208 LESS = -1,
209 EQUAL = 0,
210 GREATER = 1
212
215{
216 return Comparison_result( -static_cast<int>( sign));
217}
218
224template <typename T>
226{
227 if (t < 0) return NEGATIVE;
228 else if (t > 0) return POSITIVE;
229 else return ZERO;
230}
231
237template <typename T>
239{
240 if (lhs < rhs) return LESS;
241 else if (rhs < lhs) return GREATER;
242 else return EQUAL;
243}
244
245namespace base {
246
247// Define min/max within mi::base if and only if no STL usage is selected by defining the
248// MI_BASE_NO_STL macro. Use std definitions otherwise.
249#ifdef MI_BASE_NO_STL
250
251template <class T>
252inline const T& min MI_PREVENT_MACRO_EXPAND (const T& a, const T& b)
253{ return a < b ? a : b; }
254
255template <class T>
256inline const T& max MI_PREVENT_MACRO_EXPAND (const T& a, const T& b)
257{ return a > b ? a : b; }
258
259#else // MI_BASE_NO_STL
260
261using std::min;
262using std::max;
263
264#endif // MI_BASE_NO_STL
265
266// For simple types, we add variants that pass the arguments by value. This can result in better
267// performance on some compilers.
268inline Sint8 min MI_PREVENT_MACRO_EXPAND (const Sint8 a, const Sint8 b)
269{ return a < b ? a : b; }
270inline Sint16 min MI_PREVENT_MACRO_EXPAND (const Sint16 a, const Sint16 b)
271{ return a < b ? a : b; }
272inline Sint32 min MI_PREVENT_MACRO_EXPAND (const Sint32 a, const Sint32 b)
273{ return a < b ? a : b; }
274inline Sint64 min MI_PREVENT_MACRO_EXPAND (const Sint64 a, const Sint64 b)
275{ return a < b ? a : b; }
276inline Uint8 min MI_PREVENT_MACRO_EXPAND (const Uint8 a, const Uint8 b)
277{ return a < b ? a : b; }
278inline Uint16 min MI_PREVENT_MACRO_EXPAND (const Uint16 a, const Uint16 b)
279{ return a < b ? a : b; }
280inline Uint32 min MI_PREVENT_MACRO_EXPAND (const Uint32 a, const Uint32 b)
281{ return a < b ? a : b; }
282inline Uint64 min MI_PREVENT_MACRO_EXPAND (const Uint64 a, const Uint64 b)
283{ return a < b ? a : b; }
284inline Float32 min MI_PREVENT_MACRO_EXPAND (const Float32 a, const Float32 b)
285{ return a < b ? a : b; }
286inline Float64 min MI_PREVENT_MACRO_EXPAND (const Float64 a, const Float64 b)
287{ return a < b ? a : b; }
288
289inline Sint8 max MI_PREVENT_MACRO_EXPAND (const Sint8 a, const Sint8 b)
290{ return a > b ? a : b; }
291inline Sint16 max MI_PREVENT_MACRO_EXPAND (const Sint16 a, const Sint16 b)
292{ return a > b ? a : b; }
293inline Sint32 max MI_PREVENT_MACRO_EXPAND (const Sint32 a, const Sint32 b)
294{ return a > b ? a : b; }
295inline Sint64 max MI_PREVENT_MACRO_EXPAND (const Sint64 a, const Sint64 b)
296{ return a > b ? a : b; }
297inline Uint8 max MI_PREVENT_MACRO_EXPAND (const Uint8 a, const Uint8 b)
298{ return a > b ? a : b; }
299inline Uint16 max MI_PREVENT_MACRO_EXPAND (const Uint16 a, const Uint16 b)
300{ return a > b ? a : b; }
301inline Uint32 max MI_PREVENT_MACRO_EXPAND (const Uint32 a, const Uint32 b)
302{ return a > b ? a : b; }
303inline Uint64 max MI_PREVENT_MACRO_EXPAND (const Uint64 a, const Uint64 b)
304{ return a > b ? a : b; }
305inline Float32 max MI_PREVENT_MACRO_EXPAND (const Float32 a, const Float32 b)
306{ return a > b ? a : b; }
307inline Float64 max MI_PREVENT_MACRO_EXPAND (const Float64 a, const Float64 b)
308{ return a > b ? a : b; }
309
310// Take the abs function overloads from the Standard Library header cmath.
311
319using std::abs;
320
321namespace {
322 // helper class for the \c binary_cast function defined below
323 template <class Target, class Source>
324 union Binary_cast
325 {
326 Source source;
327 Target target;
328 };
329}
330
336#ifdef __cpp_lib_bit_cast
337template<class T, class S>
338constexpr T binary_cast(const S& src) noexcept { return std::bit_cast<T,S>(src); }
339#else
340template <class Target, class Source>
341inline Target binary_cast(Source const & val)
342{
343 mi_static_assert( sizeof(Source) == sizeof(Target));
344 Binary_cast<Target, Source> val_;
345 val_.source = val;
346 return val_.target;
347}
348#endif
349
358template <typename T>
360{
362 static const bool is_specialized = false;
363
367 static const bool has_infinity = false;
368
372 static const bool has_quiet_NaN = false;
373
378 static const bool has_signaling_NaN = false;
379
380
388 static T (min)() throw() { return T(); }
389
396 static T (max)() throw() { return T(); }
397
404 static T negative_max() throw() { return T(); }
405
407 static T infinity() throw() { return T(); }
408
410 static T quiet_NaN() throw() { return T(); }
411
413 static T signaling_NaN() throw() { return T(); }
414};
415
426template <typename T>
428{};
429
442template <> struct numeric_traits<Sint8> : public numeric_traits_base<Sint8>
443{
444 static const bool is_specialized = true;
445 static Sint8 (min)() throw() { return -128; }
446 static Sint8 (max)() throw() { return 127; }
447 static Sint8 negative_max() throw() { return -128; }
448};
449
451template <> struct numeric_traits<Sint16> : public numeric_traits_base<Sint16>
452{
453 static const bool is_specialized = true;
454 static Sint16 (min)() throw() { return -32768; }
455 static Sint16 (max)() throw() { return 32767; }
456 static Sint16 negative_max() throw() { return -32768; }
457};
458
460template <> struct numeric_traits<Sint32> : public numeric_traits_base<Sint32>
461{
462 static const bool is_specialized = true;
463 static Sint32 (min)() throw() { return -2147483647 - 1; }
464 static Sint32 (max)() throw() { return 2147483647; }
465 static Sint32 negative_max() throw() { return -2147483647 - 1; }
466};
467
469template <> struct numeric_traits<Sint64> : public numeric_traits_base<Sint64>
470{
471 static const bool is_specialized = true;
472 static Sint64 (min)() throw() { return -9223372036854775807LL - 1LL; }
473 static Sint64 (max)() throw() { return 9223372036854775807LL; }
474 static Sint64 negative_max() throw() { return -9223372036854775807LL - 1LL; }
475};
476
478template <> struct numeric_traits<Uint8> : public numeric_traits_base<Uint8>
479{
480 static const bool is_specialized = true;
481 static Uint8 (max)() throw() { return 255; }
482};
483
485template <> struct numeric_traits<Uint16> : public numeric_traits_base<Uint16>
486{
487 static const bool is_specialized = true;
488 static Uint16 (max)() throw() { return 65535; }
489};
490
492template <> struct numeric_traits<Uint32> : public numeric_traits_base<Uint32>
493{
494 static const bool is_specialized = true;
495 static Uint32 (max)() throw() { return 4294967295U; }
496};
497
499template <> struct numeric_traits<Uint64> : public numeric_traits_base<Uint64>
500{
501 static const bool is_specialized = true;
502 static Uint64 (max)() throw() { return 18446744073709551615ULL; }
503};
504
505// Architecture dependent definition of quiet NaN
506#ifdef MI_ARCH_BIG_ENDIAN
507# define MI__FLOAT32_INF_REP { 0x7f80, 0 }
508# define MI__FLOAT32_QNAN_REP { 0x7fc1, 0 }
509# define MI__FLOAT32_SNAN_REP { 0x7f81, 0 }
510# define MI__FLOAT64_INF_REP { 0x7ff0, 0, 0, 0 }
511# define MI__FLOAT64_QNAN_REP { 0x7ff9, 0, 0, 0 }
512# define MI__FLOAT64_SNAN_REP { 0x7ff1, 0, 0, 0 }
513#endif // MI_ARCH_BIG_ENDIAN
514#ifdef MI_ARCH_LITTLE_ENDIAN
515# define MI__FLOAT32_INF_REP { 0, 0x7f80 }
516# define MI__FLOAT32_QNAN_REP { 0, 0x7fc0 }
517# define MI__FLOAT32_SNAN_REP { 0, 0x7fa0 }
518# define MI__FLOAT64_INF_REP { 0, 0, 0, 0x7ff0 }
519# define MI__FLOAT64_QNAN_REP { 0, 0, 0, 0x7ff8 }
520# define MI__FLOAT64_SNAN_REP { 0, 0, 0, 0x7ff4 }
521#endif // MI_ARCH_LITTLE_ENDIAN
522
523namespace {
524 // Float number type representation for bitwise inits with NaNs
525 union Float32_rep { Uint16 rep[2]; Float32 val; };
526 union Float64_rep { Uint16 rep[4]; Float64 val; };
527}
528
530template <> struct numeric_traits<Float32> : public numeric_traits_base<Float32>
531{
532 static const bool is_specialized = true;
533 static const bool has_infinity = true;
534 static const bool has_quiet_NaN = true;
535 static const bool has_signaling_NaN = true;
536 static Float32 (min)() throw() { return 1.17549435e-38F; }
537 static Float32 (max)() throw() { return 3.402823466e+38F; }
538 static Float32 negative_max() throw() { return -3.402823466e+38F; }
539 static Float32 infinity() throw() {
540 Float32_rep rep = { MI__FLOAT32_INF_REP };
541 return rep.val;
542 }
543 static Float32 quiet_NaN() throw() {
544 Float32_rep rep = { MI__FLOAT32_QNAN_REP };
545 return rep.val;
546 }
547 static Float32 signaling_NaN() throw() {
548 Float32_rep rep = { MI__FLOAT32_SNAN_REP };
549 return rep.val;
550 }
551};
552
554template <> struct numeric_traits<Float64> : public numeric_traits_base<Float64>
555{
556 static const bool is_specialized = true;
557 static const bool has_infinity = true;
558 static const bool has_quiet_NaN = true;
559 static const bool has_signaling_NaN = true;
560 static Float64 (min)() throw() { return 2.2250738585072014e-308; }
561 static Float64 (max)() throw() { return 1.7976931348623158e+308; }
562 static Float64 negative_max() throw() { return -1.7976931348623158e+308; }
563 static Float64 infinity() throw() {
564 Float64_rep rep = { MI__FLOAT64_INF_REP };
565 return rep.val;
566 }
567 static Float64 quiet_NaN() throw() {
568 Float64_rep rep = { MI__FLOAT64_QNAN_REP };
569 return rep.val;
570 }
571 static Float64 signaling_NaN() throw() {
572 Float64_rep rep = { MI__FLOAT64_SNAN_REP };
573 return rep.val;
574 }
575};
576 // end group mi_base_number_traits_specialization
578
579} // namespace base
580 // end group mi_base_types
582
583} // namespace mi
584
585#endif // MI_BASE_TYPES_H
Assertions and compile-time assertions.
Configuration of the Base API.
#define mi_static_assert(expr)
Compile time assertion that raises a compilation error if the constant expression expr evaluates to f...
Definition: assert.h:65
#define MI_PREVENT_MACRO_EXPAND
Empty macro that can be used after function names to prevent macro expansion that happen to have the ...
Definition: config.h:97
static Sint16 negative_max()
SHRT_MIN.
Definition: types.h:456
static T signaling_NaN()
Returns a signaling NaN value for T, if one exists, and T() otherwise.
Definition: types.h:413
static T quiet_NaN()
Returns a quiet NaN value for T, if one exists, and T() otherwise.
Definition: types.h:410
static Float32 negative_max()
-FLT_MAX
Definition: types.h:538
static Sint8 negative_max()
SCHAR_MIN.
Definition: types.h:447
static const bool has_signaling_NaN
Constant that is true if and only if T has a signaling NaN (not-a-number) representation.
Definition: types.h:378
static const bool has_quiet_NaN
Constant that is true if and only if T has a quiet NaN (not-a-number) representation.
Definition: types.h:372
static Float64 negative_max()
-DBL_MAX
Definition: types.h:562
static Sint32 negative_max()
INT_MIN.
Definition: types.h:465
static T infinity()
Returns an infinity value for T, if one exists, and T() otherwise.
Definition: types.h:407
static const bool has_infinity
Constant that is true if and only if T has an infinity representation.
Definition: types.h:367
static Sint64 negative_max()
LLONG_MIN.
Definition: types.h:474
static const bool is_specialized
Constant that is true if and only if this traits is specialized for T.
Definition: types.h:362
static T() max()
Returns the maximum finite value for T.
Definition: types.h:396
static T() min()
Returns the minimum finite value for T (and for floating point types the minimum positive value).
Definition: types.h:388
static T negative_max()
Returns the smallest finite negative value for T.
Definition: types.h:404
long long Sint64
64-bit signed integer.
Definition: types.h:61
unsigned long long Uint64
64-bit unsigned integer.
Definition: types.h:62
signed short Sint16
16-bit signed integer.
Definition: types.h:45
unsigned int Uint32
32-bit unsigned integer.
Definition: types.h:49
static const Difference DIFFERENCE_MIN_VALUE
The minimum value for Difference.
Definition: types.h:150
Target binary_cast(Source const &val)
Cast an immutable 'Source' value to an immutable 'Target' value.
Definition: types.h:341
unsigned char Uint8
8-bit unsigned integer.
Definition: types.h:47
static const Size SIZE_MAX_VALUE
The maximum value for Size.
Definition: types.h:140
Comparison_result three_valued_sign(T t)
Returns the three valued sign for a numerical type T.
Definition: types.h:225
Sint64 Difference
Signed integral type that is large enough to hold the difference of two pointers.
Definition: types.h:122
Uint64 Size
Unsigned integral type that is large enough to hold the size of all types.
Definition: types.h:112
Comparison_result operator-(Comparison_result sign)
Reverses the sign of a three valued enum.
Definition: types.h:214
signed char Sint8
8-bit signed integer.
Definition: types.h:44
Comparison_result
An enum for a three-valued comparison result.
Definition: types.h:203
double Float64
64-bit float.
Definition: types.h:52
float Float32
32-bit float.
Definition: types.h:51
unsigned short Uint16
16-bit unsigned integer.
Definition: types.h:48
Comparison_result three_valued_compare(T lhs, T rhs)
Returns the three valued comparison result between two values of a numerical type T.
Definition: types.h:238
static const Difference DIFFERENCE_MAX_VALUE
The maximum value for Difference.
Definition: types.h:160
signed int Sint32
32-bit signed integer.
Definition: types.h:46
@ POSITIVE
= +1. Sign of a value is positive.
Definition: types.h:206
@ GREATER
= +1. First value is greater than second value.
Definition: types.h:210
@ EQUAL
= 0. First value is equal to second value.
Definition: types.h:209
@ NEGATIVE
= -1. Sign of a value is negative.
Definition: types.h:204
@ LESS
= -1. First value is less than second value.
Definition: types.h:208
@ ZERO
= 0. Value is zero.
Definition: types.h:205
Color abs(const Color &c)
Returns a color with the elementwise absolute values of the color c.
Definition: color.h:474
Color sign(const Color &c)
Returns the elementwise sign of color c.
Definition: color.h:758
Common namespace for APIs of NVIDIA Advanced Rendering Center GmbH.
Definition: math.h:22
Base class for the helper class to deduce properties of numeric types defined in this API.
Definition: types.h:360
Helper class to deduce properties of numeric types defined in this API.
Definition: types.h:428