AuROXTL/Include/auROXTL/auNumericLimits.hpp
2023-06-01 13:04:49 +01:00

149 lines
5.0 KiB
C++

/***
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;
}
static constexpr Type lowest()
{
return min();
}
};
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
// Update: reece: i dont care enough to fully support non--Au-types for now.
// will fix
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 constexpr float max()
{
return 340282346638528859811704183484516925440.0000000000000000f;
}
// Techincally not compatible with C++11!
// This is techincally ::lowest() in real c++
static constexpr float min()
{
return -340282346638528859811704183484516925440.0000000000000000f;
}
static constexpr float epsilon()
{
return 1.192092896e-07F;
}
static constexpr float lowest()
{
return -(max());
}
};
template <>
struct AuNumericLimits<double> : _AuNonStdLimitsFP<double>
{
static constexpr double max()
{
return 1.7976931348623158e+308;
}
static constexpr double min()
{
return -2.2250738585072014e-308;
}
static constexpr double epsilon()
{
return 2.2204460492503131e-016;
}
static constexpr double lowest()
{
return -(max());
}
};