/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: auHashUtils.hpp Date: 2022-3-23 Author: Reece ***/ #pragma once #include "auFNV1Utils.hpp" #define _AU_HASH_UTILS_HAS_STD template struct AuHasHashCode { template static constexpr AuTrueType Test(decltype(&C::HashCode)); template static constexpr AuFalseType Test(...); using type = decltype(Test(0)); }; template constexpr inline bool AuHasHashCode_v = AuHasHashCode::type::value; namespace AuHash { template struct hash { #if defined(_AU_HASH_UTILS_HAS_STD) AuConditional_t, AuUInt8, std::hash> trashHasher; #endif AuUInt operator()(const Key &ref) const { if constexpr (AuHasHashCode_v) { return ref.HashCode(); } #if defined(_AU_HASH_UTILS_HAS_STD) else { return trashHasher(ref); } #endif } }; #define _HASH_F_CPP(type) \ template <> \ struct hash \ { \ constexpr AuUInt operator ()(const type b) const \ { \ return AuFnv1aType(b); \ } \ }; _HASH_F_CPP(bool); _HASH_F_CPP(char); _HASH_F_CPP(signed char); _HASH_F_CPP(unsigned char); _HASH_F_CPP(char8_t); _HASH_F_CPP(char16_t); _HASH_F_CPP(char32_t); _HASH_F_CPP(wchar_t); _HASH_F_CPP(short); _HASH_F_CPP(unsigned short); _HASH_F_CPP(int); _HASH_F_CPP(unsigned int); _HASH_F_CPP(long); _HASH_F_CPP(long long); _HASH_F_CPP(unsigned long); _HASH_F_CPP(unsigned long long); _HASH_F_CPP(float); _HASH_F_CPP(double); _HASH_F_CPP(long double); _HASH_F_CPP(std::nullptr_t); #undef _HASH_F_CPP template struct hash { AuUInt operator ()(T *ptr) const { #if defined(AURORA_IS_32BIT) return AuFnv1a32Runtime(&ptr, sizeof(T *)); #else return AuFnv1a64Runtime(&ptr, sizeof(T *)); #endif } }; template struct less { constexpr bool operator()(const T &lhs, const T &rhs) const { if constexpr (AuHasHashCode_v) { return lhs.HashCode() < rhs.HashCode(); } else { return lhs < rhs; } } }; template struct equal { constexpr bool operator()(const T &lhs, const T &rhs) const { return lhs == rhs; } }; } template )> inline AuUInt AuHashCode(const T &ref) { return ref.HashCode(); } template )> inline AuUInt AuHashCode(const T &ref) { return AuHash::hash()(ref); } template struct AuEnableHashCodeOnData { AuUInt HashCode() const { #if defined(AURORA_IS_32BIT) return AuFnv1a32Runtime(AuStaticCast>(this), sizeof(T)); #else return AuFnv1a64Runtime(AuStaticCast>(this), sizeof(T)); #endif } };