AuROXTL/Include/auROXTL/auNumericLimits.hpp

131 lines
4.5 KiB
C++
Raw Normal View History

2022-04-01 04:06:53 +00:00
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auNumericLimits.hpp
Date: 2022-2-19
Author: Reece
***/
#pragma once
template <class T, T Min, T Max, T Epsilon, bool IsSigned = false, bool IsInteger = false>
struct _AuNonStdLimits
{
using Type = T;
static const bool is_signed = IsSigned;
static const bool is_integer = IsInteger;
static constexpr Type min()
{
return Min;
}
static constexpr Type max()
{
return Max;
}
static constexpr Type epsilon()
{
return Epsilon;
}
};
template <class T>
struct AuNumericLimits;
#define _AU_LIMITS_ADD(bits) \
\
template <> \
struct AuNumericLimits<AuUInt ## bits> : _AuNonStdLimits<AuUInt ## bits, 0, static_cast<AuUInt ## bits>(AuInt ## bits(-1)), 1, false, true> \
{ \
\
}; \
\
template <> \
struct AuNumericLimits<AuInt ## bits> : _AuNonStdLimits<AuInt ## bits, AuInt ## bits(AuUInt ## bits(0) - AuInt ## bits(AuConstPow<AuUInt ## bits>(2, bits - 1) - 1)) - 1, AuInt ## bits(AuConstPow<AuUInt ## bits>(2, bits - 1) - 1), 1, true, true> \
{ \
\
};
_AU_LIMITS_ADD(8)
_AU_LIMITS_ADD(16)
_AU_LIMITS_ADD(32)
_AU_LIMITS_ADD(64)
#undef _AU_LIMITS_ADD
#if defined(AURORA_COMPILER_MSVC)
template <>
struct AuNumericLimits<long> : AuNumericLimits<int>
{};
template <>
struct AuNumericLimits<unsigned long> : AuNumericLimits<unsigned int>
{};
#endif
// TODO: clang x86 and x64 will need different hacks for [unsigned] long long
template <>
struct AuNumericLimits<bool> : _AuNonStdLimits<bool, false, true, true>
{};
template <>
struct AuNumericLimits<char16_t> : AuNumericLimits<AuUInt16>
{};
template <>
struct AuNumericLimits<char32_t> : AuNumericLimits<AuUInt32>
{};
template <class T>
struct _AuNonStdLimitsFP
{
using Type = T;
static const bool is_signed = true;
static const bool is_integer = false;
};
template <>
struct AuNumericLimits<float> : _AuNonStdLimitsFP<float>
{
static double max()
{
return 340282346638528859811704183484516925440.0000000000000000;
}
static double min()
{
return -340282346638528859811704183484516925440.0000000000000000;
}
static constexpr double epsilon()
{
return 0.000000000000000111;
}
};
template <>
struct AuNumericLimits<double> : _AuNonStdLimitsFP<double>
{
static double max()
{
return 1.7976931348623157e+308;
}
static double min()
{
return -2.2250738585072014e-308;
}
static constexpr double epsilon()
{
return 0.000000000000000111;
}
};