diff --git a/Include/auROXTL/auFNV1Utils.hpp b/Include/auROXTL/auFNV1Utils.hpp index 40dfd4b..d47c223 100644 --- a/Include/auROXTL/auFNV1Utils.hpp +++ b/Include/auROXTL/auFNV1Utils.hpp @@ -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 +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 +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 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 -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 -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 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 \ No newline at end of file +#undef _AU_FNV1_32 + +#if defined(_AU_HASH_RETARD_COMPILER) + #pragma optimize("", on) + //#pragma GCC optimize ("fast-math") + #undef _AU_HASH_RETARD_COMPILER +#endif \ No newline at end of file diff --git a/Include/auROXTL/auHashUtils.hpp b/Include/auROXTL/auHashUtils.hpp index fdae339..aec2390 100644 --- a/Include/auROXTL/auHashUtils.hpp +++ b/Include/auROXTL/auHashUtils.hpp @@ -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 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(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(key); + #if defined(_AU_HASH_RETARD_COMPILER) + return AuFnv1aRuntime(&key, sizeof(key)); + #else + return AuFnv1aType(key); + #endif } - inline constexpr AuUInt64 ComputeLongHash(AuUInt64 key) + inline _AH_HAS_RETARD_CONSTEXPR AuUInt64 ComputeLongHash(AuUInt64 key) { - return AuFnv1aType(key); + #if defined(_AU_HASH_RETARD_COMPILER) + return AuFnv1aRuntime(&key, sizeof(key)); + #else + return AuFnv1aType(key); + #endif } #endif -#define _HASH_INT(type) \ - template <> \ - struct hash \ - { \ - constexpr AuUInt operator ()(const type b) const \ - { \ - return AuFnv1aType(b); \ - } \ - }; +#if defined(_AU_HASH_RETARD_COMPILER) + #define _HASH_INT(type) \ + template <> \ + struct hash \ + { \ + _AH_HAS_RETARD_CONSTEXPR AuUInt operator ()(const type b) const \ + { \ + return AuFnv1aRuntime(&b, sizeof(b)); \ + } \ + }; +#else + #define _HASH_INT(type) \ + template <> \ + struct hash \ + { \ + _AH_HAS_RETARD_CONSTEXPR AuUInt operator ()(const type b) const \ + { \ + return AuFnv1aType(b); \ + } \ + }; +#endif #if defined(AURORA_IS_32BIT) @@ -107,7 +134,7 @@ namespace AuHash template <> \ struct hash \ { \ - 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 \ { \ - 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 \ { \ - 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 \ { \ - 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 struct hash { - 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 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) { @@ -210,7 +237,7 @@ namespace AuHash template 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 struct hash> { - constexpr AuUInt operator ()(const AuPair &pair) const + AuUInt operator ()(const AuPair &pair) const { return AuHashCode(AuGet<0>(pair)) ^ AuHashCode(AuGet<1>(pair)); @@ -246,7 +273,7 @@ namespace AuHash template struct hash> { - constexpr AuUInt operator ()(const AuTuple &tuple) const + AuUInt operator ()(const AuTuple &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 \ No newline at end of file