/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: auFNV1Utils.hpp Date: 2022-3-23 File: fnv1.hpp Date: 2021-6-10 Author: Reece ***/ #pragma once #include "auTypeUtils.hpp" // Note: we're too early for AuroraEnv.hpp w/ AuroraEnums #if defined(AURORA_IS_32BIT) #define _AU_FNV1_32 1 #else #define _AU_FNV1_32 0 #endif constexpr AuUInt64 kFnv1MagicVal64 = 0xcbf29ce484222325; constexpr AuUInt64 kFnv1MagicPrime64 = 0x100000001b3; constexpr AuUInt32 kFnv1MagicVal32 = 0x811c9dc5; constexpr AuUInt32 kFnv1MagicPrime32 = 0x01000193; constexpr auto kFnv1MagicValPlatform = _AU_FNV1_32 ? kFnv1MagicVal32 : kFnv1MagicVal64; constexpr auto kFnv1MagicPrimePlatform = _AU_FNV1_32 ? kFnv1MagicPrime32 : kFnv1MagicPrime64; inline constexpr AuUInt64 AuFnv1a64(const char *const str, const AuUInt64 value = kFnv1MagicVal64) noexcept { return (str[0] == '\0') ? value : AuFnv1a64(&str[1], (value ^ AuUInt64(str[0])) * kFnv1MagicPrime64); } inline constexpr AuUInt32 AuFnv1aTrunc(const char *const str) noexcept { return static_cast(AuFnv1a64(str)); } inline constexpr AuUInt32 AuFnv1a32(const char *const str, const AuUInt32 value = kFnv1MagicVal32) noexcept { 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 { return (index == size) ? value : AuFnv1aType(type + 1, size, index + 1, (value ^ AuUInt(*type) * kFnv1MagicPrimePlatform)); } 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)); } inline constexpr auto AuFnv1a(const char *const str) noexcept { return _AU_FNV1_32 ? AuFnv1a32(str) : AuFnv1a64(str); } inline AuUInt32 AuFnv1a32Runtime(const void *base, AuUInt length) noexcept { AuUInt32 result {kFnv1MagicVal32}; AuUInt i {}; for (; i < length; i++) { result ^= AuUInt(AuReadU8(base, i)) * kFnv1MagicPrime32; } return result; } inline AuUInt64 AuFnv1a64Runtime(const void *base, AuUInt length) noexcept { AuUInt64 result {kFnv1MagicVal64}; AuUInt i {}; for (; i < length; i++) { result ^= AuUInt64(AuReadU8(base, i)) * kFnv1MagicPrime64; } return result; } #undef _AU_FNV1_32