types.h File Reference
Description
Basic types. See Basic Types.
Code Example
types.h
/***************************************************************************************************
* Copyright 2024 NVIDIA Corporation. All rights reserved.
**************************************************************************************************/
#ifndef MI_BASE_TYPES_H
#define MI_BASE_TYPES_H
#include <mi/base/config.h>
#include <mi/base/assert.h>
#include <cstddef> // define size_t, ptrdiff_t
#include <cstdlib> // declare abs
#include <cmath> // declare abs overloads
#if defined(__has_include)
#if (!defined(_WIN32) || (defined(_HAS_CXX20) && _HAS_CXX20) || _MSVC_LANG >= 202002L)
#if __has_include(<bit>)
#include <bit>
#endif
#endif
#endif
#ifndef MI_BASE_NO_STL
#include <algorithm> // define min, max
#endif // MI_BASE_NO_STL
namespace mi {
// primitive types of known bit size
typedef signed char Sint8;
typedef signed short Sint16;
typedef signed int Sint32;
typedef unsigned char Uint8;
typedef unsigned short Uint16;
typedef unsigned int Uint32;
typedef float Float32;
typedef double Float64;
#if defined(MI_COMPILER_MSC)
typedef signed __int64 Sint64;
typedef unsigned __int64 Uint64;
#elif defined(MI_COMPILER_GCC) // defined(MI_COMPILER_MSC)
typedef long long Sint64;
typedef unsigned long long Uint64;
#else // defined(MI_COMPILER_GCC)
typedef signed long long Sint64;
typedef unsigned long long Uint64;
#endif // defined(MI_COMPILER_GCC)
mi_static_assert( sizeof( Sint8) == 1);
mi_static_assert( sizeof( Sint16) == 2);
mi_static_assert( sizeof( Sint32) == 4);
mi_static_assert( sizeof( Sint64) == 8);
mi_static_assert( sizeof( Uint8) == 1);
mi_static_assert( sizeof( Uint16) == 2);
mi_static_assert( sizeof( Uint32) == 4);
mi_static_assert( sizeof( Uint64) == 8);
mi_static_assert( sizeof(Float32) == 4);
mi_static_assert( sizeof(Float64) == 8);
#ifdef MI_ARCH_64BIT
#define MI_BASE_FMT_MI_SINT64 "lld"
#else // MI_ARCH_64BIT
#define MI_BASE_FMT_MI_SINT64 "d"
#endif // MI_ARCH_64BIT
#ifdef MI_ARCH_64BIT
#define MI_BASE_FMT_MI_UINT64 "llu"
#else // MI_ARCH_64BIT
#define MI_BASE_FMT_MI_UINT64 "u"
#endif // MI_ARCH_64BIT
#ifdef MI_ARCH_64BIT
typedef Uint64
Size;
#else // MI_ARCH_64BIT
typedef Uint32
Size;
#endif // MI_ARCH_64BIT
#ifdef MI_ARCH_64BIT
typedef Sint64
Difference;
#else // MI_ARCH_64BIT
typedef Sint32
Difference;
#endif // MI_ARCH_64BIT
#ifdef MI_ARCH_64BIT
mi_static_assert( sizeof(Size) == 8);
mi_static_assert( sizeof(Difference) == 8);
#else // MI_ARCH_64BIT
mi_static_assert( sizeof(Size) == 4);
mi_static_assert( sizeof(Difference) == 4);
#endif // MI_ARCH_64BIT
#ifdef MI_ARCH_64BIT
static const Size
SIZE_MAX_VALUE = 18446744073709551615ULL;
#else // MI_ARCH_64BIT
static const Size
SIZE_MAX_VALUE = 4294967295U;
#endif // MI_ARCH_64BIT
#ifdef MI_ARCH_64BIT
static const Difference
DIFFERENCE_MIN_VALUE = -9223372036854775807LL - 1LL;
#else // MI_ARCH_64BIT
static const Difference
DIFFERENCE_MIN_VALUE = -2147483647 - 1;
#endif // MI_ARCH_64BIT
#ifdef MI_ARCH_64BIT
static const Difference
DIFFERENCE_MAX_VALUE = 9223372036854775807LL;
#else // MI_ARCH_64BIT
static const Difference
DIFFERENCE_MAX_VALUE = 2147483647;
#endif // MI_ARCH_64BIT
#ifdef MI_ARCH_64BIT
#define MI_BASE_FMT_MI_SIZE "llu"
#else // MI_ARCH_64BIT
#define MI_BASE_FMT_MI_SIZE "u"
#endif // MI_ARCH_64BIT
#ifdef MI_ARCH_64BIT
#define MI_BASE_FMT_MI_DIFFERENCE "lld"
#else // MI_ARCH_64BIT
#define MI_BASE_FMT_MI_DIFFERENCE "d"
#endif // MI_ARCH_64BIT
// primitive types related constants
#define MI_PI 3.14159265358979323846
#define MI_PI_2 1.57079632679489661923
#define MI_PI_4 0.78539816339744830962
enum Comparison_result
{
NEGATIVE = -1,
ZERO = 0,
POSITIVE = 1,
LESS = -1,
EQUAL = 0,
GREATER = 1
};
inline Comparison_result
operator-( Comparison_result
sign)
{
return Comparison_result( -static_cast<int>( sign));
}
template <typename T>
inline Comparison_result
three_valued_sign( T t)
{
if (t < 0) return NEGATIVE;
else if (t > 0) return POSITIVE;
else return ZERO;
}
template <typename T>
inline Comparison_result
three_valued_compare( T lhs, T rhs)
{
if (lhs < rhs) return LESS;
else if (rhs < lhs) return GREATER;
else return EQUAL;
}
namespace base {
// Define min/max within mi::base if and only if no STL usage is selected by defining the
// MI_BASE_NO_STL macro. Use std definitions otherwise.
#ifdef MI_BASE_NO_STL
template <class T>
inline const T& min MI_PREVENT_MACRO_EXPAND (const T& a, const T& b)
{ return a < b ? a : b; }
template <class T>
inline const T& max MI_PREVENT_MACRO_EXPAND (const T& a, const T& b)
{ return a > b ? a : b; }
#else // MI_BASE_NO_STL
using std::min;
using std::max;
#endif // MI_BASE_NO_STL
// For simple types, we add variants that pass the arguments by value. This can result in better
// performance on some compilers.
inline Sint8 min MI_PREVENT_MACRO_EXPAND (const Sint8 a, const Sint8 b)
{ return a < b ? a : b; }
inline Sint16 min MI_PREVENT_MACRO_EXPAND (const Sint16 a, const Sint16 b)
{ return a < b ? a : b; }
inline Sint32 min MI_PREVENT_MACRO_EXPAND (const Sint32 a, const Sint32 b)
{ return a < b ? a : b; }
inline Sint64 min MI_PREVENT_MACRO_EXPAND (const Sint64 a, const Sint64 b)
{ return a < b ? a : b; }
inline Uint8 min MI_PREVENT_MACRO_EXPAND (const Uint8 a, const Uint8 b)
{ return a < b ? a : b; }
inline Uint16 min MI_PREVENT_MACRO_EXPAND (const Uint16 a, const Uint16 b)
{ return a < b ? a : b; }
inline Uint32 min MI_PREVENT_MACRO_EXPAND (const Uint32 a, const Uint32 b)
{ return a < b ? a : b; }
inline Uint64 min MI_PREVENT_MACRO_EXPAND (const Uint64 a, const Uint64 b)
{ return a < b ? a : b; }
inline Float32 min MI_PREVENT_MACRO_EXPAND (const Float32 a, const Float32 b)
{ return a < b ? a : b; }
inline Float64 min MI_PREVENT_MACRO_EXPAND (const Float64 a, const Float64 b)
{ return a < b ? a : b; }
inline Sint8 max MI_PREVENT_MACRO_EXPAND (const Sint8 a, const Sint8 b)
{ return a > b ? a : b; }
inline Sint16 max MI_PREVENT_MACRO_EXPAND (const Sint16 a, const Sint16 b)
{ return a > b ? a : b; }
inline Sint32 max MI_PREVENT_MACRO_EXPAND (const Sint32 a, const Sint32 b)
{ return a > b ? a : b; }
inline Sint64 max MI_PREVENT_MACRO_EXPAND (const Sint64 a, const Sint64 b)
{ return a > b ? a : b; }
inline Uint8 max MI_PREVENT_MACRO_EXPAND (const Uint8 a, const Uint8 b)
{ return a > b ? a : b; }
inline Uint16 max MI_PREVENT_MACRO_EXPAND (const Uint16 a, const Uint16 b)
{ return a > b ? a : b; }
inline Uint32 max MI_PREVENT_MACRO_EXPAND (const Uint32 a, const Uint32 b)
{ return a > b ? a : b; }
inline Uint64 max MI_PREVENT_MACRO_EXPAND (const Uint64 a, const Uint64 b)
{ return a > b ? a : b; }
inline Float32 max MI_PREVENT_MACRO_EXPAND (const Float32 a, const Float32 b)
{ return a > b ? a : b; }
inline Float64 max MI_PREVENT_MACRO_EXPAND (const Float64 a, const Float64 b)
{ return a > b ? a : b; }
// Take the abs function overloads from the Standard Library header cmath.
using std::abs;
namespace {
// helper class for the \c binary_cast function defined below
template <class Target, class Source>
union Binary_cast
{
Source source;
Target target;
};
}
#ifdef __cpp_lib_bit_cast
template<class T, class S>
constexpr T binary_cast(const S& src) noexcept { return std::bit_cast<T,S>(src); }
#else
template <class Target, class Source>
inline Target binary_cast(Source const & val)
{
mi_static_assert( sizeof(Source) == sizeof(Target));
Binary_cast<Target, Source> val_;
val_.source = val;
return val_.target;
}
#endif
template <typename T>
struct numeric_traits_base
{
static const bool is_specialized = false;
static const bool has_infinity = false;
static const bool has_quiet_NaN = false;
static const bool has_signaling_NaN = false;
static T (min)() throw() { return T(); }
static T (max)() throw() { return T(); }
static T negative_max() throw() { return T(); }
static T infinity() throw() { return T(); }
static T quiet_NaN() throw() { return T(); }
static T signaling_NaN() throw() { return T(); }
};
template <typename T>
struct numeric_traits : public numeric_traits_base<T>
{};
template <> struct numeric_traits<Sint8> : public numeric_traits_base<Sint8>
{
static const bool is_specialized = true;
static Sint8 (min)() throw() { return -128; }
static Sint8 (max)() throw() { return 127; }
static Sint8
negative_max() throw() { return -128; }
};
template <> struct numeric_traits<Sint16> : public numeric_traits_base<Sint16>
{
static const bool is_specialized = true;
static Sint16 (min)() throw() { return -32768; }
static Sint16 (max)() throw() { return 32767; }
static Sint16
negative_max() throw() { return -32768; }
};
template <> struct numeric_traits<Sint32> : public numeric_traits_base<Sint32>
{
static const bool is_specialized = true;
static Sint32 (min)() throw() { return -2147483647 - 1; }
static Sint32 (max)() throw() { return 2147483647; }
static Sint32
negative_max() throw() { return -2147483647 - 1; }
};
template <> struct numeric_traits<Sint64> : public numeric_traits_base<Sint64>
{
static const bool is_specialized = true;
static Sint64 (min)() throw() { return -9223372036854775807LL - 1LL; }
static Sint64 (max)() throw() { return 9223372036854775807LL; }
static Sint64
negative_max() throw() { return -9223372036854775807LL - 1LL; }
};
template <> struct numeric_traits<Uint8> : public numeric_traits_base<Uint8>
{
static const bool is_specialized = true;
static Uint8 (max)() throw() { return 255; }
};
template <> struct numeric_traits<Uint16> : public numeric_traits_base<Uint16>
{
static const bool is_specialized = true;
static Uint16 (max)() throw() { return 65535; }
};
template <> struct numeric_traits<Uint32> : public numeric_traits_base<Uint32>
{
static const bool is_specialized = true;
static Uint32 (max)() throw() { return 4294967295U; }
};
template <> struct numeric_traits<Uint64> : public numeric_traits_base<Uint64>
{
static const bool is_specialized = true;
static Uint64 (max)() throw() { return 18446744073709551615ULL; }
};
// Architecture dependent definition of quiet NaN
#ifdef MI_ARCH_BIG_ENDIAN
# define MI__FLOAT32_INF_REP { 0x7f80, 0 }
# define MI__FLOAT32_QNAN_REP { 0x7fc1, 0 }
# define MI__FLOAT32_SNAN_REP { 0x7f81, 0 }
# define MI__FLOAT64_INF_REP { 0x7ff0, 0, 0, 0 }
# define MI__FLOAT64_QNAN_REP { 0x7ff9, 0, 0, 0 }
# define MI__FLOAT64_SNAN_REP { 0x7ff1, 0, 0, 0 }
#endif // MI_ARCH_BIG_ENDIAN
#ifdef MI_ARCH_LITTLE_ENDIAN
# define MI__FLOAT32_INF_REP { 0, 0x7f80 }
# define MI__FLOAT32_QNAN_REP { 0, 0x7fc0 }
# define MI__FLOAT32_SNAN_REP { 0, 0x7fa0 }
# define MI__FLOAT64_INF_REP { 0, 0, 0, 0x7ff0 }
# define MI__FLOAT64_QNAN_REP { 0, 0, 0, 0x7ff8 }
# define MI__FLOAT64_SNAN_REP { 0, 0, 0, 0x7ff4 }
#endif // MI_ARCH_LITTLE_ENDIAN
namespace {
// Float number type representation for bitwise inits with NaNs
union Float32_rep { Uint16 rep[2]; Float32 val; };
union Float64_rep { Uint16 rep[4]; Float64 val; };
}
template <> struct numeric_traits<Float32> : public numeric_traits_base<Float32>
{
static const bool is_specialized = true;
static const bool has_infinity = true;
static const bool has_quiet_NaN = true;
static const bool has_signaling_NaN = true;
static Float32 (min)() throw() { return 1.17549435e-38F; }
static Float32 (max)() throw() { return 3.402823466e+38F; }
static Float32
negative_max() throw() { return -3.402823466e+38F; }
static Float32
infinity() throw() {
Float32_rep rep = { MI__FLOAT32_INF_REP };
return rep.val;
}
static Float32
quiet_NaN() throw() {
Float32_rep rep = { MI__FLOAT32_QNAN_REP };
return rep.val;
}
static Float32
signaling_NaN() throw() {
Float32_rep rep = { MI__FLOAT32_SNAN_REP };
return rep.val;
}
};
template <> struct numeric_traits<Float64> : public numeric_traits_base<Float64>
{
static const bool is_specialized = true;
static const bool has_infinity = true;
static const bool has_quiet_NaN = true;
static const bool has_signaling_NaN = true;
static Float64 (min)() throw() { return 2.2250738585072014e-308; }
static Float64 (max)() throw() { return 1.7976931348623158e+308; }
static Float64
negative_max() throw() { return -1.7976931348623158e+308; }
static Float64
infinity() throw() {
Float64_rep rep = { MI__FLOAT64_INF_REP };
return rep.val;
}
static Float64
quiet_NaN() throw() {
Float64_rep rep = { MI__FLOAT64_QNAN_REP };
return rep.val;
}
static Float64
signaling_NaN() throw() {
Float64_rep rep = { MI__FLOAT64_SNAN_REP };
return rep.val;
}
};
// end group mi_base_number_traits_specialization
} // namespace base
// end group mi_base_types
} // namespace mi
#endif // MI_BASE_TYPES_H
Namespaces
- namespace
- Common namespace for APIs of NVIDIA Advanced Rendering Center GmbH. More...
- namespace
- Namespace for the Base API. More...
Classes
- struct
- Numeric traits specialization for mi::Float32. More...
- struct
- Numeric traits specialization for mi::Float64. More...
- struct
- Numeric traits specialization for mi::Sint16. More...
- struct
- Numeric traits specialization for mi::Sint32. More...
- struct
- Numeric traits specialization for mi::Sint64. More...
- struct
- Numeric traits specialization for mi::Sint8. More...
- struct
- Helper class to deduce properties of numeric types defined in this API. More...
- struct
- Numeric traits specialization for mi::Uint16. More...
- struct
- Numeric traits specialization for mi::Uint32. More...
- struct
- Numeric traits specialization for mi::Uint64. More...
- struct
- Numeric traits specialization for mi::Uint8. More...
- struct
- Base class for the helper class to deduce properties of numeric types defined in this API. More...
Defines
- #define "lld"
- The printf format specifier for mi::Difference. More...
- #define "lld"
- The printf format specifier for mi::Sint64. More...
- #define "llu"
- The printf format specifier for mi::Size. More...
- #define "llu"
- The printf format specifier for mi::Uint64. More...
- #define 3.14159265358979323846
- Value of Pi. More...
- #define 1.57079632679489661923
- Value of Pi / 2. More...
- #define 0.78539816339744830962
- Value of Pi / 4. More...
Typedefs
- typedef Sint64
- Signed integral type that is large enough to hold the difference of two pointers. More...
- typedef float
- 32-bit float. More...
- typedef double
- 64-bit float. More...
- typedef signed short
- 16-bit signed integer. More...
- typedef signed int
- 32-bit signed integer. More...
- typedef long long
- 64-bit signed integer. More...
- typedef signed char
- 8-bit signed integer. More...
- typedef Uint64
- Unsigned integral type that is large enough to hold the size of all types. More...
- typedef unsigned short
- 16-bit unsigned integer. More...
- typedef unsigned int
- 32-bit unsigned integer. More...
- typedef unsigned long long
- 64-bit unsigned integer. More...
- typedef unsigned char
- 8-bit unsigned integer. More...
Enumerations
- enum {NEGATIVE = -1, ZERO = 0, POSITIVE = 1, LESS = -1, EQUAL = 0, GREATER = 1 }
- An enum for a three-valued comparison result. More...
Functions
- template< class Target, class Source>Target ( const Source& val)
- Cast an immutable 'Source' value to an immutable 'Target' value. More...
- Comparison_result ( Comparison_result sign)
- Reverses the sign of a three valued enum. More...
- template< typename T>Comparison_result ( T lhs, T rhs)
- Returns the three valued comparison result between two values of a numerical type T. More...
- template< typename T>Comparison_result ( T t)
- Returns the three valued sign for a numerical type T. More...