[*] Stupid fuck compiler (clang)

This commit is contained in:
Reece Wilson 2023-08-22 14:08:10 +01:00 committed by J Reece Wilson
parent 15398bdd10
commit d7d2a576b2
2 changed files with 107 additions and 45 deletions

View File

@ -18,8 +18,14 @@
#define _AU_FNV1_32 0
#endif
constexpr AuUInt64 kFnv1MagicVal64 = 0xcbf29ce484222325;
constexpr AuUInt64 kFnv1MagicPrime64 = 0x100000001b3;
#if defined(AURORA_COMPILER_CLANG) && !defined(AURORA_BUG_CLANG_SUPPORT_HASH_OVERFLOW)
#define _AU_HASH_RETARD_COMPILER
#pragma optimize("", off)
//#pragma GCC optimize ("no-fast-math")
#endif
constexpr AuUInt64 kFnv1MagicVal64 = 0xcbf29ce484222325ull;
constexpr AuUInt64 kFnv1MagicPrime64 = 0x100000001b3ull;
constexpr AuUInt32 kFnv1MagicVal32 = 0x811c9dc5;
constexpr AuUInt32 kFnv1MagicPrime32 = 0x01000193;
@ -41,38 +47,56 @@ inline constexpr AuUInt32 AuFnv1a32(const char *const str, const AuUInt32 value
return (str[0] == '\0') ? value : AuFnv1a32(&str[1], (value ^ AuUInt32(str[0])) * kFnv1MagicPrime32);
}
inline constexpr AuUInt AuFnv1aType(const char *type, AuUInt size, AuUInt index, const AuUInt value) noexcept
inline constexpr AuUInt AuFnv1aType(const char *const type, AuUInt size, AuUInt index, const AuUInt value) noexcept
{
return (index == size) ? value : AuFnv1aType(type + 1, size, index + 1, (value ^ AuUInt(*type)) * kFnv1MagicPrimePlatform);
}
inline constexpr AuUInt32 AuFnv1aType32(const char *type, AuUInt size, AuUInt index, const AuUInt32 value) noexcept
inline constexpr AuUInt32 AuFnv1aType32(const char *const type, AuUInt size, AuUInt index, const AuUInt32 value) noexcept
{
return (index == size) ? value : AuFnv1aType32(type + 1, size, index + 1, (value ^ AuUInt32(*type)) * kFnv1MagicPrime32);
}
inline constexpr AuUInt64 AuFnv1aType64(const char *type, AuUInt size, AuUInt index, const AuUInt64 value) noexcept
inline constexpr AuUInt64 AuFnv1aType64(const char *const type, AuUInt size, AuUInt index, const AuUInt64 value) noexcept
{
return (index == size) ? value : AuFnv1aType64(type + 1, size, index + 1, (value ^ AuUInt64(*type)) * kFnv1MagicPrime64);
}
#if !defined(_AU_HASH_RETARD_COMPILER)
template <class T>
inline constexpr AuUInt32 AuFnv1aType32(T type, const AuUInt32 value = kFnv1MagicVal32) noexcept
{
#if defined(AURORA_COMPILER_CLANG)
static_assert(false, "Unsupported constexpr hash on type");
#else
return AuFnv1aType32(((const char *)&type) + 1, sizeof(T), 1, (value ^ (AuUInt32(*(const char *)&type)) * kFnv1MagicPrime32));
#endif
}
#endif
#if !defined(_AU_HASH_RETARD_COMPILER)
template <class T>
inline constexpr AuUInt64 AuFnv1aType64(T type, const AuUInt64 value = kFnv1MagicVal64) noexcept
{
#if defined(AURORA_COMPILER_CLANG)
static_assert(false, "Unsupported constexpr hash on type");
#else
return AuFnv1aType64(((const char *)&type) + 1, sizeof(T), 1, (value ^ (AuUInt64(*(const char *)&type)) * kFnv1MagicPrime64));
#endif
}
#endif
#if !defined(_AU_HASH_RETARD_COMPILER)
template <class T>
inline constexpr AuUInt AuFnv1aType(const T &type, const AuUInt value = kFnv1MagicValPlatform) noexcept
{
return AuFnv1aType(((const char *)&type) + 1, sizeof(T), 1, (value ^ (AuUInt(*(const char *)&type)) * kFnv1MagicPrimePlatform));
}
template <class T>
inline constexpr AuUInt32 AuFnv1aType32(const T &type, const AuUInt32 value = kFnv1MagicVal32) noexcept
{
return AuFnv1aType32(((const char *)&type) + 1, sizeof(T), 1, (value ^ (AuUInt(*(const char *)&type)) * kFnv1MagicPrime32));
}
template <class T>
inline constexpr AuUInt64 AuFnv1aType64(const T &type, const AuUInt64 value = kFnv1MagicVal64) noexcept
{
return AuFnv1aType64(((const char *)&type) + 1, sizeof(T), 1, (value ^ (AuUInt(*(const char *)&type)) * kFnv1MagicPrime64));
#if _AU_FNV1_32
return AuFnv1aType32(type, value);
#else
return AuFnv1aType64(type, value);
#endif
}
#endif
template <class T>
inline constexpr AuUInt AuFnv1aPtr(const T *const type, AuUInt length, const AuUInt value = kFnv1MagicValPlatform) noexcept
@ -118,7 +142,7 @@ inline AuUInt32 AuFnv1a32Runtime(const void *base, AuUInt length) noexcept
AuUInt i {};
for (; i < length; i++)
{
result ^= AuUInt(AuReadU8(base, i)) * kFnv1MagicPrime32;
result ^= AuUInt32(AuReadU8(base, i)) * AuUInt32(kFnv1MagicPrime32);
}
return result;
@ -131,7 +155,7 @@ inline AuUInt64 AuFnv1a64Runtime(const void *base, AuUInt length) noexcept
AuUInt i {};
for (; i < length; i++)
{
result ^= AuUInt64(AuReadU8(base, i)) * kFnv1MagicPrime64;
result ^= AuUInt64(AuReadU8(base, i)) * AuUInt64(kFnv1MagicPrime64);
}
return result;
@ -144,4 +168,10 @@ inline auto AuFnv1aRuntime(const void *base, AuUInt length) noexcept
AuFnv1a64Runtime(base, length);
}
#undef _AU_FNV1_32
#undef _AU_FNV1_32
#if defined(_AU_HASH_RETARD_COMPILER)
#pragma optimize("", on)
//#pragma GCC optimize ("fast-math")
#undef _AU_HASH_RETARD_COMPILER
#endif

View File

@ -11,6 +11,13 @@
#define _AU_HASH_UTILS_HAS_STD
#if defined(AURORA_COMPILER_CLANG) && !defined(AURORA_BUG_DOES_CLANG_SUPPORT_64_BIT_CONSTEXPR_YET)
#define _AU_HASH_RETARD_COMPILER
#define _AH_HAS_RETARD_CONSTEXPR
#else
#define _AH_HAS_RETARD_CONSTEXPR constexpr
#endif
template <class T>
struct AuHasHashCode
{
@ -54,7 +61,7 @@ namespace AuHash
// Real world experience > 1999 HP guy > whatever the fuck the stl is doing (i think ms just uses fnv1s for everything)
//
// Preserving original function names for ease of xref. unseeded vs implied seeded doesnt mean anything. see: ComputeLongHash comment.
inline constexpr AuUInt32 ComputeUnseededHash(AuUInt32 key)
inline _AH_HAS_RETARD_CONSTEXPR AuUInt32 ComputeUnseededHash(AuUInt32 key)
{
AuUInt32 hash = key;
hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1;
@ -68,7 +75,7 @@ namespace AuHash
// ComputeLongHash(base::double_to_uint64(AsNumber())); ( pre-maglev V8 wasn't u64 optimizated. )
// ComputeLongHash(static_cast<uint64_t>(digit(0))); ( most js wont touch >31bit ints. )
inline constexpr AuUInt64 ComputeLongHash(AuUInt64 key)// ( i'm sure this function's fine for all ranges. )
inline _AH_HAS_RETARD_CONSTEXPR AuUInt64 ComputeLongHash(AuUInt64 key)// ( i'm sure this function's fine for all ranges. )
{
AuUInt64 hash = key;
hash = ~hash + (hash << 18); // hash = (hash << 18) - hash - 1;
@ -80,26 +87,46 @@ namespace AuHash
return hash;
}
#else
inline constexpr AuUInt32 ComputeUnseededHash(AuUInt32 key)
inline _AH_HAS_RETARD_CONSTEXPR AuUInt32 ComputeUnseededHash(AuUInt32 key)
{
return AuFnv1aType<AuUInt32>(key);
#if defined(_AU_HASH_RETARD_COMPILER)
return AuFnv1aRuntime(&key, sizeof(key));
#else
return AuFnv1aType<AuUInt32>(key);
#endif
}
inline constexpr AuUInt64 ComputeLongHash(AuUInt64 key)
inline _AH_HAS_RETARD_CONSTEXPR AuUInt64 ComputeLongHash(AuUInt64 key)
{
return AuFnv1aType<AuUInt64>(key);
#if defined(_AU_HASH_RETARD_COMPILER)
return AuFnv1aRuntime(&key, sizeof(key));
#else
return AuFnv1aType<AuUInt64>(key);
#endif
}
#endif
#define _HASH_INT(type) \
template <> \
struct hash<type> \
{ \
constexpr AuUInt operator ()(const type b) const \
{ \
return AuFnv1aType<type>(b); \
} \
};
#if defined(_AU_HASH_RETARD_COMPILER)
#define _HASH_INT(type) \
template <> \
struct hash<type> \
{ \
_AH_HAS_RETARD_CONSTEXPR AuUInt operator ()(const type b) const \
{ \
return AuFnv1aRuntime(&b, sizeof(b)); \
} \
};
#else
#define _HASH_INT(type) \
template <> \
struct hash<type> \
{ \
_AH_HAS_RETARD_CONSTEXPR AuUInt operator ()(const type b) const \
{ \
return AuFnv1aType<type>(b); \
} \
};
#endif
#if defined(AURORA_IS_32BIT)
@ -107,7 +134,7 @@ namespace AuHash
template <> \
struct hash<type> \
{ \
constexpr AuUInt operator ()(const type intValue) const \
_AH_HAS_RETARD_CONSTEXPR AuUInt operator ()(const type intValue) const \
{ \
return ComputeUnseededHash(AuUInt32(intValue)); \
} \
@ -119,7 +146,7 @@ namespace AuHash
template <> \
struct hash<type> \
{ \
constexpr AuUInt operator ()(const type intValue) const \
_AH_HAS_RETARD_CONSTEXPR AuUInt operator ()(const type intValue) const \
{ \
return ComputeLongHash(AuUInt64(intValue)); \
} \
@ -133,7 +160,7 @@ namespace AuHash
template <> \
struct hash<type> \
{ \
constexpr AuUInt operator ()(const type intValue) const \
_AH_HAS_RETARD_CONSTEXPR AuUInt operator ()(const type intValue) const \
{ \
return AuUInt32(ComputeLongHash(AuUInt64(intValue)) & 0xFFFFFFFF); \
} \
@ -145,7 +172,7 @@ namespace AuHash
template <> \
struct hash<type> \
{ \
constexpr AuUInt operator ()(const type intValue) const \
_AH_HAS_RETARD_CONSTEXPR AuUInt operator ()(const type intValue) const \
{ \
return ComputeLongHash(AuUInt64(intValue)); \
} \
@ -181,7 +208,7 @@ namespace AuHash
template <class T>
struct hash<T *>
{
AuUInt operator ()(T *ptr) const
_AH_HAS_RETARD_CONSTEXPR AuUInt operator ()(T *ptr) const
{
#if defined(AURORA_IS_32BIT)
return ComputeUnseededHash(AuUInt(ptr));
@ -194,7 +221,7 @@ namespace AuHash
template <class T>
struct less
{
constexpr bool operator()(const T &lhs, const T &rhs) const
bool operator()(const T &lhs, const T &rhs) const
{
if constexpr (AuHasHashCode_v<T>)
{
@ -210,7 +237,7 @@ namespace AuHash
template <class T>
struct equal
{
constexpr bool operator()(const T &lhs, const T &rhs) const
bool operator()(const T &lhs, const T &rhs) const
{
return lhs == rhs;
}
@ -236,7 +263,7 @@ namespace AuHash
template <typename T, typename Z>
struct hash<AuPair<T, Z>>
{
constexpr AuUInt operator ()(const AuPair<T, Z> &pair) const
AuUInt operator ()(const AuPair<T, Z> &pair) const
{
return AuHashCode(AuGet<0>(pair)) ^
AuHashCode(AuGet<1>(pair));
@ -246,7 +273,7 @@ namespace AuHash
template <class ...Ts>
struct hash<AuTuple<Ts...>>
{
constexpr AuUInt operator ()(const AuTuple<Ts...> &tuple) const
AuUInt operator ()(const AuTuple<Ts...> &tuple) const
{
AuUInt uHashCode {};
AuTupleForEach(tuple, [&](auto & a /*c++14 poggurs*/)
@ -270,3 +297,8 @@ struct AuEnableHashCodeOnData
#endif
}
};
#if defined(_AU_HASH_RETARD_COMPILER)
#undef _AU_HASH_RETARD_COMPILER
#undef _AH_HAS_RETARD_CONSTEXPR
#endif