Compare commits

...

4 Commits

5 changed files with 183 additions and 6 deletions

View File

@ -363,8 +363,31 @@ using intmax = int128;
using intmax = int64;
#endif
static_assert(sizeof(int8) == 1, "int8 must be 1 byte");
static_assert(sizeof(int16) == 2, "int16 must be 2 bytes");
static_assert(sizeof(int32) == 4, "int32 must be 4 bytes");
static_assert(sizeof(int64) == 8, "int64 must be 8 bytes");
static_assert(sizeof(int8_least) >= 1, "int8_least must be at least 1 byte");
static_assert(sizeof(int16_least) >= 2, "int16_least must be at least 2 bytes");
static_assert(sizeof(int32_least) >= 4, "int32_least must be at least 4 bytes");
static_assert(sizeof(int64_least) >= 8, "int64_least must be at least 8 bytes");
static_assert(sizeof(int8_fast) >= 1, "int8_fast must be at least 1 byte");
static_assert(sizeof(int16_fast) >= 2, "int16_fast must be at least 2 bytes");
static_assert(sizeof(int32_fast) >= 4, "int32_fast must be at least 4 bytes");
static_assert(sizeof(int64_fast) >= 8, "int64_fast must be at least 8 bytes");
static_assert(static_cast<int8>(0xFF) == -1, "int8 use two's complement");
static_assert(static_cast<int16>(0xFFFF) == -1, "int16 use two's complement");
static_assert(static_cast<int32>(0xFFFFFFFF) == -1, "int32 use two's complement");
static_assert(static_cast<int64>(0xFFFFFFFFFFFFFFFF) == -1, "int64 use two's complement");
// Unsigned integral types
using uint = unsigned int;
using byte = unsigned char;
using uint8 = NAMESPACE_STD::uint8_t;
using uint16 = NAMESPACE_STD::uint16_t;
using uint32 = NAMESPACE_STD::uint32_t;
@ -398,6 +421,26 @@ using uintmax = uint128;
using uintmax = uint64;
#endif
static_assert(sizeof(uint8) == 1, "uint8 must be 1 byte");
static_assert(sizeof(uint16) == 2, "uint16 must be 2 bytes");
static_assert(sizeof(uint32) == 4, "uint32 must be 4 bytes");
static_assert(sizeof(uint64) == 8, "uint64 must be 8 bytes");
static_assert(sizeof(uint8_least) >= 1, "uint8_least must be at least 1 byte");
static_assert(sizeof(uint16_least) >= 2, "uint16_least must be at least 2 bytes");
static_assert(sizeof(uint32_least) >= 4, "uint32_least must be at least 4 bytes");
static_assert(sizeof(uint64_least) >= 8, "uint64_least must be at least 8 bytes");
static_assert(sizeof(uint8_fast) >= 1, "uint8_fast must be at least 1 byte");
static_assert(sizeof(uint16_fast) >= 2, "uint16_fast must be at least 2 bytes");
static_assert(sizeof(uint32_fast) >= 4, "uint32_fast must be at least 4 bytes");
static_assert(sizeof(uint64_fast) >= 8, "uint64_fast must be at least 8 bytes");
static_assert(static_cast<uint8 >(-1) > static_cast< uint8>(0), "uint8 must be unsigned");
static_assert(static_cast<uint16>(-1) > static_cast<uint16>(0), "uint16 must be unsigned");
static_assert(static_cast<uint32>(-1) > static_cast<uint32>(0), "uint32 must be unsigned");
static_assert(static_cast<uint64>(-1) > static_cast<uint64>(0), "uint64 must be unsigned");
// Floating point types
#if PLATFORM_HAS_FLOAT16
@ -451,10 +494,13 @@ static_assert(!PLATFORM_LINUX || sizeof(wchar) == sizeof(u32char), "wchar repr
// Pointer types
using uintptr = NAMESPACE_STD::uintptr_t;
using intptr = NAMESPACE_STD::intptr_t;
using ptrdiff = NAMESPACE_STD::ptrdiff_t;
using size_t = NAMESPACE_STD::size_t;
using ssize_t = intptr_t;
static_assert(sizeof(uintptr) == sizeof(void*), "uintptr must be the same size as a pointer");
static_assert(sizeof(ptrdiff) == sizeof(void*), "ptrdiff must be the same size as a pointer");
static_assert(sizeof(size_t) == sizeof(void*), "size_t must be the same size as a pointer");
static_assert(static_cast<uintptr>(-1) > static_cast<uintptr>(0), "uintptr must be unsigned");
// Null types

View File

@ -0,0 +1,91 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h"
#include <limits>
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
static_assert(CHAR_BIT == 8, "CHAR_BIT must be 8");
enum class EFloatRoundMode : uint8
{
TowardZero,
ToNearest,
Upward,
Downward,
Unknown,
};
enum class EFloatDenormMode : uint8
{
Absent,
Present,
Unknown,
};
template <CArithmetic T>
struct TNumericLimits;
template <typename T> struct TNumericLimits<const T> : public TNumericLimits<T> { };
template <typename T> struct TNumericLimits< volatile T> : public TNumericLimits<T> { };
template <typename T> struct TNumericLimits<const volatile T> : public TNumericLimits<T> { };
template <CArithmetic T>
struct TNumericLimits
{
static_assert(!CFloatingPoint<T> || NAMESPACE_STD::numeric_limits<T>::has_infinity, "Floating point types must have infinity.");
static_assert(!CFloatingPoint<T> || NAMESPACE_STD::numeric_limits<T>::has_quiet_NaN, "Floating point types must have quiet NaN.");
static_assert(!CFloatingPoint<T> || NAMESPACE_STD::numeric_limits<T>::has_signaling_NaN, "Floating point types must have signaling NaN.");
static constexpr bool bIsExact = NAMESPACE_STD::numeric_limits<T>::is_exact;
static constexpr EFloatRoundMode RoundMode =
NAMESPACE_STD::numeric_limits<T>::round_style == NAMESPACE_STD::round_toward_zero ? EFloatRoundMode::TowardZero :
NAMESPACE_STD::numeric_limits<T>::round_style == NAMESPACE_STD::round_to_nearest ? EFloatRoundMode::ToNearest :
NAMESPACE_STD::numeric_limits<T>::round_style == NAMESPACE_STD::round_toward_infinity ? EFloatRoundMode::Upward :
NAMESPACE_STD::numeric_limits<T>::round_style == NAMESPACE_STD::round_toward_neg_infinity ? EFloatRoundMode::Downward :
EFloatRoundMode::Unknown;
static constexpr EFloatDenormMode DenormMode =
NAMESPACE_STD::numeric_limits<T>::has_denorm == NAMESPACE_STD::denorm_absent ? EFloatDenormMode::Absent :
NAMESPACE_STD::numeric_limits<T>::has_denorm == NAMESPACE_STD::denorm_present ? EFloatDenormMode::Present :
EFloatDenormMode::Unknown;
static constexpr bool bHasDenormLoss = NAMESPACE_STD::numeric_limits<T>::has_denorm_loss;
static constexpr bool bIsIEEE754 = NAMESPACE_STD::numeric_limits<T>::is_iec559 && sizeof(T) <= 8;
static constexpr bool bIsModulo = NAMESPACE_STD::numeric_limits<T>::is_modulo;
static constexpr int Radix = NAMESPACE_STD::numeric_limits<T>::radix;
static constexpr int Digits = NAMESPACE_STD::numeric_limits<T>::digits;
static constexpr int Digits10 = NAMESPACE_STD::numeric_limits<T>::digits10;
static constexpr int MaxExponent = NAMESPACE_STD::numeric_limits<T>::max_exponent;
static constexpr int MaxExponent10 = NAMESPACE_STD::numeric_limits<T>::max_exponent10;
static constexpr int MinExponent = NAMESPACE_STD::numeric_limits<T>::min_exponent;
static constexpr int MinExponent10 = NAMESPACE_STD::numeric_limits<T>::min_exponent10;
static constexpr bool bInterrupt = NAMESPACE_STD::numeric_limits<T>::traps;
static constexpr T Min() { return NAMESPACE_STD::numeric_limits<T>::lowest(); }
static constexpr T Max() { return NAMESPACE_STD::numeric_limits<T>::max(); }
static constexpr T Epsilon() { return NAMESPACE_STD::numeric_limits<T>::epsilon(); }
static constexpr T Infinity() { return NAMESPACE_STD::numeric_limits<T>::infinity(); }
static constexpr T QuietNaN() { return NAMESPACE_STD::numeric_limits<T>::quiet_NaN(); }
static constexpr T SignalingNaN() { return NAMESPACE_STD::numeric_limits<T>::signaling_NaN(); }
static constexpr T MinNormal() { return NAMESPACE_STD::numeric_limits<T>::min(); }
static constexpr T MinDenorm() { return NAMESPACE_STD::numeric_limits<T>::denorm_min(); }
};
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -0,0 +1,40 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_BEGIN(Math)
template <CFloatingPoint T>
struct TConstant
{
static constexpr T E = static_cast<T>(2.71828182845904523536028747135266249775724709369995);
static constexpr T Log2E = static_cast<T>(1.44269504088896340735992468100189213742664595415299);
static constexpr T Log10E = static_cast<T>(0.43429448190325182765112891891660508229439700580367);
static constexpr T Pi = static_cast<T>(3.14159265358979323846264338327950288419716939937511);
static constexpr T HalfPi = static_cast<T>(1.57079632679489661923132169163975144209858469968756);
static constexpr T TwoPi = static_cast<T>(6.28318530717958647692528676655900576839433879875022);
static constexpr T SquaredPi = static_cast<T>(9.86960440108935861883449099987615113531369940724079);
static constexpr T InvPi = static_cast<T>(0.31830988618379067153776752674502872406891929148091);
static constexpr T InvSqrtPi = static_cast<T>(0.56418958354775628694807945156077258584405062932900);
static constexpr T Ln2 = static_cast<T>(0.69314718055994530941723212145817656807550013436026);
static constexpr T Ln10 = static_cast<T>(2.30258509299404568401799145468436420760110148862877);
static constexpr T Sqrt2 = static_cast<T>(1.41421356237309504880168872420969807856967187537694);
static constexpr T Sqrt3 = static_cast<T>(1.73205080756887729352744634150587236694280525381038);
static constexpr T InvSqrt2 = static_cast<T>(0.70710678118654752440084436210484903928483593768847);
static constexpr T InvSqrt3 = static_cast<T>(0.57735026918962576450914878050195745564760175127013);
static constexpr T HalfSqrt2 = static_cast<T>(0.70710678118654752440084436210484903928483593768847);
static constexpr T HalfSqrt3 = static_cast<T>(0.86602540378443864676372317075293618347140262690519);
static constexpr T EGamma = static_cast<T>(0.57721566490153286060651209008240243104215933593992);
static constexpr T GoldenRatio = static_cast<T>(1.61803398874989484820458683436563811772030917980576);
};
NAMESPACE_END(Math)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -75,7 +75,7 @@ public:
// Make sure you call this function after you have destroyed the held object using Destroy().
template <typename T, typename U>
FORCEINLINE constexpr void Emplace(intptr InCallable, U&& Args)
FORCEINLINE constexpr void Emplace(uintptr InCallable, U&& Args)
{
static_assert(CSameAs<TDecay<T>, TDecay<U>>);
ValuePtr = reinterpret_cast<uintptr>(AddressOf(Args));

View File

@ -53,7 +53,7 @@ FORCEINLINE constexpr size_t GetTypeHash(T A)
if constexpr (sizeof(T) == 8) return GetTypeHash(static_cast<uint32>(A)) ^ GetTypeHash(static_cast<uint32>(A >> 32));
if constexpr (sizeof(T) == 16) return GetTypeHash(static_cast<uint64>(A)) ^ GetTypeHash(static_cast<uint64>(A >> 64));
else check_no_entry();
return INDEX_NONE;
}
@ -69,7 +69,7 @@ FORCEINLINE constexpr size_t GetTypeHash(T A)
if constexpr (sizeof(T) == 8) return GetTypeHash(*reinterpret_cast<uint64*>(&A));
if constexpr (sizeof(T) == 16) return GetTypeHash(*reinterpret_cast<uint64*>(&A) ^ *(reinterpret_cast<uint64*>(&A) + 1));
else check_no_entry();
return INDEX_NONE;
}
@ -84,7 +84,7 @@ FORCEINLINE constexpr size_t GetTypeHash(T A)
template <typename T> requires (CPointer<T> || CSameAs<T, nullptr_t>)
FORCEINLINE constexpr size_t GetTypeHash(T A)
{
return GetTypeHash(reinterpret_cast<intptr>(A));
return GetTypeHash(reinterpret_cast<uintptr>(A));
}
/** Overloads the GetTypeHash algorithm for T::hash_code(). */