143 lines
3.4 KiB
C++
143 lines
3.4 KiB
C++
/***
|
|
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 <class T>
|
|
struct AuHasHashCode
|
|
{
|
|
template <class C> static constexpr AuTrueType Test(decltype(&C::HashCode));
|
|
template <class C> static constexpr AuFalseType Test(...);
|
|
using type = decltype(Test<T>(0));
|
|
};
|
|
|
|
template <class T>
|
|
constexpr inline bool AuHasHashCode_v = AuHasHashCode<T>::type::value;
|
|
|
|
namespace AuHash
|
|
{
|
|
template <class Key>
|
|
struct hash
|
|
{
|
|
#if defined(_AU_HASH_UTILS_HAS_STD)
|
|
AuConditional_t<AuHasHashCode_v<Key>, AuUInt8, std::hash<Key>> trashHasher;
|
|
#endif
|
|
|
|
AuUInt operator()(const Key &ref) const
|
|
{
|
|
if constexpr (AuHasHashCode_v<Key>)
|
|
{
|
|
return ref.HashCode();
|
|
}
|
|
#if defined(_AU_HASH_UTILS_HAS_STD)
|
|
else
|
|
{
|
|
return trashHasher(ref);
|
|
}
|
|
#endif
|
|
}
|
|
};
|
|
|
|
#define _HASH_F_CPP(type) \
|
|
template <> \
|
|
struct hash<type> \
|
|
{ \
|
|
constexpr AuUInt operator ()(const type b) const \
|
|
{ \
|
|
return AuFnv1aType<type>(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 <class T> struct hash<T *>
|
|
{
|
|
AuUInt operator ()(T *ptr) const
|
|
{
|
|
#if defined(AURORA_IS_32BIT)
|
|
return AuFnv1a32Runtime(&ptr, sizeof(T *));
|
|
#else
|
|
return AuFnv1a64Runtime(&ptr, sizeof(T *));
|
|
#endif
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
struct less
|
|
{
|
|
constexpr bool operator()(const T &lhs, const T &rhs) const
|
|
{
|
|
if constexpr (AuHasHashCode_v<T>)
|
|
{
|
|
return lhs.HashCode() < rhs.HashCode();
|
|
}
|
|
else
|
|
{
|
|
return lhs < rhs;
|
|
}
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
struct equal
|
|
{
|
|
constexpr bool operator()(const T &lhs, const T &rhs) const
|
|
{
|
|
return lhs == rhs;
|
|
}
|
|
};
|
|
}
|
|
|
|
template <class T, AU_TEMPLATE_ENABLE_WHEN(AuHasHashCode_v<T>)>
|
|
inline AuUInt AuHashCode(const T &ref)
|
|
{
|
|
return ref.HashCode();
|
|
}
|
|
|
|
template <class T, AU_TEMPLATE_ENABLE_WHEN(!AuHasHashCode_v<T>)>
|
|
inline AuUInt AuHashCode(const T &ref)
|
|
{
|
|
return AuHash::hash<T>()(ref);
|
|
}
|
|
|
|
template <class T>
|
|
struct AuEnableHashCodeOnData
|
|
{
|
|
AuUInt HashCode() const
|
|
{
|
|
#if defined(AURORA_IS_32BIT)
|
|
return AuFnv1a32Runtime(AuStaticCast<AuAddConst_t<T>>(this), sizeof(T));
|
|
#else
|
|
return AuFnv1a64Runtime(AuStaticCast<AuAddConst_t<T>>(this), sizeof(T));
|
|
#endif
|
|
}
|
|
}; |