cog/Frameworks/OpenMPT.old/OpenMPT/common/mptBaseTypes.h

291 lines
6.7 KiB
C++

/*
* mptBaseTypes.h
* --------------
* Purpose: Basic data type definitions.
* Notes : (currently none)
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#pragma once
#include "BuildSettings.h"
#include "mptBaseMacros.h"
#include <array>
#include <limits>
#if MPT_CXX_AT_LEAST(20)
#include <source_location>
#endif // C++20
#include <cstddef>
#include <cstdint>
#include <stdint.h>
OPENMPT_NAMESPACE_BEGIN
namespace mpt
{
template <bool cond, typename Ta, typename Tb>
struct select_type
{
};
template <typename Ta, typename Tb>
struct select_type<true, Ta, Tb>
{
using type = Ta;
};
template <typename Ta, typename Tb>
struct select_type<false, Ta, Tb>
{
using type = Tb;
};
} // namespace mpt
using int8 = std::int8_t;
using int16 = std::int16_t;
using int32 = std::int32_t;
using int64 = std::int64_t;
using uint8 = std::uint8_t;
using uint16 = std::uint16_t;
using uint32 = std::uint32_t;
using uint64 = std::uint64_t;
constexpr int8 int8_min = std::numeric_limits<int8>::min();
constexpr int16 int16_min = std::numeric_limits<int16>::min();
constexpr int32 int32_min = std::numeric_limits<int32>::min();
constexpr int64 int64_min = std::numeric_limits<int64>::min();
constexpr int8 int8_max = std::numeric_limits<int8>::max();
constexpr int16 int16_max = std::numeric_limits<int16>::max();
constexpr int32 int32_max = std::numeric_limits<int32>::max();
constexpr int64 int64_max = std::numeric_limits<int64>::max();
constexpr uint8 uint8_max = std::numeric_limits<uint8>::max();
constexpr uint16 uint16_max = std::numeric_limits<uint16>::max();
constexpr uint32 uint32_max = std::numeric_limits<uint32>::max();
constexpr uint64 uint64_max = std::numeric_limits<uint64>::max();
// fp half
// n/a
// fp single
using single = float;
constexpr single operator"" _fs(long double lit)
{
return static_cast<single>(lit);
}
// fp double
constexpr double operator"" _fd(long double lit)
{
return static_cast<double>(lit);
}
// fp extended
constexpr long double operator"" _fe(long double lit)
{
return static_cast<long double>(lit);
}
// fp quad
// n/a
using float32 = mpt::select_type<sizeof(float) == 4,
float
,
mpt::select_type<sizeof(double) == 4,
double
,
mpt::select_type<sizeof(long double) == 4,
long double
,
float
>::type
>::type
>::type;
constexpr float32 operator"" _f32(long double lit)
{
return static_cast<float32>(lit);
}
using float64 = mpt::select_type<sizeof(float) == 8,
float
,
mpt::select_type<sizeof(double) == 8,
double
,
mpt::select_type<sizeof(long double) == 8,
long double
,
double
>::type
>::type
>::type;
constexpr float64 operator"" _f64(long double lit)
{
return static_cast<float64>(lit);
}
namespace mpt
{
template <typename T>
struct float_traits
{
static constexpr bool is_float = !std::numeric_limits<T>::is_integer;
static constexpr bool is_hard = is_float && !MPT_COMPILER_QUIRK_FLOAT_EMULATED;
static constexpr bool is_soft = is_float && MPT_COMPILER_QUIRK_FLOAT_EMULATED;
static constexpr bool is_float32 = is_float && (sizeof(T) == 4);
static constexpr bool is_float64 = is_float && (sizeof(T) == 8);
static constexpr bool is_native_endian = is_float && !MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN;
static constexpr bool is_ieee754_binary = is_float && std::numeric_limits<T>::is_iec559 && !MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754;
static constexpr bool is_ieee754_binary32 = is_float && is_ieee754_binary && is_float32;
static constexpr bool is_ieee754_binary64 = is_float && is_ieee754_binary && is_float64;
static constexpr bool is_ieee754_binary32ne = is_float && is_ieee754_binary && is_float32 && is_native_endian;
static constexpr bool is_ieee754_binary64ne = is_float && is_ieee754_binary && is_float64 && is_native_endian;
};
} // namespace mpt
#if MPT_COMPILER_QUIRK_FLOAT_PREFER32
using nativefloat = float32;
#elif MPT_COMPILER_QUIRK_FLOAT_PREFER64
using nativefloat = float64;
#else
// prefer smaller floats, but try to use IEEE754 floats
using nativefloat = mpt::select_type<std::numeric_limits<float>::is_iec559,
float
,
mpt::select_type<std::numeric_limits<double>::is_iec559,
double
,
mpt::select_type<std::numeric_limits<long double>::is_iec559,
long double
,
float
>::type
>::type
>::type;
#endif
constexpr nativefloat operator"" _nf(long double lit)
{
return static_cast<nativefloat>(lit);
}
static_assert(sizeof(std::uintptr_t) == sizeof(void*));
static_assert(std::numeric_limits<unsigned char>::digits == 8);
static_assert(sizeof(char) == 1);
static_assert(sizeof(std::byte) == 1);
static_assert(alignof(std::byte) == 1);
namespace mpt {
inline constexpr int arch_bits = sizeof(void*) * 8;
inline constexpr std::size_t pointer_size = sizeof(void*);
} // namespace mpt
static_assert(mpt::arch_bits == static_cast<int>(mpt::pointer_size) * 8);
namespace mpt {
template <typename T>
struct limits
{
static constexpr typename std::remove_cv<T>::type min() noexcept { return std::numeric_limits<typename std::remove_cv<T>::type>::min(); }
static constexpr typename std::remove_cv<T>::type max() noexcept { return std::numeric_limits<typename std::remove_cv<T>::type>::max(); }
};
} // namespace mpt
namespace mpt
{
#if MPT_CXX_AT_LEAST(20)
using std::source_location;
#define MPT_SOURCE_LOCATION_CURRENT() std::source_location::current()
#else // !C++20
// compatible with std::experimental::source_location from Library Fundamentals TS v2.
struct source_location
{
private:
const char* m_file_name;
const char* m_function_name;
uint32 m_line;
uint32 m_column;
public:
constexpr source_location() noexcept
: m_file_name("")
, m_function_name("")
, m_line(0)
, m_column(0)
{
}
constexpr source_location(const char* file, const char* function, uint32 line, uint32 column) noexcept
: m_file_name(file)
, m_function_name(function)
, m_line(line)
, m_column(column)
{
}
source_location(const source_location&) = default;
source_location(source_location&&) = default;
//static constexpr current() noexcept; // use MPT_SOURCE_LOCATION_CURRENT()
static constexpr source_location current(const char* file, const char* function, uint32 line, uint32 column) noexcept
{
return source_location(file, function, line, column);
}
constexpr uint32 line() const noexcept
{
return m_line;
}
constexpr uint32 column() const noexcept
{
return m_column;
}
constexpr const char* file_name() const noexcept
{
return m_file_name;
}
constexpr const char* function_name() const noexcept
{
return m_function_name;
}
};
#define MPT_SOURCE_LOCATION_CURRENT() mpt::source_location::current( __FILE__ , __func__ , __LINE__ , 0 )
#endif // C++20
} // namespace mpt
OPENMPT_NAMESPACE_END