//! The default value for the seed is optimal for general cases at a certain hash size.
namespace MurmurHash
{
-uint32_t MurmurHash2A(const void* theKey, int theLen, uint32_t theSeed);
-uint64_t MurmurHash64A(const void* theKey, int theLen, uint64_t theSeed);
+uint32_t MurmurHash2A(const void* theKey, int theLen, uint32_t theSeed) noexcept;
+uint64_t MurmurHash64A(const void* theKey, int theLen, uint64_t theSeed) noexcept;
template <typename T1, typename T = size_t>
typename std::enable_if<sizeof(T) == 8, uint64_t>::type hash_combine(
const T1& theValue,
const int theLen = sizeof(T1),
- const T theSeed = 0xA329F1D3A586ULL)
+ const T theSeed = 0xA329F1D3A586ULL) noexcept
{
return MurmurHash::MurmurHash64A(&theValue, theLen, theSeed);
}
template <typename T1, typename T = size_t>
-typename std::enable_if<sizeof(T) != 8, T>::type hash_combine(const T1& theValue,
- const int theLen = sizeof(T1),
- const T theSeed = 0xc70f6907U)
+typename std::enable_if<sizeof(T) != 8, T>::type hash_combine(
+ const T1& theValue,
+ const int theLen = sizeof(T1),
+ const T theSeed = 0xc70f6907U) noexcept
{
return static_cast<T>(MurmurHash::MurmurHash2A(&theValue, theLen, theSeed));
}
template <typename T = size_t>
-constexpr T optimalSeed()
+constexpr T optimalSeed() noexcept
{
return sizeof(T) == 8 ? static_cast<T>(0xA329F1D3A586ULL) : static_cast<T>(0xc70f6907U);
}
//! The default value for the seed is optimal for general cases at a certain hash size.
namespace FNVHash
{
-uint32_t FNVHash1A(const void* theKey, int theLen, uint32_t theSeed);
-uint64_t FNVHash64A(const void* theKey, int theLen, uint64_t theSeed);
+uint32_t FNVHash1A(const void* theKey, int theLen, uint32_t theSeed) noexcept;
+uint64_t FNVHash64A(const void* theKey, int theLen, uint64_t theSeed) noexcept;
template <typename T1, typename T = size_t>
static typename std::enable_if<sizeof(T) == 8, uint64_t>::type hash_combine(
const T1& theValue,
const int theLen = sizeof(T1),
- const T theSeed = 14695981039346656037ULL)
+ const T theSeed = 14695981039346656037ULL) noexcept
{
return FNVHash::FNVHash64A(&theValue, theLen, theSeed);
}
template <typename T1, typename T = size_t>
-static typename std::enable_if<sizeof(T) != 8, T>::type hash_combine(const T1& theValue,
- const int theLen = sizeof(T1),
- const T theSeed = 2166136261U)
+static typename std::enable_if<sizeof(T) != 8, T>::type hash_combine(
+ const T1& theValue,
+ const int theLen = sizeof(T1),
+ const T theSeed = 2166136261U) noexcept
{
return static_cast<T>(FNVHash::FNVHash1A(&theValue, theLen, theSeed));
}
template <typename T = size_t>
-constexpr T optimalSeed()
+constexpr T optimalSeed() noexcept
{
return sizeof(T) == 8 ? static_cast<T>(14695981039346656037ULL) : static_cast<T>(2166136261U);
}
}; // namespace FNVHash
template <typename T1, typename T = size_t>
-T hash(const T1 theValue) noexcept
+T hash(const T1& theValue) noexcept
{
return opencascade::MurmurHash::hash_combine<T1, T>(theValue);
}
template <typename T1, typename T = size_t>
-T hashBytes(const T1* theKey, int theLen)
+T hashBytes(const T1* theKey, int theLen) noexcept
{
return opencascade::MurmurHash::hash_combine<T1, T>(*theKey, theLen);
}
template <typename T1, typename T = size_t>
-T hash_combine(const T1 theValue, const int theLen, const T theSeed)
+T hash_combine(const T1& theValue, const int theLen, const T theSeed) noexcept
{
return opencascade::MurmurHash::hash_combine<T1, T>(theValue, theLen, theSeed);
}
{
namespace MurmurHashUtils
{
-inline uint64_t shift_mix(uint64_t theV)
+inline uint64_t shift_mix(uint64_t theV) noexcept
{
return theV ^ (theV >> 47);
}
-// Loads n bytes, where 1 <= n < 8.
-inline uint64_t load_bytes(const char* thePnt, int theNb)
+// Loads n bytes, where 1 <= n < 8
+inline uint64_t load_bytes(const char* thePnt, int theNb) noexcept
{
- uint64_t aRes = 0;
- --theNb;
- do
- aRes = (aRes << 8) + static_cast<unsigned char>(thePnt[theNb]);
- while (--theNb >= 0);
- return aRes;
+ // Initialize result value
+ uint64_t aResult = 0;
+
+ // Use switch with fall-through for better performance and branch prediction
+ switch (theNb)
+ {
+ case 7:
+ aResult = (static_cast<uint64_t>(static_cast<unsigned char>(thePnt[6])) << 48) | aResult;
+ Standard_FALLTHROUGH
+ case 6:
+ aResult = (static_cast<uint64_t>(static_cast<unsigned char>(thePnt[5])) << 40) | aResult;
+ Standard_FALLTHROUGH
+ case 5:
+ aResult = (static_cast<uint64_t>(static_cast<unsigned char>(thePnt[4])) << 32) | aResult;
+ Standard_FALLTHROUGH
+ case 4:
+ aResult = (static_cast<uint64_t>(static_cast<unsigned char>(thePnt[3])) << 24) | aResult;
+ Standard_FALLTHROUGH
+ case 3:
+ aResult = (static_cast<uint64_t>(static_cast<unsigned char>(thePnt[2])) << 16) | aResult;
+ Standard_FALLTHROUGH
+ case 2:
+ aResult = (static_cast<uint64_t>(static_cast<unsigned char>(thePnt[1])) << 8) | aResult;
+ Standard_FALLTHROUGH
+ case 1:
+ aResult = static_cast<uint64_t>(static_cast<unsigned char>(thePnt[0])) | aResult;
+ Standard_FALLTHROUGH
+ default:
+ break;
+ }
+
+ return aResult;
}
template <typename T>
-inline T unaligned_load(const char* thePnt)
+inline T unaligned_load(const char* thePnt) noexcept
{
T aRes;
memcpy(&aRes, thePnt, sizeof(aRes));
// function : MurmurHash64A
// purpose :
//=======================================================================
-inline uint64_t MurmurHash64A(const void* theKey, int theLen, uint64_t theSeed)
+inline uint64_t MurmurHash64A(const void* theKey, int theLen, uint64_t theSeed) noexcept
{
static constexpr uint64_t aMul = (((uint64_t)0xc6a4a793UL) << 32UL) + (uint64_t)0x5bd1e995UL;
const char* const aBuf = static_cast<const char*>(theKey);
// function : MurmurHash2A
// purpose :
//=======================================================================
-inline uint32_t MurmurHash2A(const void* theKey, int theLen, uint32_t theSeed)
+inline uint32_t MurmurHash2A(const void* theKey, int theLen, uint32_t theSeed) noexcept
{
- const uint32_t aMul = 0x5bd1e995;
- uint32_t aHash = theSeed ^ theLen;
- const char* aBuf = static_cast<const char*>(theKey);
+ constexpr uint32_t aMul = 0x5bd1e995;
+ uint32_t aHash = theSeed ^ theLen;
+ const char* aBuf = static_cast<const char*>(theKey);
// Mix 4 bytes at a time into the hash.
while (theLen >= 4)
// function : FNVHash1A
// purpose :
//=======================================================================
-inline uint32_t FNVHash1A(const void* theKey, int theLen, uint32_t theSeed)
+inline uint32_t FNVHash1A(const void* theKey, int theLen, uint32_t theSeed) noexcept
{
const char* cptr = static_cast<const char*>(theKey);
for (; theLen; --theLen)
// function : FNVHash64A
// purpose :
//=======================================================================
-inline uint64_t FNVHash64A(const void* theKey, int theLen, uint64_t theSeed)
+inline uint64_t FNVHash64A(const void* theKey, int theLen, uint64_t theSeed) noexcept
{
const char* cptr = static_cast<const char*>(theKey);
for (; theLen; --theLen)